Greasy Fork is available in English.
移除一些网站用于数据统计的链接跳转,加快网站访问速度。
// ==UserScript==// @name rBlock// @author nonoroazoro// @description 移除一些网站用于数据统计的链接跳转,加快网站访问速度。// @description:en Removes redirects of web sites.// @homepageURL https://github.com/nonoroazoro/firefox/tree/master/greasemonkey/rBlock// @namespace https://gfork.dahi.icu/zh-CN/scripts/20568-rblock// @grant none// @version 1.3.8// @run-at document-end// @include /^https?:\/\/(.+\.)?google\./// @include /^https?:\/\/(.+\.)?zhihu\./// @include https://forum.gamer.com.tw/*// ==/UserScript==const rBlock = {_blockers: [],start(){this.init();for (const blocker of this._blockers){blocker.start();}},init(){this._blockers = [];const _host = window.location.host;// 1. googleif (/^(.+\.)?google\./.test(_host)){this._blockers.push({start(){// 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._observe(this._block);},// block redirects of google_block(){// 1. generallet elems = document.querySelectorAll(`a[href*="url="]`);revealURL(elems, /.*url=(http[^&]+)/i);// 2. imageselems = document.querySelectorAll(`a[jsaction][href]:not([href="javascript:void(0)"]):not(.rg_l)`);_removeAttributes(elems, "jsaction");// 3. all/videos/news/appselems = document.querySelectorAll(`a[onmousedown^="return rwt("]`);_removeAttributes(elems, "onmousedown");// 4. cached linkselems = document.querySelectorAll(`a[href^="http://webcache.googleusercontent."], a[href^="https://webcache.googleusercontent."]`);const targets = document.querySelectorAll(`a.rblock-cached-link`);if (elems.length !== targets.length * 2){// prevent duplicationlet menuLink;let cacheLink;for (const 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. zhihuif (/^(.+\.)?zhihu\./.test(_host)){this._blockers.push({start(){this._block();_observe(this._block);},_block(){// 1. generalrevealURL(document.querySelectorAll(`a[href*="?target="]`),/.*target=(http[^&]+)/i);// 2. open in new tabfor (const elem of document.querySelectorAll(`a.internal`)){_openInNewTab(elem);}}});}// 3. 巴哈姆特if (_host === "forum.gamer.com.tw"){this._blockers.push({start(){this._block();_observe(this._block);},_block(){// 1. generalrevealURL(document.querySelectorAll(`a[href*="?url="]`),/.*url=(http.+)/i);}});}}};function _observe(p_callback){if (typeof p_callback === "function" && document.body){(new window.MutationObserver(debounce(p_callback))).observe(document.body, { childList: true, subtree: true });}}function _removeAttributes(p_elements, p_attributes){if (p_elements && typeof p_attributes === "string"){const attributes = p_attributes.split(/\W+/) || [];for (const elem of p_elements){for (const attr of attributes){elem.removeAttribute(attr);}}}}/* eslint no-unused-vars: "off" */function _removeListeners(p_element, p_events){if (p_element && typeof p_events === "string"){const events = p_events.split(/\W+/) || [];for (const event of events){p_element.removeEventListener(event, _preventDefaultAction, true);p_element.addEventListener(event, _preventDefaultAction, true);}}}function _preventDefaultAction(e){e.stopPropagation();}function revealURL(p_elems, p_regex){if (p_elems && p_regex){let groups;for (const elem of p_elems){// reveal url & open in new tabgroups = decodeURIComponent(elem.getAttribute("href")).match(p_regex);if (groups && groups[1]){elem.setAttribute("href", groups[1]);_openInNewTab(elem);}}}}function _openInNewTab(p_elem){if (p_elem){p_elem.target = "_blank";}}function debounce(p_callback, p_delay = 500){let timer = null;return function _inner(...args){const context = this;window.clearTimeout(timer);timer = window.setTimeout(() =>{p_callback.apply(context, args);}, p_delay);};}function throttle(p_callback, p_threshhold = 500, p_scope){let last;let timer;return function _inner(...args){const now = +new Date();const context = p_scope || this;if (last && now < last + p_threshhold){window.clearTimeout(timer);timer = window.setTimeout(() =>{last = now;p_callback.apply(context, args);}, p_threshhold);}else{last = now;p_callback.apply(context, args);}};}rBlock.start();