您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Open redirected/cloaked links directly
当前为
- // ==UserScript==
- // @name Decloak links and open directly
- // @description Open redirected/cloaked links directly
- // @version 2.0.4
- // @author wOxxOm
- // @namespace wOxxOm.scripts
- // @icon https://i.imgur.com/cfmXJHv.png
- // @resource icon https://i.imgur.com/cfmXJHv.png
- // @license MIT License
- // @run-at document-start
- // @grant GM_getResourceURL
- // @match *://*/*
- // ==/UserScript==
- /* jshint lastsemic:true, multistr:true, laxbreak:true, -W030, -W041, -W084 */
- var RX_DETECT = /=(\w+(?::\/\/|%3[Aa]%2[Ff]%2[Ff])[^+&?]+)/;
- var RX_SKIP_LOGIN = /[?&=\/]\w*(sign|log)([io]n|out|off)/;
- var POPUP = document.createElement('a');
- POPUP.id = GM_info.script.name;
- POPUP.title = 'Original link';
- POPUP.style.cssText = 'all: unset;' +
- 'width: 18px;' +
- 'height: 18px;' +
- 'background: url("' + GM_getResourceURL('icon') + '") center no-repeat;' +
- 'background-size: 16px;' +
- 'background-color: white;' +
- 'opacity: 0;' +
- 'transition: opacity .5s;' +
- 'border: 1px solid #888;' +
- 'border-radius: 11px;' +
- 'z-index: 2147483647;' +
- 'margin-left: 0;' +
- 'position: absolute;'
- .replace(/;/g, '!important;');
- var allLinks = document.getElementsByTagName('a');
- window.addEventListener('mousedown', decloakOnClick, true);
- window.addEventListener('keydown', function(e) { if (e.keyCode == 13) decloakOnClick(e) }, true);
- document.addEventListener('DOMContentLoaded', function() {
- process(allLinks);
- new MutationObserver(function(mutations) {
- if (allLinks[0])
- setTimeout(extractLinks, 0, mutations);
- }).observe(document.body, {childList: true, subtree: true});
- });
- function extractLinks(mutations) {
- var extracted = [];
- for (var m = 0, ml = mutations.length; m < ml; m++) {
- for (var n = 0, added = mutations[m].addedNodes, nl = added.length; n < nl; n++) {
- var node = added[n];
- if (node.localName == 'a')
- extracted.push(node);
- else if (node.children && node.children.length) {
- var childLinks = node.getElementsByTagName('a');
- if (childLinks[0])
- [].push.apply(extracted, childLinks);
- }
- }
- }
- if (extracted.length)
- process(extracted);
- }
- function process(links) {
- for (var i = 0, len = links.length; i < len; i++) {
- var a = links[i];
- if (a.href.match(/^(http|ftp)/) && decloak(a))
- a.addEventListener('mouseover', onHover, true);
- }
- }
- function onHover(e) {
- if (onHover.element)
- onHover.element.removeEventListener('mouseout', cancelHover);
- clearTimeout(onHover.timeout);
- onHover.timeout = setTimeout(showPopup, 500, this);
- onHover.element = this;
- this.addEventListener('mouseout', cancelHover);
- }
- function cancelHover(e) {
- this.removeEventListener('mouseout', cancelHover);
- clearTimeout(cancelHover.timeout);
- cancelHover.timeout = setTimeout(hidePopup, 500, this);
- }
- function showPopup(a) {
- if (!a.parentElement || !a.matches(':hover'))
- return;
- var linkStyle = getComputedStyle(a);
- POPUP.href = a.hrefUndecloaked;
- POPUP.style.opacity = '0';
- POPUP.style.marginLeft = -(
- (parseFloat(linkStyle.paddingRight) || 0) +
- (parseFloat(linkStyle.marginRight) || 0) +
- (parseFloat(linkStyle.borderRightWidth) || 0)
- ) + 'px';
- setTimeout(function() { POPUP.style.opacity = '1' }, 0);
- a.parentElement.insertBefore(POPUP, a.nextSibling);
- POPUP.addEventListener('click', openOriginal);
- }
- function hidePopup(a) {
- if (POPUP.matches(':hover') || onHover.element && onHover.element.matches(':hover')) {
- cancelHover.call(a);
- } else if (POPUP.style.opacity == '1') {
- POPUP.style.opacity = '0';
- cancelHover.call(a);
- } else {
- onHover.element = null;
- POPUP.remove();
- }
- }
- function openOriginal(e) {
- POPUP.href = '';
- e.preventDefault();
- e.stopPropagation();
- e.stopImmediatePropagation();
- setTimeout(function() {
- onHover.element.href = onHover.element.hrefUndecloaked;
- onHover.element.dispatchEvent(new MouseEvent('click', {bubbles: true}));
- });
- }
- function decloak(a) {
- if (a == POPUP)
- return;
- if (location.hostname.indexOf('yandex.') >= 0) {
- a.onmousedown = null;
- a.onclick = null;
- }
- var m = a.href.match(/=(\w+(?::\/\/|%3[Aa]%2[Ff]%2[Ff])[^+&?\/]+)/);
- if (!m)
- return;
- if (a.hostname == 'disqus.com' && a.pathname.startsWith('/embed/comments/'))
- return;
- var realUrl = decodeURIComponent(m[1]);
- if (a.hostname == 'disq.us' && realUrl.lastIndexOf(':') != realUrl.indexOf(':'))
- realUrl = realUrl.substr(0, realUrl.lastIndexOf(':'));
- if (new URL(realUrl).hostname == a.hostname || a.href.match(/[?&=\/]\w*(sign|log)[io]n/)) {
- // console.debug('Decloak skipped: assumed a login redirection.');
- return;
- }
- a.hrefUndecloaked = a.href;
- a.href = realUrl;
- return true;
- }
- function decloakOnClick(e) {
- var a = e.target.closest && e.target.closest('a');
- if (!a || !a.hrefUndecloaked || !a.href.match(/^(http|ftp)/))
- return;
- decloak(a);
- }