链接预览助手

功能1:长按链接将打开内置窗口预览。Esc 可以关闭窗口。按住 Shift 或者 Alt 或者 Ctrl 或者 Command 键 或者 鼠标移动,长按时不会打开预览。功能2:鼠标中键 + (Shift 或者 Alt 或者 Ctrl 或者 Command 键),新窗口打开链接。

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==UserScript==
// @name         链接预览助手
// @namespace    https://github.com/CheckCoder
// @version      0.8.0
// @description  功能1:长按链接将打开内置窗口预览。Esc 可以关闭窗口。按住 Shift 或者 Alt 或者 Ctrl 或者 Command 键 或者 鼠标移动,长按时不会打开预览。功能2:鼠标中键 + (Shift 或者 Alt 或者 Ctrl 或者 Command 键),新窗口打开链接。
// @author       check
// @match        http://*/*
// @match        https://*/*
// @grant        none
// @license      GPL
// ==/UserScript==

(function() {
    'use strict';

    // https://www.baidu.com 自动将 http 请求升级为 https
    if (window.location.href.indexOf('https://www.baidu.com') === 0) {
        const meta = document.createElement('meta');
        meta.setAttribute('http-equiv', 'Content-Security-Policy');
        meta.setAttribute('content', 'upgrade-insecure-requests');
        document.head.appendChild(meta);
    }

    // 界面
    const iframeContainer = document.createElement('div');
    iframeContainer.setAttribute('style', 'width: 100vw; height: 100vh; position: fixed; z-index: 99999; top: 0; left:0; display:none; background: rgba(0,0,0,0.5); justify-content: center; align-items:center');
    const iframe = document.createElement('iframe');
    iframe.setAttribute('style', 'width:90vw; height: 80vh; background: white; border: none');

    // 设置id
    const iframeContainerId = '$link-preview-iframeContainer';
    const iframeId = '$link-preview-iframe';
    iframeContainer.setAttribute('id', iframeContainerId);
    iframe.setAttribute('id', iframeId);

    function getIframeContainer() {
        return document.getElementById(iframeContainerId);
    }

    function getIframe() {
        return document.getElementById(iframeId);
    }

    iframeContainer.appendChild(iframe);

    // 显示和隐藏控制
    function show() {
        if (!getIframeContainer()) document.body.appendChild(iframeContainer);
        iframeContainer.style.display = 'flex';
    }

    function hide() {
        iframeContainer.style.display = 'none';
        iframe.src = '';
    }
    iframeContainer.addEventListener('click', hide);

    function getATagByEvent(event) {
        for(let i = 0; i < event.path.length; i++) {
            const nodeName = event.path[i].nodeName;
            if (nodeName && nodeName.toLocaleLowerCase() === 'a') {
                return event.path[i];
            }
        }
    }

    // 长按逻辑
    let pressTimer = null;
    let hasIntoTimeout = false;
    let loogPressThreshold = 350;
    let isPressCancelButton = false;
    document.body.addEventListener('mousedown', function(event) {
        // 按住 Shift 或者 Alt 或者 Ctrl 或者 Command 键,不长按打开预览
        if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return;
        // 非鼠标左键,不长按打开预览
        if (event.button !== 0) return;
        const aTag = getATagByEvent(event);
        if (!aTag) return;

        const href = aTag.getAttribute('href');
        if (!href || href.indexOf('javascript:') === 0) return;

        pressTimer = setTimeout(function() {
            hasIntoTimeout = true;
            iframe.src = href;
            show();
        }, loogPressThreshold);
    });
    function cancelTimer() {
        if (!pressTimer) return;

        clearTimeout(pressTimer);
        pressTimer = null;
    }
    document.body.addEventListener('mouseup', cancelTimer);
    // 鼠标移动取消
    let moveTime = 0;
    document.body.addEventListener('mousemove', function() {
        if (!pressTimer) return;
        if (++moveTime < 2) return;
        cancelTimer();
        moveTime = 0;
    });

    // document.body.addEventListener('click', function(event) {
    //     if (hasIntoTimeout) event.preventDefault();
    //     hasIntoTimeout = false;
    // });

    // esc 关闭
    document.body.addEventListener('keydown', function(event) {
        if (event.key === 'Escape') {
            window.parent.postMessage('$link-preview-hide', '*');
        }
    });
    window.addEventListener('message', function(event){
        if (event.data === '$link-preview-hide') {
            hide();
            window.focus();
        }
    }, {
        capture: true
    });

    // 鼠标中键 + (Shift 或者 Alt 或者 Ctrl 或者 Command 键),新窗口打开链接
    document.body.addEventListener('mousedown', function(event) {
        if (event.button !== 1 || !(event.shiftKey || event.altKey || event.ctrlKey || event.metaKey)) return;

        const aTag = getATagByEvent(event);
        if (!aTag) return;

        const href = aTag.getAttribute('href');
        if (!href || href.indexOf('javascript:') === 0) return;

        window.open(href);
    });
})();