diff --git a/src/content-script.js b/src/content-script.js index aaffcb3..7f53526 100644 --- a/src/content-script.js +++ b/src/content-script.js @@ -173,6 +173,7 @@ function cleanClone(node) { clone.querySelectorAll(selector).forEach((element) => element.remove()); }); + removeEditorialRecommendationSections(clone); removePromotionalBlocks(clone); clone.querySelectorAll("a[href]").forEach((link) => { @@ -430,6 +431,7 @@ function sanitizeSectionClone(wrapper) { } }); + removeEditorialRecommendationSections(wrapper); removePromotionalBlocks(wrapper); wrapper.querySelectorAll("a[href]").forEach((link) => { @@ -441,6 +443,59 @@ function sanitizeSectionClone(wrapper) { wrapper.querySelectorAll('.comments, #comments, [class*="comment-thread"], [class*="comment-list"]').forEach((element) => element.remove()); } +function removeEditorialRecommendationSections(root) { + if (!root || typeof root.querySelectorAll !== 'function') { + return; + } + + const editorialHeadingPatterns = [ + /^empfehlungen der redaktion$/i, + /^das könnte (dich|euch|sie) (auch )?interessieren$/i, + /^mehr zum thema$/i, + /^ähnliche (artikel|beiträge|news)$/i, + /^verwandte (artikel|beiträge)$/i, + /^sponsored( post| content)?$/i, + /^weitere (artikel|news|beiträge) (zum thema|dazu)$/i, + /^lesen sie auch$/i, + ]; + + const cssRecommendationSelectors = [ + '[class*="recommendation"]', + '[class*="related-article"]', + '[class*="more-articles"]', + '[class*="further-reading"]', + '[data-component*="recommendation"]', + '[data-module*="recommendation"]', + ]; + + cssRecommendationSelectors.forEach((selector) => { + root.querySelectorAll(selector).forEach((el) => el.remove()); + }); + + const headings = Array.from(root.querySelectorAll('h2, h3, h4')); + + for (const heading of headings) { + const text = (heading.textContent || '').trim(); + const isEditorial = editorialHeadingPatterns.some((pattern) => pattern.test(text)); + + if (!isEditorial) { + continue; + } + + let container = heading.parentElement; + while (container && container !== root) { + if (container.children.length >= 2) { + break; + } + container = container.parentElement; + } + + if (container && container !== root) { + container.remove(); + } + } +} + function removePromotionalBlocks(root) { if (!root || typeof root.querySelectorAll !== "function") { return; @@ -449,13 +504,24 @@ function removePromotionalBlocks(root) { const candidates = Array.from(root.querySelectorAll("div, section, aside, p, blockquote, ul")); candidates.forEach((element) => { const text = normalizeInlineWhitespace(element.textContent || "").trim().toLowerCase(); - const paragraphCount = element.querySelectorAll("p").length; - const listCount = element.querySelectorAll("ul, ol").length; - if (!text || text.length < 18) { + if (!text) { return; } + // Check short promotional labels (e.g. "Anzeige") before the length guard + if (text.length <= 18 && isPromotionalTextBlock(text)) { + element.remove(); + return; + } + + if (text.length < 18) { + return; + } + + const paragraphCount = element.querySelectorAll("p").length; + const listCount = element.querySelectorAll("ul, ol").length; + if (text.length > 600 || paragraphCount > 2 || listCount > 1) { return; } @@ -471,6 +537,10 @@ function isPromotionalTextBlock(text) { return false; } + if (/^anzeige[.:!]?$/.test(text)) { + return true; + } + if (/kein bock auf werbung\?/.test(text)) { return true; }