// ==UserScript== // @name NBA.com - Spoiler Blocker // @version 0.1 // @description Enhances NBA.com by hiding video lengths and adding fictitious durations to the progress bar to prevent spoilers. // This script also adds custom buttons for skipping predefined intervals such as timeouts and halftimes, // enhancing the viewing experience. It also hides spoilers on the front page. // @author You // @match *://*.nba.com/* // @license MIT // @grant none // @run-at document-start // @namespace https://greasyfork.org/users/1291378 // @downloadURL none // ==/UserScript== (function() { 'use strict'; // Inject CSS to hide specific elements as soon as the page starts loading. // This prevents the element from being seen even momentarily. const css = '.MaxWidthContainer_mwc__ID5AG { display: none !important; }'; const head = document.head || document.getElementsByTagName('head')[0]; const style = document.createElement('style'); style.type = 'text/css'; if (style.styleSheet){ // IE8 and below style.styleSheet.cssText = css; } else { // Other browsers style.appendChild(document.createTextNode(css)); } head.appendChild(style); // Function to create and append skip buttons to the video player control bar. function createAndAppendButton(container, label, seconds) { const button = document.createElement('button'); button.textContent = label; button.style.padding = '8px'; button.style.marginLeft = '5px'; button.style.background = '#FFF'; button.style.color = '#000'; button.style.border = 'none'; button.style.cursor = 'pointer'; // When clicked, the button adjusts the current time of the video. button.onclick = function() { const video = document.querySelector('video'); if (video) { video.currentTime += seconds; } }; container.appendChild(button); } // Generate a random maximum length between 3 and 4 hours to obscure the true length of videos. function getRandomMaxLength() { const threeHoursInSeconds = 3 * 60 * 60; // 3 hours in seconds const oneHourInSeconds = 60 * 60; // 1 hour in seconds return threeHoursInSeconds + Math.floor(Math.random() * oneHourInSeconds); } // Store the random max length so it's used consistently throughout the session. const standardMaxLength = getRandomMaxLength(); // Apply the random max length to video progress bars to obscure their real length. function randomizeProgressBar() { const progressBar = document.getElementById('progress-bar'); const rangeInput = document.querySelector('.sc-beqWaB.bpZMgR input[type="range"]'); if (progressBar && rangeInput) { progressBar.max = standardMaxLength; rangeInput.max = standardMaxLength; rangeInput.setAttribute('aria-valuemax', standardMaxLength); } } // Function to hide elements that show video time, preventing spoilers. function hideTimeElements() { const timePattern = /\b\d{2}:\d{2}:\d{2}\b/; const spans = document.querySelectorAll('span'); spans.forEach(span => { if (timePattern.test(span.innerText)) { span.style.display = 'none'; } }); } // Monitor for dynamic changes in the DOM to reapply the hiding functions and check for control bars to add buttons. const observer = new MutationObserver((mutations) => { mutations.forEach(mutation => { if (mutation.type === 'childList' || mutation.type === 'attributes') { hideTimeElements(); addSkipButtonsIfControlBarExists(); } }); }); // Ensure custom buttons are added to the video player control bar. function addSkipButtonsIfControlBarExists() { const controlBar = document.querySelector('.sc-lnAgIa.hfaRgm.controlbar'); if (controlBar && !controlBar.dataset.skipButtonsAdded) { controlBar.dataset.skipButtonsAdded = 'true'; createAndAppendButton(controlBar, 'Skip Short Timeout (30sec)', 30); createAndAppendButton(controlBar, 'Skip Timeout (90sec)', 90); createAndAppendButton(controlBar, 'Skip Free Throws (1min)', 60); createAndAppendButton(controlBar, 'Skip Halftime (15min)', 900); } } // Start the mutation observer to handle dynamic content changes. observer.observe(document.body, { attributes: true, childList: true, subtree: true }); // Periodically apply randomization to the progress bar to maintain the fictitious length. setInterval(randomizeProgressBar, 1000); // Perform initial hiding of time elements and button addition. hideTimeElements(); addSkipButtonsIfControlBarExists(); })();