您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Replace shortened URLs with real URLs
当前为
// ==UserScript== // @name FuckShortenedUrl // @namespace https://greasyfork.org/en/users/173996-wtfjs // @version 0.25 // @description Replace shortened URLs with real URLs // @author wtfjs // @license MIT // @run-at document-start // @match https://*/* // @match http://*/* // @grant none // ==/UserScript== ;(function __FuckShortenedUrl() { "use strict"; var utils = { $: function $(selector, parent) { var _parent = parent || document return _parent.querySelector(selector) }, $$: function $$(selector, parent) { var _parent = parent || document return _parent.querySelectorAll(selector) }, forEachRight: function forEachRight(arr, fn) { for (var i = (arr.length >>> 0) - 1; i >= 0; i -= 1) { var it = arr[i] var res = fn(it, i, arr) if (res === false) { break; } } }, concurrent: function concurrent(job) { var dispatch = window.requestIdleCallback || window.requestAnimationFrame || window.setTimeout dispatch(job) }, isElement: function isElement(any) { return typeof any === "object" && any.nodeType === 1 // Node.ELEMENT_NODE }, getSearchParams: function getSearchParams(urlStr) { try { return new URL(urlStr).searchParams } catch (e) {} return null }, findParent: function findParent(el, elOrMatchFn) { var matchFn = typeof elOrMatchFn === "function" ? elOrMatchFn : function matchFn(it) { return it === elOrMatchFn } var node = el.parentElement while (node !== null) { if (matchFn(node)) { return node } node = node.parentElement } return null } } var handlers = [ [ /https?:\/\/link\.zhihu\.com/, function transform($link) { var searchParams = utils.getSearchParams($link.href) if (searchParams && searchParams.get("target")) { var realHref = searchParams.get("target") $link.href = realHref return realHref } } ], [ /https?:\/\/douc\.cc/, function transform($link) { if (/https?:\/\//.test($link.title)) { var realHref = $link.title $link.textContent = $link.textContent.replace($link.href, realHref) $link.href = realHref return realHref } } ], [ /https?:\/\/(www.)?douban\.com\/link2/, function transform($link) { var searchParams = utils.getSearchParams($link.href) if (searchParams && searchParams.get("url")) { var realHref = searchParams.get("url") $link.href = realHref return realHref } } ], [ /https?:\/\/t\.co/, function transform($link) { var $cardWrapper = utils.findParent($link, function(node) { return node.dataset.testid === "card.wrapper" }) var isCardLink = !!$cardWrapper var realHref if (isCardLink) { try { var $textContent = $cardWrapper.parentElement.parentElement.parentElement.previousElementSibling var $textLink = utils.$("a[href^=http]", $textContent) if ($textLink) { realHref = getTextLinkHref($textLink) $link.href = realHref return realHref } } catch (e) {} } else { realHref = getTextLinkHref($link) $link.href = realHref return realHref } function getTextLinkHref($el) { return $el.textContent.replace(/((\.\.\.)|(…))$/, '') } } ], [ /https?:\/\/(www\.)?youtube\.com\/redirect\?/, function transform($link) { var searchParams = utils.getSearchParams($link.href) if (searchParams && searchParams.get("q")) { var realHref = searchParams.get("q") $link.href = realHref return realHref } } ] ] var REDIRECT_URL_SELECTORS = [ "t.co","link.zhihu.com","douc.cc","douban.com/link2", "youtube.com/redirect" ] .map(function(url) {return 'a[href*="' + url + '/"]'}) .join(",") function selectLinks(parent) { return utils.$$(REDIRECT_URL_SELECTORS, parent) } function transformLinks($links, cache) { utils.forEachRight($links, function($link) { utils.concurrent(function transform() { if (!$link || !$link.href) return var href = $link.href var cachedHref = cache[href] if (cachedHref) { if (href !== cachedHref) { $link.href = cachedHref } return } utils.forEachRight(handlers, function(handler) { var pattern = handler[0] var fn = handler[1] if (pattern.test(href)) { var res = fn($link) if (res) { cache[href] = res } return false } }) }) }) } function onDomMutation(mutationList) { var cache = {} utils.forEachRight(mutationList, function(mutation) { utils.concurrent(function () { var target = mutation.target if (!target || !utils.isElement(target)) return var $newLinks = [] utils.forEachRight(selectLinks(target), function addNewLink($link) { $newLinks.push($link) }) transformLinks($newLinks, cache) }) }) } function start() { console.log("----------- FuckShortenedUrl -------------") transformLinks(selectLinks(), {}) var observer = new MutationObserver(onDomMutation) observer.observe(document.body, {subtree: true, childList: true}) } window.addEventListener("load", start) })()