Youtube video blocker

Allows you to block videos from youtube

As of 27.05.2017. See ბოლო ვერსია.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         Youtube video blocker
// @namespace    Danielv123
// @version      1.1
// @description  Allows you to block videos from youtube
// @author       Danielv123
// @match        https://www.youtube.com/*
// @grant        none
// @require      https://code.jquery.com/jquery.js
// ==/UserScript==

//'use strict';
/*
Videos in sidebar

Get video ID
document.querySelectorAll(".video-list-item .yt-uix-simple-thumb-wrap")[0].dataset.vid
Get video title
document.querySelectorAll(".video-list-item .content-wrapper a:nth-child(1)")[2].title
Get username
document.querySelectorAll(".video-list-item .content-wrapper .stat.attribution span")[2].innerHTML
Hide
document.querySelectorAll(".video-list-item")[2].style.display = "none";

Videos on subscriptions page

Get video ID
document.querySelectorAll(".yt-shelf-grid-item > div")[0].dataset.contextItemId
Get video title
document.querySelectorAll(".yt-shelf-grid-item .yt-lockup-content .yt-lockup-title a")[0].title
Get username
document.querySelectorAll(".yt-shelf-grid-item .yt-lockup-content .yt-lockup-byline a")[0].innerHTML
Hide
document.querySelectorAll(".yt-shelf-grid-item")[0].style.display = "none"
*/
// Code goes here and onwards

function main() {
    if(!localStorage.blockedUsers){
        localStorage.blockedUsers = JSON.stringify([]);
    }
    if(!localStorage.blockedTitles){
        localStorage.blockedTitles = JSON.stringify([]);
    }
    if(!localStorage.blockedRegex){
        localStorage.blockedRegex = JSON.stringify([]);
    }
    //hideSidebarVideos("","PewDiePie");
    //hideShelfVideos("","nigahiga");
    //hideShelfVideos("","","s");
    injectScripts();
    makeFilterGui();

    // Hide videos
    let userFilters = JSON.parse(localStorage.blockedUsers);
    let titleFilters = JSON.parse(localStorage.blockedTitles);
    let regexFilters = JSON.parse(localStorage.blockedRegex);
    // Loop until we are through the larges of our filter sets
    for(let i = 0; i < Math.max(regexFilters.length, Math.max(userFilters.length, titleFilters.length));i++){
        // hideSidebarVideos(id, username, title, regex)
        let id = "";
        let user = userFilters[i] || "";
        let title = titleFilters[i] || "";
        let regex = regexFilters[i] || "";
        hideSidebarVideos(id, user, title);
        hideShelfVideos(id, user, title);
    }
}
setTimeout(main, 500);

