rBlock

移除一些网站用于数据统计的跳转功能,加快访问目标地址的速度。包括谷歌、知乎等,并添加少量定制化。| Removes redirects of some sites, such as google, zhihu..., add some customization.

Verzia zo dňa 15.06.2016. Pozri najnovšiu verziu.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name         rBlock
// @description  移除一些网站用于数据统计的跳转功能,加快访问目标地址的速度。包括谷歌、知乎等,并添加少量定制化。| Removes redirects of some sites, such as google, zhihu..., add some customization.
// @namespace    https://greasyfork.org/zh-CN/scripts/20568-rblock
// @author       nonoroazoro
// @include      /^https?\:\/\/(www|encrypted|news)\.google\./
// @include      /^https?\:\/\/(www|zhuanlan)\.zhihu\./
// @version      1.2.2
// @run-at       document-end
// @grant        none
// ==/UserScript==

if (typeof unsafeWindow === "undefined")
{
    unsafeWindow = window;
}

const rBlock = {

    _blockers: [],

    start: function()
    {
        this.reset();
        for (let blocker of this._blockers)
        {
            blocker.start();
        }
    },

    reset: function()
    {
        this._blockers = [];

        // 1. google
        this._blockers.push(
        {
            start: function()
            {
                if (/^https?\:\/\/(www|encrypted|news)\.google\./.test(unsafeWindow.location.href))
                {
                    const scope = this._getScope();
                    if (scope)
                    {
                        this._block(scope);
                        const observer = new unsafeWindow.MutationObserver((p_mutations) =>
                        {
                            this._block(scope);
                        });
                        observer.observe(document.body,
                        {
                            childList: true,
                            subtree: true
                        });
                    }
                }
            },

            // block redirects of google
            _block: function(p_scope)
            {
                let base;
                let elem;
                let elems;
                if (["all", "videos", "news", "apps"].indexOf(p_scope) != -1)
                {
                    // 1. all/videos/news/apps
                    base = document.querySelector("div#search");
                    elems = base.querySelectorAll(`a[onmousedown^="return rwt("]`);
                    for (let e of elems)
                    {
                        _removeAttributes(e, "onmousedown");
                    }
                }
                else if (["images"].indexOf(p_scope) != -1)
                {
                    // 2. images
                    base = document.querySelector("div#search");
                    elems = base.querySelectorAll(`a[class^="irc_"], a[class*=" irc_"]`);
                    for (let e of elems)
                    {
                        _removeListeners(e, "mousedown");
                    }
                }
                else if (["books"].indexOf(p_scope) != -1)
                {
                    // 3. books
                    base = document.querySelector("div#search");
                    elems = base.querySelectorAll(`a`);
                    for (let e of elems)
                    {
                        // open in new tab
                        if (!e.target)
                        {
                            e.target = "_blank";
                        }
                    }
                }
                else if (["news.google.com"].indexOf(p_scope) != -1)
                {
                    // 4. news.google.com
                    elems = document.querySelectorAll(`.content-pane-container a.article`);
                    for (let e of elems)
                    {
                        _removeListeners(e, "click mousedown");
                    }
                }

                // 4. general
                revealURL(
                    document.querySelectorAll(`a[href^="/url?"]`),
                    /^(?:\/url\?.*url=)(.*?)(?:&usg=|$)/i
                );

                // 5. cached links
                let menuLink;
                let cacheLink;
                elems = document.querySelectorAll(`a[href^="http://webcache.googleusercontent."], a[href^="https://webcache.googleusercontent."]`);
                for (let e of elems)
                {
                    e.style.display = "inline";
                    menuLink = e.closest("div.action-menu.ab_ctl");

                    cacheLink = document.createElement("a");
                    cacheLink.setAttribute("href", e.getAttribute("href").replace(/^http\:/, "https:"));
                    cacheLink.target = "_blank";
                    cacheLink.innerText = " Cached ";

                    menuLink.parentNode.insertBefore(cacheLink, menuLink);
                }
            },

            _getScope: function()
            {
                const elem = document.querySelector("div.hdtb-msel");
                const result = (elem ? elem.innerText : unsafeWindow.location.host).toLowerCase();
                return result;
            }
        });

        // 2. zhihu
        this._blockers.push(
        {
            start: function()
            {
                if (/^https?\:\/\/(www|zhuanlan)\.zhihu\./.test(unsafeWindow.location.href))
                {
                    this._block();
                    const observer = new unsafeWindow.MutationObserver((p_mutations) =>
                    {
                        this._block();
                    });
                    observer.observe(document.body,
                    {
                        childList: true,
                        subtree: true
                    });
                }
            },

            _block: function()
            {
                // 1. general
                revealURL(
                    document.querySelectorAll(`a[href^="http://link.zhihu.com"], a[href^="https://link.zhihu.com"]`),
                    /https?\:\/\/link\.zhihu\.com\/\?target=(.*)/i
                );
            }
        });
    }
};

function _removeAttributes(p_element, p_attributes)
{
    if (p_element && typeof p_attributes === "string")
    {
        const attributes = p_attributes.split(/\W+/) || [];
        for (let attribute of attributes)
        {
            p_element.removeAttribute(attribute);
        }
    }
}

function _removeListeners(p_element, p_events)
{
    if (p_element && typeof p_events === "string")
    {
        const events = p_events.split(/\W+/) || [];
        for (let event of events)
        {
            p_element.removeEventListener(event, _preventDefaultAction, true);
            p_element.addEventListener(event, _preventDefaultAction, true);
        }
    }
}

function _preventDefaultAction(e)
{
    e.stopPropagation();
}

/**
 * reveal url
 */
function revealURL(p_elems, p_regex)
{
    if (p_elems && p_regex)
    {
        for (let e of p_elems)
        {
            // reveal url
            const m = e.getAttribute("href").match(p_regex);
            if (m && m[1])
            {
                e.setAttribute("href", decodeURIComponent(m[1]));
            }

            // open in new tab
            if (!e.target)
            {
                e.target = "_blank";
            }
        }
    }
}

rBlock.start();