Greasy Fork is available in English.

linkPreviewer

在页面右侧预览超链接内容。直接点击链接,将在页面右侧打开链接内容;按 shift 点击链接,将在本页跳转到链接内容;按 ctrl 或 cmd 点击链接,将在新标签页打开链接内容;同时按 shift 和 ctrl 或 shift 加 cmd 点击右侧预览页面内部的链接,将在本页面跳转到点击链接的内容。请自行添加白名单。

// ==UserScript==

// @name:zh-CN  超链接预览器
// @name:zh-TW  超鏈接預覽器
// @name:ko     超鏈接預覽器
// @name:ja     超鏈接預覽器
// @name        linkPreviewer

// @namespace   leizingyiu.net

// @author      leizingyiu
// @version     2022.10.09

// @include     http*://*.one-tab.com/page/*
// @include     /http.*:\/\/\d*\.\d*\.\d*\.\d*:*\d*.*/
// @include     file://*
// @grant       none

// @description:zh-CN 在页面右侧预览超链接内容。直接点击链接,将在页面右侧打开链接内容;按 shift 点击链接,将在本页跳转到链接内容;按 ctrl 或 cmd 点击链接,将在新标签页打开链接内容;同时按 shift 和 ctrl 或 shift 加 cmd 点击右侧预览页面内部的链接,将在本页面跳转到点击链接的内容。请自行添加白名单。

// @description:zh-TW 在頁面右側預覽超鏈接內容。直接點擊鏈接,將在頁面右側打開鏈接內容;按 shift 點擊鏈接,將在本頁跳轉到鏈接內容;按 ctrl 或 cmd 點擊鏈接,將在新標籤頁打開鏈接內容;同時按 shift 和 ctrl 或 shift 加 cmd 點擊右側預覽頁面內部的鏈接,將在本頁面跳轉到點擊鏈接的內容。請自行添加白名單。

// @description: Preview the hyperlink content on the right side of the page. Clicking the link directly will open the link content on the right side of the page; pressing shift to click the link will jump to the link content on this page; pressing ctrl or cmd to click the link will open the link content in a new tab; pressing shift and ctrl or Shift + cmd Click the link inside the preview page on the right, and it will jump to the content of the clicked link on this page. 

// @description:ja  ページの右側でハイパーリンクのコンテンツをプレビューします。 リンクを直接クリックすると、ページの右側にリンク コンテンツが開きます。Shift キーを押してリンクをクリックすると、このページのリンク コンテンツにジャンプします。Ctrl または cmd を押してリンクをクリックすると、リンク コンテンツが新しいタブで開きます。 ; Shift + ctrl または Shift + cmd を押す 右側のプレビュー ページ内のリンクをクリックすると、このページのクリックしたリンクのコンテンツにジャンプします。 ホワイトリストは自分で追加してください。

// @description:ko  페이지 오른쪽에서 하이퍼링크 내용을 미리 봅니다. 링크를 직접 클릭하면 페이지 오른쪽에 링크 내용이 열리고, Shift 키를 눌러 링크를 클릭하면 이 페이지의 링크 내용으로 이동합니다. ctrl 또는 cmd를 눌러 링크를 클릭하면 새 탭에서 링크 내용이 열립니다. ; Shift + ctrl 또는 Shift + cmd 누르기 오른쪽 미리보기 페이지 내부의 링크를 클릭하면 해당 페이지에서 클릭한 링크의 내용으로 이동합니다. 화이트리스트를 직접 추가하세요.

// @license     GNU AGPLv3

// @description 在页面右侧预览超链接内容。直接点击链接,将在页面右侧打开链接内容;按 shift 点击链接,将在本页跳转到链接内容;按 ctrl 或 cmd 点击链接,将在新标签页打开链接内容;同时按 shift 和 ctrl 或 shift 加 cmd 点击右侧预览页面内部的链接,将在本页面跳转到点击链接的内容。请自行添加白名单。
// ==/UserScript==


const pageWName = '页面宽度',
    frameWName = '窗口宽度',
    widthSettings = {
        'one-tab.com': {
            '页面宽度': 1440,
            '窗口宽度': '64%'
        }
    },
    contentSpecifyWidth = {
        'zcool.com.cn': 1440
    };
let pageW = 1440,
    frameW = 480;

const iframeId = 'yiu_linkPreview_iframe',
    iframeClass = 'yiu_linkPreview',
    bodyClass = 'yiu_previewPage',
    aClass = 'yiu_previewing',
    searchName = 'yiu_link_previewer';

let scaleK = frameW / pageW;

Object.keys(widthSettings).filter(u => window.location.host.includes(u)).map(u => {
    let w = window.innerWidth;
    let pW = widthSettings[u][pageWName],
        fW = widthSettings[u][frameWName];
    console.log(w, pW, fW);
    const widthNumFn = (n, w) => typeof n == 'string' && n.includes('%') ?
        Number(n.replace(/%/g, '')) / 100 * w :
        (isFinite(Number(n)) ? Number(n) : NaN);
    pW = widthNumFn(pW, w), fW = widthNumFn(fW, w);
    pageW = pW, frameW = fW;
    console.log(w, pW, fW);
    scaleK = fW / pW;
});

