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,15 +129,81 @@ 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)) {
try {
// Handle text nodes that may contain raw script/HTML
if (node.nodeType === Node.TEXT_NODE) {
const txt = (node.nodeValue || '').trim();
if (txt.includes('<script') || txt.length > 500) {
// remove large/raw script text nodes to avoid visible JS
node.parentNode && node.parentNode.removeChild(node);
}
continue;
}
if (!(node instanceof HTMLElement)) continue; if (!(node instanceof HTMLElement)) continue;
const src = (node.tagName === 'IFRAME' && node.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 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) { if (isAdNode) {
try { try {
// move iframe/ad node into placeholder
placeholder.innerHTML = ''; placeholder.innerHTML = '';
if (iframe && iframe.parentNode) {
placeholder.appendChild(iframe);
} else {
placeholder.appendChild(node); placeholder.appendChild(node);
node.style.maxWidth = '100%'; }
node.style.display = 'block'; const moved = placeholder.firstElementChild;
if (moved) {
moved.style.maxWidth = '100%';
moved.style.display = 'block';
}
observer.disconnect(); observer.disconnect();
try { window.dispatchEvent(new CustomEvent('ads:relocated',{detail:{provider:'propeller',zone:propSlotId}})); } catch {} try { window.dispatchEvent(new CustomEvent('ads:relocated',{detail:{provider:'propeller',zone:propSlotId}})); } catch {}
return; return;
@@ -145,6 +211,9 @@ async function renderPropeller() {
console.warn('Failed to relocate ad node', e); console.warn('Failed to relocate ad node', e);
} }
} }
} catch (e) {
console.warn('mutation handler error', e);
}
} }
} }
}); });