function makeFilterGui() {
    let HTML =  '<div id="youtubeBlockerGui" style="">';
    // Close button
    HTML += '<div id="youtubeBlockerGuiCloseButton"><img src="http://www.drodd.com/images14/x23.png"></img></div>';
    HTML += '<h1>Youtube Blocker</h1><p>Below are a few textfields. Enter , (comma) seperated lists of titles and/or channels to exclude from your youtube feed.</p><p>Video titles don\'t have to match completely, just having part of the title is enough. Ex "porn,1000 degree,prank" will match "1000 degree knife vs water baloon EPIC"<br>';
    HTML += '<h2>Blocked channels</h2><p><i>All channels with this excact name will be hidden</i></p><textarea id="blockedChannels"></textarea>';
    HTML += '<h2>Blocked videos by name</h2><p><i>All videos with this in their names will be hidden</i></p><textarea id="blockedVideos"></textarea>';
    HTML += '<h2>Regex blocks</h2><p><i>All video titles matching this regex will be hidden</i></p><textarea id="blockedRegex"></textarea>';
    // Save button
    HTML += '<div id="saveButton"><h2>Save</h2></div>';
    // Close everything
    HTML += '</div>';
    // Open settings button in botttom right corner
    HTML += '<div id="gearwheelButton"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/bd/Simpleicons_Interface_gear-wheel-in-black.svg/2000px-Simpleicons_Interface_gear-wheel-in-black.svg.png"></img></div>';
    // inject into body
    let container = document.createElement('div');
    container.innerHTML = HTML;
    (document.body || document.head || document.documentElement).appendChild(container);

    // Populate textareas with old settings
    let x = JSON.parse(localStorage.blockedUsers);
    let y = "";
    for(let i in x) {
        y += x[i]+",\n";
    }
    $("textarea#blockedChannels")[0].value = y;
    x = JSON.parse(localStorage.blockedTitles);
    y = "";
    for(let i in x) {
        y += x[i]+",\n";
    }
    $("textarea#blockedVideos")[0].value = y;
    x = JSON.parse(localStorage.blockedRegex);
    y = "";
    for(let i in x) {
        y += x[i]+",\n";
    }
    $("textarea#blockedRegex")[0].value = y;

    document.querySelector("#youtubeBlockerGui #youtubeBlockerGuiCloseButton").onclick = toggleGuiDisplay;
    document.querySelector("#gearwheelButton").onclick = toggleGuiDisplay;
    document.querySelector("#saveButton").onclick = function(){
        console.log("Saving lists of blocked channels, users and regexes");
        // Regex to replace linebreaks
        localStorage.blockedUsers = JSON.stringify($("textarea#blockedChannels")[0].value.replace(/(\r\n|\n|\r)/gm,"").split(","));
        localStorage.blockedTitles = JSON.stringify($("textarea#blockedVideos")[0].value.replace(/(\r\n|\n|\r)/gm,"").split(","));
        localStorage.blockedRegex = JSON.stringify($("textarea#blockedRegex")[0].value.replace(/(\r\n|\n|\r)/gm,"").split(","));
    };
}
function readBlockSettings(){
    $("#youtubeBlockerGui textarea")[0].value.replace(/(\r\n|\n|\r)/gm,"").split(",");
}
function toggleGuiDisplay(){
    let gui = $("#youtubeBlockerGui")[0];
    if(gui.style.display == "none"){
        gui.style.display = "block";
    } else {
        gui.style.display = "none";
    }
}
function injectScripts(){
    // jQuery
    var s=document.createElement('script');
    s.setAttribute('src','https://code.jquery.com/jquery.js');
    document.getElementsByTagName('head')[0].appendChild(s);
    // CSS
    var d=document.createElement('style');
    d.innerHTML = "#youtubeBlockerGui {"+
        "display:none;"+
        "width:60%;"+
        "height:80%;"+
        "background-color:white;"+
        "position:fixed;"+
        "top:10%;"+
        "left:20%;"+
        "border:1px solid lightgrey;"+
        // damn, the youtube sidebar apparently has a z index of 1999999999...
        "z-index:2000000000;"+
        "}"+
        // red X on gui to close
        "#youtubeBlockerGuiCloseButton {"+
        "float:right;"+
        "height:30px;"+
        "width:30px;"+
        "cursor:pointer;"+
        "}"+
        "#youtubeBlockerGuiCloseButton img {"+
        "height:100%;"+
        "width:100%;"+
        "}"+
        // gearwheel in bottom right corner
        "#gearwheelButton {"+
        "position:fixed;"+
        "height:30px;"+
        "width:30px;"+
        "bottom:0px;"+
        "right:0px;"+
        "cursor:pointer;"+
        "}"+
        "#gearwheelButton img {"+
        "height:100%;"+
        "width:100%;"+
        "}"+
        "#saveButton {"+
        "cursor:pointer;"+
        "}"
        ;
    document.getElementsByTagName('body')[0].appendChild(d);
}
function hideShelfVideos(id, username,title, regex) {
    let videos = document.querySelectorAll(".yt-shelf-grid-item");
    for(let i = 0; i < videos.length; i++){
        let hideVideo = function(number, filter){
            document.querySelectorAll(".yt-shelf-grid-item")[number].style.display = "none";
            console.log("Filter: " + filter + " Hidden: " + document.querySelectorAll(".yt-shelf-grid-item .yt-lockup-content .yt-lockup-title a")[number].title);
        };
        // Check by video ID
        if(id && id == document.querySelectorAll(".yt-shelf-grid-item > div")[i].dataset.contextItemId){
            hideVideo(i, id);
        }
        // Check by channel name
        if(username && username.toLowerCase() == document.querySelectorAll(".yt-shelf-grid-item .yt-lockup-content .yt-lockup-byline a")[i].innerHTML.toLowerCase()){
            hideVideo(i, username);
        }
        // Check if video title contains title
        if(title && title != " " && document.querySelectorAll(".yt-shelf-grid-item .yt-lockup-content .yt-lockup-title a")[i].title.toLowerCase().includes(title.toLowerCase())){
            hideVideo(i, title);
        }
        // Check if title matches regex
        if(regex && document.querySelectorAll(".yt-shelf-grid-item .yt-lockup-content .yt-lockup-title a")[i].title.match(regex)){
            hideVideo(i, regex);
        }
    }
}
function hideSidebarVideos(id, username, title, regex) {
    let videos = document.querySelectorAll(".video-list-item");
    for(let i = 0; i < videos.length; i++){
        let hideVideo = function(number, filter){
            document.querySelectorAll(".video-list-item")[number].style.display = "none";
            console.log("Filter: " + filter + " Hidden: " + document.querySelectorAll(".video-list-item .content-wrapper a:nth-child(1)")[number].title);
        };
        // Check by video ID
        if(id == document.querySelectorAll(".video-list-item .yt-uix-simple-thumb-wrap")[i].dataset.vid){
            hideVideo(i, id);
        }
        // Check by channel name
        if(username.toLowerCase() == document.querySelectorAll(".video-list-item .content-wrapper .stat.attribution span")[i].innerHTML.toLowerCase()){
            hideVideo(i, username);
        }
        // Check if video title contains title
        if(title && title != " " && document.querySelectorAll(".video-list-item .content-wrapper a:nth-child(1)")[i].title.toLowerCase().includes(title.toLowerCase())){
            hideVideo(i, title);
        }
        // Check if title matches regex
        if(regex && document.querySelectorAll(".video-list-item .content-wrapper a:nth-child(1)")[i].title.match(regex)){
            hideVideo(i, regex);
        }
    }
}