bodyCapture = false;
aCapture = true;

let iframe = document.createElement('iframe');
iframe.id = iframeId;
iframe.classList.add(iframeClass);
document.body.appendChild(iframe);


let style = document.createElement('style');
style.innerHTML = `
    iframe#${iframeId}{
      width:${pageW}px; height:${100 / scaleK}vh;
      position:fixed; top:0; right:-100vw;
      transform:scale(0,${scaleK});
      transform-origin:right top;
      pointer-events: none;
      opacity:0;
      background: #fffa;
    }

    body.${bodyClass}{
      padding-right:${pageW * scaleK}px;
    }

    body.${bodyClass} iframe#${iframeId}.${iframeClass}{
      transform:scale(${scaleK})!important;
      right:0!important;
      pointer-events:auto;
      opacity:1;
    }

    a.${aClass}{
    background: var(--bgc);
    color: #fff;
    }
    a{transition:background 0.5s ease;}
    body{transition:padding 0.5s ease;}
    iframe{transition:transform 0.5s ease , right 0.5s ease,  opacity 0.3s ease;}
`;
document.body.appendChild(style);

function iframeFitContentWidth() {
    Object.keys(contentSpecifyWidth).filter(u => iframe.src.includes(u)).map(u => {
        let tempPW = contentSpecifyWidth[u],
            tempScaleK = frameW / tempPW;

        iframe.style.cssText =
            ` width:${tempPW}px; height:${100 / tempScaleK}vh;
                        transform:scale(${tempScaleK})!important;`;
        document.body.style.paddingRight = tempPW * tempScaleK + 'px';
    });
}

function cleanSpecifyStyle() {
    if(iframe.style.cssText){
        iframe.style.cssText = '';
    }
    if(document.body.style.paddingRight){
        document.body.style.paddingRight = 'unset';
    }
}
function bodyClickFn() {
    console.trace('bodyClick');

    document.body.classList.remove(bodyClass);
    [...document.querySelectorAll(`.${aClass}`)].map(_a => {
        _a.classList.remove(aClass);
    });
    cleanSpecifyStyle();
}

[...document.querySelectorAll('a')].filter(a => !a.href.match(/^javascript/)).map(a => {
    a.style.setProperty('--bgc', `hsl(${360 * Math.random()}deg ${70 + 20 * Math.random()}% 50%)`);
    a.removeAttribute('target');
    a.setAttribute('data-link', a.href);
    a.setAttribute('href', 'javascript:void 0;');
    let origFn = a.onclick;
    a.addEventListener('click', function (ev) {

        const openBoo = ev.ctrlKey || ev.metaKey,
            jumpBoo = ev.shiftKey;

        if (openBoo == false && jumpBoo == false) {

            console.log(a.getAttribute('class'), a.classList.contains(aClass));
            if (!a.classList.contains(aClass)) {

                setTimeout(function () {
                    a.classList.add(aClass);
                    iframe.src = a.getAttribute('data-link');

                    cleanSpecifyStyle()
                    iframeFitContentWidth();


                    document.body.classList.add(bodyClass);

                    var url = new URL(window.location),
                        search = new URLSearchParams(url.search);
                    search.set(searchName, JSON.stringify(a.getAttribute('data-link')));
                    url.search = search.toString();
                    window.history.pushState(null, null, url.href);

                }, 200);
            }

            document.body.classList.remove(bodyClass);
            [...document.querySelectorAll(`.${aClass}`)].map(_a => {
                _a.classList.remove(aClass);
            });
            iframe.src = null;

            return false;

        } else {
            if (origFn) {
                origFn();
            }

            if (a.getAttribute('data-link')) {
                if (openBoo == true && jumpBoo == true) {
                    top.location.href = a.getAttribute('data-link');
                } else if (openBoo == true) {
                    window.open(a.getAttribute('data-link'), '_blank');
                } else {
                    window.location.href = a.getAttribute('data-link');
                }
            }

        }
    }, aCapture);

    a.onmouseenter = function () {
        // console.log(a,'in');
        document.body.removeEventListener('click', bodyClickFn);
    }

    a.onmouseleave = function () {
        // console.log(a,'out');
        document.body.addEventListener('click', bodyClickFn, bodyCapture);
    }
}, false);

document.body.addEventListener('click', bodyClickFn, bodyCapture);

window.addEventListener('load', function () {
    setTimeout(
        function () {
            let url = new URL(window.location),
                search = new URLSearchParams(url.search);
            let frameSrc = search.get(searchName);
            if (frameSrc) {
                let srcUrl = new URL(decodeURIComponent(JSON.parse(frameSrc)));
                iframe.src = srcUrl.href;
                cleanSpecifyStyle();
                iframeFitContentWidth()
                document.body.classList.add(bodyClass);
            };
        }, 100
    )
});