Verbessere die Handhabung von Anzeigenknoten: Füge Logik hinzu, um Skripte sicher auszuführen und Textknoten zu entfernen, um sichtbaren JS-Code zu vermeiden.

This commit is contained in:
Torsten Schulz (local)
2026-05-18 15:43:37 +02:00
parent 12a724614d
commit 53a8aa3869

View File

@@ -129,21 +129,90 @@ async function renderPropeller() {
const observer = new MutationObserver(mutations => { const observer = new MutationObserver(mutations => {
for (const m of mutations) { for (const m of mutations) {
for (const node of Array.from(m.addedNodes)) { for (const node of Array.from(m.addedNodes)) {
if (!(node instanceof HTMLElement)) continue; try {
const src = (node.tagName === 'IFRAME' && node.getAttribute('src')) || ''; // Handle text nodes that may contain raw script/HTML
const isAdNode = src.includes('nap5k') || (node.dataset && node.dataset.zone === propSlotId) || /nap5k|propel|propeller|inpage|push/i.test(node.className + ' ' + node.id); if (node.nodeType === Node.TEXT_NODE) {
if (isAdNode) { const txt = (node.nodeValue || '').trim();
try { if (txt.includes('<script') || txt.length > 500) {
placeholder.innerHTML = ''; // remove large/raw script text nodes to avoid visible JS
placeholder.appendChild(node); node.parentNode && node.parentNode.removeChild(node);
node.style.maxWidth = '100%'; }
node.style.display = 'block'; continue;
observer.disconnect();
try { window.dispatchEvent(new CustomEvent('ads:relocated',{detail:{provider:'propeller',zone:propSlotId}})); } catch {}
return;
} catch (e) {
console.warn('Failed to relocate ad node', e);
} }
if (!(node instanceof HTMLElement)) continue;
// If element contains script tags, extract and execute them safely
const innerScripts = Array.from(node.querySelectorAll('script'));
if (innerScripts.length) {
for (const sc of innerScripts) {
try {
if (sc.src) {
const s2 = document.createElement('script');
s2.src = sc.src;
s2.async = true;
document.head.appendChild(s2);
} else if (sc.textContent) {
const s2 = document.createElement('script');
s2.textContent = sc.textContent;
document.head.appendChild(s2);
}
} catch (e) {
console.warn('execute inner script failed', e);
}
// remove the inline script node from original element to avoid visible code
sc.parentNode && sc.parentNode.removeChild(sc);
}
}
// If the added node is a script element itself, execute safely via head insertion
if (node.tagName === 'SCRIPT') {
const src = node.getAttribute('src');
if (src) {
const s2 = document.createElement('script');
s2.src = src;
s2.async = true;
s2.onload = () => console.log('relocated script loaded', src);
s2.onerror = (e) => console.warn('relocated script failed', src, e);
document.head.appendChild(s2);
node.parentNode && node.parentNode.removeChild(node);
continue;
} else if (node.textContent) {
const s2 = document.createElement('script');
s2.textContent = node.textContent;
document.head.appendChild(s2);
node.parentNode && node.parentNode.removeChild(node);
continue;
}
}
// Detect iframe ad nodes or nodes with nap5k indicators
const iframe = node.tagName === 'IFRAME' ? node : node.querySelector && node.querySelector('iframe');
const src = iframe ? (iframe.getAttribute('src') || '') : '';
const isAdNode = src.includes('nap5k') || (node.dataset && node.dataset.zone === propSlotId) || /nap5k|propel|propeller|inpage|push/i.test((node.className || '') + ' ' + (node.id || ''));
if (isAdNode) {
try {
// move iframe/ad node into placeholder
placeholder.innerHTML = '';
if (iframe && iframe.parentNode) {
placeholder.appendChild(iframe);
} else {
placeholder.appendChild(node);
}
const moved = placeholder.firstElementChild;
if (moved) {
moved.style.maxWidth = '100%';
moved.style.display = 'block';
}
observer.disconnect();
try { window.dispatchEvent(new CustomEvent('ads:relocated',{detail:{provider:'propeller',zone:propSlotId}})); } catch {}
return;
} catch (e) {
console.warn('Failed to relocate ad node', e);
}
}
} catch (e) {
console.warn('mutation handler error', e);
} }
} }
} }