Github recommendation blocker

Remove github's recommendation/trending cards in the dashboard thread. It's triggered by HTML change, usually takes 5ms in PC Chrome browser.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         Github recommendation blocker
// @namespace    http://tampermonkey.net/
// @version      1
// @description  Remove github's recommendation/trending cards in the dashboard thread. It's triggered by HTML change, usually takes 5ms in PC Chrome browser.
// @author       dont-be-evil
// @match        https://github.com/
// @icon         https://www.google.com/s2/favicons?sz=64&domain=github.com
// @grant        none
// @license      GPLv3
// ==/UserScript==

(function() {
    'use strict';
    document.querySelectorAll('h2').forEach(h2 => {
        console.log(h2.textContent.trim());
        if (h2.textContent.trim() === "Explore repositories") {
            h2.parentElement.remove();
        }
    });

    const keywords = ["Recommended for you", "Based on", "Popular among", "Popular projects among", ...
                      "Trending repositories"];

    const observer = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            mutation.addedNodes.forEach(node => {
                if (node.nodeType === 1) { // Ensure it's an element
                    node.querySelectorAll('h5').forEach(h5 => {
                        if (keywords.some(keyword => h5.textContent.includes(keyword))) {
                            let parent = h5;
                            for (let i = 0; i < 5; i++) {
                                if (parent.parentElement) {
                                    parent = parent.parentElement;
                                } else {
                                    return; // Exit if there are fewer than 5 ancestors
                                }
                            }
                            parent.remove();
                        }
                    });
                }
            });
        });
    });

    // Observe the whole document, including subtree modifications
    observer.observe(document, {
        childList: true,
        subtree: true
    });

    // Function to observe shadow DOM elements
    function observeShadowRoots(node) {
        if (node.shadowRoot) {
            observer.observe(node.shadowRoot, { childList: true, subtree: true });
        }
    }

    // Observe shadow DOM elements dynamically added
    const shadowObserver = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            mutation.addedNodes.forEach(node => {
                if (node.nodeType === 1) { // Ensure it's an element
                    observeShadowRoots(node);
                }
            });
        });
    });

    // Start observing for new shadow DOM elements
    shadowObserver.observe(document, {
        childList: true,
        subtree: true
    });


})();