您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Open redirected/cloaked links directly
当前为
- // ==UserScript==
- // @name Decloak links and open directly
- // @description Open redirected/cloaked links directly
- // @version 2.2.0
- // @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==
- 'use strict';
- const POPUP = document.createElement('a');
- POPUP.id = GM_info.script.name;
- POPUP.title = 'Original link';
- let isPopupStyled;
- let lastLink;
- let hoverTimer;
- let hoverStopTimer;
- addEventListener('keypress', e => e.which === 13 && decloakLink(e), true);
- addEventListener('mousedown', decloakLink, true);
- addEventListener('mouseover', onHover, true);
- function onHover(event) {
- const a = decloakLink(event);
- if (a) {
- if (lastLink)
- lastLink.removeEventListener('mouseout', cancelHover);
- clearTimeout(hoverTimer);
- hoverTimer = setTimeout(showPopup, 500, a);
- a.addEventListener('mouseout', cancelHover);
- }
- lastLink = a;
- }
- function cancelHover(e) {
- this.removeEventListener('mouseout', cancelHover);
- clearTimeout(hoverStopTimer);
- hoverStopTimer = setTimeout(hidePopup, 500, this);
- }
- function showPopup(a) {
- if (!a.matches(':hover'))
- return;
- if (!isPopupStyled) {
- isPopupStyled = true;
- POPUP.style.cssText = //'all: unset;' +
- 'width: 18px;' +
- 'height: 18px;' +
- 'background: url("' + GM_getResourceURL('icon') + '") center no-repeat, white;' +
- 'background-size: 16px;' +
- 'opacity: 0;' +
- 'transition: opacity .5s;' +
- 'border: 1px solid #888;' +
- 'border-radius: 11px;' +
- 'z-index: 2147483647;' +
- 'margin-left: 0;' +
- 'cursor: pointer;' +
- 'position: absolute;'
- .replace(/;/g, '!important;');
- }
- const 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) +
- Math.max(0, a.getBoundingClientRect().right + 32 - innerWidth)
- ) + 'px';
- setTimeout(() => (POPUP.style.opacity = '1'));
- a.parentElement.insertBefore(POPUP, a.nextSibling);
- POPUP.addEventListener('click', openOriginal);
- }
- function hidePopup(a) {
- if (POPUP.matches(':hover') || lastLink && lastLink.matches(':hover')) {
- cancelHover.call(a);
- } else if (POPUP.style.opacity === '1') {
- POPUP.style.opacity = '0';
- cancelHover.call(a);
- } else {
- lastLink = null;
- POPUP.remove();
- }
- }
- function openOriginal(e) {
- POPUP.href = '';
- e.preventDefault();
- e.stopPropagation();
- e.stopImmediatePropagation();
- setTimeout(() => {
- lastLink.href = lastLink.hrefUndecloaked;
- lastLink.dispatchEvent(new MouseEvent('click', {bubbles: true}));
- });
- }
- function decloakLink(event) {
- const a = getClosestLink(event);
- if (!a || a === POPUP)
- return;
- if (a.hrefUndecloaked)
- return a;
- if (/\bthis\.href\s*=[^=]/.test(a.getAttribute('onmousedown')))
- a.onmousedown = null;
- if (/\bthis\.href\s*=[^=]/.test(a.getAttribute('onclick')))
- a.onclick = null;
- const href = a.href.baseVal || a.href;
- const m = href.match(/[=?/]((ftps?|https?)((:|%3[Aa])\/\/[^+&]+|%3[Aa]%2[Ff]%2[Ff][^+&/]+))/);
- if (!m ||
- a.hostname === 'disqus.com' && a.pathname.startsWith('/embed/comments/')) {
- return;
- }
- let 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 ||
- href.match(/[?&=/]\w*([Ss]ign|[Ll]og)[io]n/)) {
- console.debug('Decloak skipped: assumed a login redirection.');
- return;
- }
- a.hrefUndecloaked = href;
- a.setAttribute('href', realUrl);
- a.rel = 'external noreferrer nofollow noopener';
- return a;
- }
- function getClosestLink(event) {
- const a = event.composedPath
- ? event.composedPath().find(el => el.tagName === 'A')
- : event.target.closest('a');
- return a && /^(f|ht)tps?:/.test(a.getAttribute('href')) && a;
- }