// ==UserScript== // @name Super Duolingo Ad Blocker // @version 0.2 // @description Block ads and unwanted promotional content on Duolingo, including full-browser videos and dynamically named ad classes, while preserving essential lesson content. // @author Zinovia // @match https://www.duolingo.com/* // @grant none // @namespace https://greasyfork.org/users/1340999 // @downloadURL none // ==/UserScript== (function() { 'use strict'; // Function to inject CSS into the document function addStyles(css) { const style = document.createElement('style'); style.type = 'text/css'; style.textContent = css; document.head.appendChild(style); } // CSS to hide specific promotional and ad content const styles = ` /* General video ad elements */ video { display: none !important; volume: 0; } /* Specific divs associated with ads and promotions, conditional on not being essential content */ div[data-test="purchase-step-active"], div._3D_HB, div._16rRh, div._1tzFd { display: none !important; } `; // Inject styles into the document addStyles(styles); // Function to dynamically hide elements and mute videos function hideElementsAndMuteVideos() { const selectors = [ 'video', 'div[data-test="purchase-step-active"]', 'div._3D_HB', 'div._16rRh', 'div._1tzFd' ]; selectors.forEach(selector => { document.querySelectorAll(selector).forEach(element => { if (!element.closest('.learning-path')) { // Ensures that elements within the learning path are not hidden element.style.display = 'none'; } }); }); // Mute and pause videos to prevent audio play document.querySelectorAll('video').forEach(video => { video.volume = 0; video.pause(); }); } // Run function initially to hide elements and mute videos hideElementsAndMuteVideos(); // Observe DOM changes and apply modifications as necessary const observer = new MutationObserver(hideElementsAndMuteVideos); observer.observe(document.body, { childList: true, subtree: true }); console.log('Super Duolingo Ad Blocker initialized.'); })();