attempt sanitizing raum content when content is just h1 + img tag; sanitize tables on raum contents sites

This commit is contained in:
Johann Hoffmann
2025-02-11 15:05:22 +01:00
parent fe4351fc87
commit 2b27b55f40
@@ -1,6 +1,11 @@
export default {
name: "RaumComponent",
data() {
return {
imgContent: null
}
},
props:{
content:{
type:String,
@@ -10,11 +15,64 @@ export default {
type:Number,
}
},
methods: {
sanitizeLegacyTables(table) {
// find nested tables and replace with p element
const tt = table.querySelectorAll('table')
tt.forEach(t => {
const textContent = t.textContent.trim();
const pElement = document.createElement('p');
pElement.textContent = textContent;
t.parentNode.replaceChild(pElement, t);
})
// find unordered lists, traverse li childs and replace with p element -> more readable than 1 p tag for ul
const ul = table.querySelectorAll('ul')
ul.forEach(u => {
Array.from(u.children).forEach(li => {
const p = document.createElement('p');
p.textContent = li.textContent
u.parentNode.appendChild(p)
})
u.parentNode.removeChild(u)
})
// find bare text nodes and put into p element
const td = Array.from(table.querySelectorAll('td')).filter(el => el.scrollWidth > 100)
td.forEach(element => {
if (element.firstChild?.nodeType === Node.TEXT_NODE && element.firstChild.length > 10) {
const p = document.createElement('p');
p.appendChild(element.firstChild)
element.appendChild(p);
}
});
// flatten nested th elements
const ths = Array.from(table.querySelectorAll('th'))
ths.forEach(th => {
if(th.children.length > 1) {
th.innerHTML = Array.from(th.childNodes).find(cn => cn.textContent).textContent
}
})
// let p elements wrap on overflow
const p = table.querySelectorAll('p')
p.forEach(p => {
p.style.setProperty('word-wrap', 'break-word');
p.style.setProperty('white-space', 'normal');
p.style.setProperty('max-width', '400px');
})
}
},
mounted(){
// replaces the tablesorter with the tabulator
let tables = document.getElementsByClassName("tablesorter");
for (let table of tables) {
this.sanitizeLegacyTables(table)
new Tabulator(table, {
layout: "fitDataStretch",
@@ -25,11 +83,28 @@ export default {
}
})
}
const parser = new DOMParser()
const doc = parser.parseFromString(`<div>${this.content}</div>`, "text/html");
const img = doc.querySelector("img")
// let img = document.getElementsByTagName("img");
if(img && img.title)
{
const imgAttributes = {}
for (let attr of img.attributes) {
imgAttributes[attr.name] = attr.value
}
// tries to wrap the Raum titel with a link tag that redirects to the Reservierungen of that Raum
this.imgContent = imgAttributes; // Now it's a plain object
return
}
let title = document.getElementsByTagName("h1");
title = title.length ? title[0] : null;
if (title)
// tries to wrap the Raum titel with a link tag that redirects to the Reservierungen of that Raum
if (title && title.innerText)
{
let room_name = title.innerText;
let room_name_reg_exp = new RegExp("\\w*\\s([a-zA-Z][0-9\\.]+)$");
@@ -56,7 +131,9 @@ export default {
},
template: /*html*/ `
<!-- div that contains the content -->
<div v-html="content" v-if="content" ></div>
<!-- TODO: test with more img content from cms-->
<div v-if="imgContent"><img v-bind="imgContent"></img></div>
<div v-html="content" v-else-if="content" ></div>
<p v-else>Content was not found</p>
`,
};