Rotter.net Ad Blocker

Blocks all ads, banners, and sponsored content on Rotter.net including Taboola widgets, ad containers, and sponsored links

Size

9.8 KB

Version

1.0.1

Created

Mar 11, 2026

Updated

about 1 month ago

1// ==UserScript==
2// @name		Rotter.net Ad Blocker
3// @description		Blocks all ads, banners, and sponsored content on Rotter.net including Taboola widgets, ad containers, and sponsored links
4// @version		1.0.1
5// @match		https://*.rotter.net/*
6// @icon		https://rotter.net/favicon.ico
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    console.log('Rotter.net Ad Blocker extension loaded');
12
13    // Main initialization function
14    async function init() {
15        console.log('Initializing ad blocker...');
16        
17        // Block ads immediately when page loads
18        blockAds();
19        
20        // Set up MutationObserver to block ads that load dynamically
21        setupMutationObserver();
22        
23        // Add CSS to hide ads
24        addAdBlockingCSS();
25        
26        // Show blocked ads count
27        showBlockedCount();
28    }
29
30    // Function to block all ads on the page
31    function blockAds() {
32        console.log('Blocking ads...');
33        
34        // Common ad selectors based on analysis
35        const adSelectors = [
36            // Taboola ads
37            '[id*="taboola"]',
38            '[class*="taboola"]',
39            '.trc_related_container',
40            '.trc_rbox_container',
41            '.trc-content-sponsored',
42            
43            // Ad containers with data-adpath
44            '[data-adpath]',
45            '[data-onpage="true"]',
46            
47            // General ad selectors
48            '[id*="ad"]',
49            '[class*="ad"]',
50            '[id*="banner"]',
51            '[class*="banner"]',
52            '[id*="sponsor"]',
53            '[class*="sponsor"]',
54            '[id*="promo"]',
55            '[class*="promo"]',
56            
57            // Specific elements found on rotter.net
58            '#adn_player',
59            'iframe[src*="ads"]',
60            'iframe[src*="ad"]',
61            
62            // Social media widgets that might contain ads
63            '.social-widget',
64            '.share-widget'
65        ];
66
67        let blockedCount = 0;
68
69        // Try each selector and hide matching elements
70        adSelectors.forEach(selector => {
71            try {
72                const elements = document.querySelectorAll(selector);
73                elements.forEach(element => {
74                    // Check if element is already hidden
75                    if (element.style.display !== 'none' && element.style.visibility !== 'hidden') {
76                        element.style.display = 'none';
77                        element.style.visibility = 'hidden';
78                        element.style.height = '0';
79                        element.style.width = '0';
80                        element.style.overflow = 'hidden';
81                        element.style.opacity = '0';
82                        blockedCount++;
83                        
84                        console.log(`Blocked ad element: ${selector}`, element);
85                    }
86                });
87            } catch (error) {
88                console.error(`Error blocking ads with selector ${selector}:`, error);
89            }
90        });
91
92        // Also block iframes that might contain ads
93        const iframes = document.querySelectorAll('iframe');
94        iframes.forEach(iframe => {
95            const src = iframe.src || '';
96            if (src.includes('ad') || src.includes('ads') || src.includes('banner') || 
97                src.includes('sponsor') || src.includes('promo')) {
98                iframe.style.display = 'none';
99                iframe.style.visibility = 'hidden';
100                blockedCount++;
101                console.log('Blocked ad iframe:', iframe);
102            }
103        });
104
105        console.log(`Blocked ${blockedCount} ad elements`);
106        return blockedCount;
107    }
108
109    // Set up MutationObserver to catch dynamically loaded ads
110    function setupMutationObserver() {
111        console.log('Setting up MutationObserver for dynamic ads...');
112        
113        // Debounce function to prevent excessive calls
114        function debounce(func, wait) {
115            let timeout;
116            return function executedFunction(...args) {
117                const later = () => {
118                    clearTimeout(timeout);
119                    func(...args);
120                };
121                clearTimeout(timeout);
122                timeout = setTimeout(later, wait);
123            };
124        }
125
126        const debouncedBlockAds = debounce(() => {
127            console.log('Mutation detected, checking for new ads...');
128            blockAds();
129            showBlockedCount();
130        }, 500);
131
132        // Create MutationObserver
133        const observer = new MutationObserver((mutations) => {
134            let shouldBlock = false;
135            
136            mutations.forEach(mutation => {
137                // Check if new nodes were added
138                if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
139                    shouldBlock = true;
140                }
141                
142                // Check if attributes changed (ads might load with different attributes)
143                if (mutation.type === 'attributes') {
144                    const attrName = mutation.attributeName;
145                    if (attrName && (attrName.includes('src') || attrName.includes('data-ad') || 
146                        attrName.includes('class') || attrName.includes('id'))) {
147                        shouldBlock = true;
148                    }
149                }
150            });
151            
152            if (shouldBlock) {
153                debouncedBlockAds();
154            }
155        });
156
157        // Start observing the document
158        observer.observe(document.documentElement, {
159            childList: true,
160            subtree: true,
161            attributes: true,
162            attributeFilter: ['src', 'data-ad', 'class', 'id', 'style']
163        });
164
165        console.log('MutationObserver started');
166    }
167
168    // Add CSS styles to hide ads
169    function addAdBlockingCSS() {
170        console.log('Adding ad blocking CSS...');
171        
172        const css = `
173            /* Hide ad elements */
174            [id*="taboola"],
175            [class*="taboola"],
176            .trc_related_container,
177            .trc_rbox_container,
178            .trc-content-sponsored,
179            [data-adpath],
180            [data-onpage="true"],
181            #adn_player,
182            [id*="ad"],
183            [class*="ad"],
184            [id*="banner"],
185            [class*="banner"],
186            [id*="sponsor"],
187            [class*="sponsor"],
188            [id*="promo"],
189            [class*="promo"] {
190                display: none !important;
191                visibility: hidden !important;
192                height: 0 !important;
193                width: 0 !important;
194                overflow: hidden !important;
195                opacity: 0 !important;
196                position: absolute !important;
197                left: -9999px !important;
198                top: -9999px !important;
199            }
200            
201            /* Hide ad iframes */
202            iframe[src*="ad"],
203            iframe[src*="ads"],
204            iframe[src*="banner"],
205            iframe[src*="sponsor"],
206            iframe[src*="promo"] {
207                display: none !important;
208                visibility: hidden !important;
209            }
210            
211            /* Improve page layout after removing ads */
212            body {
213                overflow-x: hidden;
214            }
215            
216            /* Optional: Add some visual feedback when ads are blocked */
217            .ad-blocked-notice {
218                display: none;
219            }
220        `;
221
222        const style = document.createElement('style');
223        style.textContent = css;
224        style.id = 'rotter-ad-blocker-styles';
225        document.head.appendChild(style);
226        
227        console.log('Ad blocking CSS added');
228    }
229
230    // Show blocked ads count (optional visual feedback)
231    function showBlockedCount() {
232        // Remove any existing counter
233        const existingCounter = document.getElementById('ad-blocker-counter');
234        if (existingCounter) {
235            existingCounter.remove();
236        }
237        
238        // Count ad elements that are hidden
239        const adElements = document.querySelectorAll(`
240            [id*="taboola"],
241            [class*="taboola"],
242            .trc_related_container,
243            [data-adpath],
244            #adn_player,
245            [id*="ad"],
246            [class*="ad"]
247        `);
248        
249        let hiddenCount = 0;
250        adElements.forEach(el => {
251            const style = window.getComputedStyle(el);
252            if (style.display === 'none' || style.visibility === 'hidden') {
253                hiddenCount++;
254            }
255        });
256        
257        // Create counter element
258        const counter = document.createElement('div');
259        counter.id = 'ad-blocker-counter';
260        counter.innerHTML = `🚫 ${hiddenCount} ads blocked`;
261        counter.style.cssText = `
262            position: fixed;
263            bottom: 20px;
264            right: 20px;
265            background: #4CAF50;
266            color: white;
267            padding: 8px 16px;
268            border-radius: 20px;
269            font-size: 14px;
270            font-family: Arial, sans-serif;
271            z-index: 999999;
272            box-shadow: 0 2px 10px rgba(0,0,0,0.2);
273            cursor: pointer;
274            transition: opacity 0.3s;
275        `;
276        
277        // Add click to hide functionality
278        counter.addEventListener('click', () => {
279            counter.style.opacity = '0';
280            setTimeout(() => counter.remove(), 300);
281        });
282        
283        document.body.appendChild(counter);
284        
285        // Auto-hide after 5 seconds
286        setTimeout(() => {
287            if (counter.parentNode) {
288                counter.style.opacity = '0';
289                setTimeout(() => counter.remove(), 300);
290            }
291        }, 5000);
292        
293        console.log(`Showing blocked count: ${hiddenCount} ads`);
294    }
295
296    // Initialize when DOM is ready
297    if (document.readyState === 'loading') {
298        document.addEventListener('DOMContentLoaded', init);
299    } else {
300        init();
301    }
302
303})();