// ==UserScript== // @name Twitch.tv Amazon Prime Ad Remover // @namespace https://github.com/mirbyte/TwitchTV-Userscripts // @match https://www.twitch.tv/* // @grant none // @version 1.4 // @author mirbyte // @description Removes amazon prime ad/button on twitch.tv. Check GitHub page for the demonstration image. // @icon https://www.twitch.tv/favicon.ico // ==/UserScript== (function() { 'use strict'; function removePrime() { // Direct targeting of prime elements const directSelectors = [ '.top-nav__prime', '.prime-offers', '[class*="prime-offers"]', '[data-a-target="prime-offers-icon"]', '[data-a-target*="prime"]', '[data-target*="prime"]' ]; // Remove elements using direct selectors directSelectors.forEach(selector => { const elements = document.querySelectorAll(selector); elements.forEach(element => { if (element) { element.remove(); console.log("Prime element removed via direct selector:", selector); } }); }); // Additional targeting by aria-label (for internationalized versions) const ariaElements = document.querySelectorAll('[aria-label]'); ariaElements.forEach(element => { const ariaLabel = element.getAttribute('aria-label')?.toLowerCase() || ''; if (ariaLabel.includes('prime') || ariaLabel.includes('amazon')) { // Check if it's in the top navigation area const isInTopNav = element.closest('[class*="top-nav"]') || element.closest('[class*="prime"]') || element.closest('[data-a-target*="prime"]'); if (isInTopNav) { const container = element.closest('[class*="Layout"]') || element; container.remove(); console.log("Prime element removed via aria-label:", ariaLabel); } } }); // Target buttons with Prime-related data attributes const primeButtons = document.querySelectorAll('button[data-a-target*="prime"], button[data-target*="prime"]'); primeButtons.forEach(button => { const container = button.closest('[class*="Layout"]') || button.closest('[class*="prime"]') || button.parentElement; if (container) { container.remove(); console.log("Prime button container removed"); } }); // Fallback: Look for elements containing Prime icon SVGs const svgElements = document.querySelectorAll('svg'); svgElements.forEach(svg => { const paths = svg.querySelectorAll('path'); // Look for the crown/prime icon path pattern paths.forEach(path => { const d = path.getAttribute('d'); if (d && d.includes('13.798 10.456')) { // Part of the Prime crown icon path const primeContainer = svg.closest('[class*="Layout"]') || svg.closest('button') || svg.closest('div[class*="prime"]'); if (primeContainer) { primeContainer.remove(); console.log("Prime element removed via SVG detection"); } } }); }); } // Run on load if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', removePrime); } else { removePrime(); } // Enhanced observer with throttling let debounceTimeout; const observer = new MutationObserver(function(mutations) { clearTimeout(debounceTimeout); debounceTimeout = setTimeout(removePrime, 100); }); if (document.body) { observer.observe(document.body, { subtree: true, childList: true, attributes: true, attributeFilter: ['class', 'style', 'data-a-target', 'aria-label'] }); } })();