// ==UserScript== // @name Super Duolingo Ad Blocker // @version 0.7 // @description Block ads and unwanted promotional content on Duolingo, including dynamically named ad classes, while preserving essential lesson content and handling fullscreen ads by pressing the exit button automatically. // @author Zinovia // @match https://*.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 = ` /* 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._16rRh._2cnFr._1T_BQ, div._1tzFd, div._1Qh5D._36g4N._2YF0P.uapW2, div._3ZUrl._2BflZ, div.MGk8p, div._3ywWe, div._1145W { display: none !important; } `; // Inject styles into the document addStyles(styles); // Function to dynamically hide elements function hideElements() { const selectors = [ 'div[data-test="purchase-step-active"]', 'div._3D_HB', 'div._16rRh', 'div._16rRh._2cnFr._1T_BQ', 'div._1tzFd', 'div._1Qh5D._36g4N._2YF0P.uapW2', 'div._3ZUrl._2BflZ', 'div.MGk8p', 'div._3ywWe', 'div._1145W' ]; selectors.forEach(selector => { document.querySelectorAll(selector).forEach(element => { if (!element.closest('#session/PlayerFooter') && !element.closest('div._1QQhE') && !element.closest('div._3rB4d._1VTif._2HXQ9')) { // Ensure essential content is not hidden element.style.display = 'none'; } }); }); } // Function to press the exit button on fullscreen ads function pressExitButton() { const exitButton = document.querySelector('._48lxa'); if (exitButton) { exitButton.click(); console.log('Fullscreen ad exit button clicked!'); } } // Function to click the button in the lesson function clickLessonButton() { const button = document.querySelector('._3vGNs._2YF0P._1Udkq'); if (button) { button.click(); console.log('Lesson button clicked!'); } } // Function to handle the blank screen issue function handleBlankScreen() { const continueButton = document.querySelector('button[data-test="player-next"]'); if (continueButton) { continueButton.click(); console.log('Continue button clicked!'); } const reviewLessonButton = document.querySelector('button span._1o-YO:contains("Review lesson")'); if (reviewLessonButton) { reviewLessonButton.click(); console.log('Review lesson button clicked!'); } } // Run initial functions hideElements(); pressExitButton(); clickLessonButton(); handleBlankScreen(); // Observe DOM changes and apply modifications as necessary const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { if (mutation.type === 'childList') { hideElements(); pressExitButton(); clickLessonButton(); handleBlankScreen(); } }); }); // Start observing the body for child list changes observer.observe(document.body, { childList: true, subtree: true }); console.log('Super Duolingo Ad Blocker initialized.'); })();