YouTube uBlock Whitelister (Improved)

An improved version of Zalastax's fixed version of gorhill's tool to whitelist ads for certain YouTubers

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         YouTube uBlock Whitelister (Improved)
// @namespace    com.imnofox.uBOWhitelistYT
// @version      1.0
// @description  An improved version of Zalastax's fixed version of gorhill's tool to whitelist ads for certain YouTubers
// @author       imnofox, Zalastax, Raymond Hill (gorhill)
// @match        https://*.youtube.com/*
// @grant        GM_registerMenuCommand
// @license      http://creativecommons.org/licenses/by-sa/4.0/
// ==/UserScript==

// based on https://greasyfork.org/en/scripts/22308-youtube-whitelist-channels-in-ublock-origin
// which was based on https://greasyfork.org/en/scripts/13226-youtube-whitelist-channels-in-ublock-origin
// with adaption from https://greasyfork.org/en/forum/discussion/8985


// Function to return the channel name
var fetchChannel = function() {
    var link = document.querySelector('[id="watch7-user-header"] a[href^="/user/"]');
    if (link === null) {
        link = document.querySelector('[id="watch7-user-header"] a[href^="/channel/"]');
        if (link === null) {
            return;
        }
    }
    var linkHref = link.getAttribute('href');
    var linkmatch = linkHref.match(/\/(user|channel)\/(.+)/);
    if (linkmatch === null)
        return;
    var channel = linkmatch[2];
    return channel || '';
};

// Add the channel name to the URL
var exposeUserInURL = function() {
    var channel = fetchChannel();

    var newArg = channelId !== '' ? 'user=' + encodeURIComponent(channel) : '';
    var matches = location.search.match(/(?:[?&])(user=(?:[^&]+|$))/);
    var oldArg = matches !== null ? matches[1] : '';
    if (newArg === oldArg) {
        return;
    }
    var href = location.href;
    if (oldArg === '') {
        location.replace(href + (location.search === '' ? '?' : '&') + newArg);
        return;
    }
    location.replace(href.replace(oldArg, newArg));
};
setTimeout(exposeUserInURL, 25);


// DOM modifications
var mutationHandlerTimer = null;
var mutationHandlerAsync = function() {
    'use strict';

    mutationHandlerTimer = null;
    exposeUserInURL();
};
var mutationHandler = function(mutations) {

    if (mutationHandlerTimer !== null) {
        return;
    }

    for (var i = 0; i < mutations.length; i++) {
        if (mutations[i].addedNodes) {
            mutationHandlerTimer = setTimeout(mutationHandlerAsync, 25);
            break;
        }
    }
};
var observer = new MutationObserver(mutationHandler);
observer.observe(document.body, {
    childList: true,
    subtree: true
});

// Function to provide the user with the whitelist rule
var provideRule = function() {
    var channel = fetchChannel();
    if (channel !== '') {
        prompt("Add this to your uBO whitelist.\n\nuBO whitelist directive for this channel:", "youtube.com/*user=" + encodeURIComponent(channel) + "*");
    } else {
        alert("No Youtube user name found on this page.");
    }
};

// Add button to videos
var createButton = function() {
    var container = document.getElementById("watch7-subscription-container");
    if (container) {
        // Insert some style overrides for this button
        document.styleSheets[0].insertRule("button.UBO-button::before { content: none; margin-right: 0px; width: 0px; height: 0px; }", 0);
        document.styleSheets[0].insertRule("button.UBO-button { margin-left: 5px; padding: 0 5.5px 0px 6px !important;}", 0);

        var button = document.createElement("button");
        button.className = "UBO-button yt-uix-button yt-uix-button-size-default yt-uix-button-subscribed-branded yt-uix-button-has-icon no-icon-markup yt-uix-subscription-button yt-can-buffer hover-enabled";
        button.innerHTML = "uBO";
        button.addEventListener("click", provideRule, false);

        // Add the button after the container
        if (container.nextSibling) {
            container.parentNode.insertBefore(button, container.nextSibling);
        } else {
            container.parentNode.appendChild(button);
        }
    }
};
createButton();

// Nice clicky item in the GM menu
GM_registerMenuCommand("TubeWhitelister", provideRule);