// ==UserScript== // @name rBlock // @description 移除一些网站用于数据统计的跳转功能,加快访问目标地址的速度。包括 Google、GitHub、知乎等,并添加少量定制化。| Removes redirects of some sites, such as Google, GitHub, Zhihu..., add some customization. // @namespace https://greasyfork.org/zh-CN/scripts/20568-rblock // @homepageURL https://github.com/nonoroazoro/rBlock // @author nonoroazoro // @include /^https?\:\/\/(www|encrypted|news)\.google\./ // @include /^https?\:\/\/(www|zhuanlan)\.zhihu\./ // @include /^https?\:\/\/(gist\.)?github\.com/ // @version 1.2.6 // @run-at document-end // @grant none // @downloadURL 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)) { // 1. for static pages. // when google instant predictions is disabled, // this blocker will only be called once. this._block(); // 2. for dynamic pages. // when google instant predictions is enabled, // this blocker will be call whenever the current page is updated. _startMutationObserver( { "id": [ "search", // all/videos/news/shopping/books/apps ], "class": [ "irc_rit", // images "pspo-popout pspo-lpop", // shopping ] }, this._block ); } }, // block redirects of google _block: function () { const host = unsafeWindow.location.host; if (host === "news.google.com") { // 1. news.google.com const elems = document.querySelectorAll(`.content-pane-container a.article`); for (let e of elems) { _removeListeners(e, "click mousedown"); } } else { const base = document.querySelector("div#search"); if (base) { // 1. all/videos/news/apps let elems = base.querySelectorAll(`a[onmousedown^="return rwt("]`); for (let e of elems) { _removeAttributes(e, "onmousedown"); } // 2. images elems = base.querySelectorAll(`a[class^="irc_"], a[class*=" irc_"]`); for (let e of elems) { _removeListeners(e, "mousedown"); } // 3. books revealURL( base.querySelectorAll(`a[href^="/aclk?"]`), /\/aclk?.*url=(.*)/i ); // 4. general revealURL( document.querySelectorAll(`a[href*="/url?"]`), /(?:\/url\?.*url=)(.*?)(?:&usg=|$)/i ); // 5. cached links elems = document.querySelectorAll(`a[href^="http://webcache.googleusercontent."], a[href^="https://webcache.googleusercontent."]`); let targets = document.querySelectorAll(`a.rblock-cached-link`); if (elems.length != targets.length * 2) { // prevent duplication let menuLink; let cacheLink; for (let elem of elems) { elem.style.display = "inline"; menuLink = elem.closest("div.action-menu.ab_ctl"); cacheLink = document.createElement("a"); cacheLink.setAttribute("href", elem.getAttribute("href").replace(/^http\:/, "https:")); cacheLink.setAttribute("class", "rblock-cached-link"); cacheLink.target = "_blank"; cacheLink.innerText = " Cached "; menuLink.parentNode.insertBefore(cacheLink, menuLink); } } } } } } ); // 2. zhihu this._blockers.push( { start: function () { if (/^https?\:\/\/(www|zhuanlan)\.zhihu\./.test(unsafeWindow.location.href)) { this._block(); _startMutationObserver( { "id": [ "js-home-feed-list", // 首页最新动态 "zh-question-answer-wrap", // 具体内容 ], "class": [ "zm-item-rich-text expandable js-collapse-body", // 首页、话题显示全部 "zh-general-list clearfix", // 话题 ], "data-type": [ "daily", // 发现 ] }, this._block ); } }, _block: function () { // 1. general revealURL( document.querySelectorAll(`a[href^="http://link.zhihu.com"], a[href^="https://link.zhihu.com"], a[href^="//link.zhihu.com"]`), /(?:https?\:)?\/\/link\.zhihu\.com\/\?target=(.*)/i ); // 2. open in new tab const elems = document.querySelectorAll(`a.internal`); for (let elem of elems) { _openInNewTab(elem); } } } ); // 3. github this._blockers.push( { start: function () { if (/^https?\:\/\/(gist\.)?github\.com/.test(unsafeWindow.location.href)) { this._block(); } }, _block: function () { // 1. general document.addEventListener("keydown", (e) => { if (e.key === "s" || e.key === "S") { e.stopPropagation(); } }, true); } } ); } }; function _startMutationObserver(p_filter, p_handler) { if (typeof p_handler === "function") { const filter = p_filter || {}; const observer = new unsafeWindow.MutationObserver((p_mutations) => { let needUpdate = false; for (let mutation of p_mutations) { for (let key in p_filter) { if (p_filter[key].indexOf(mutation.target.getAttribute(key)) != -1) { needUpdate = true; break; } } if (needUpdate) { break; } } if (needUpdate) { p_handler(); } }); observer.observe(document.body, { childList: true, subtree: true } ); } } 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 _openInNewTab(e); } } } function _openInNewTab(p_elem) { if (p_elem && !p_elem.target) { p_elem.target = "_blank"; } } rBlock.start();