Imgur圖片使用duckduckgo代理

使用proxy.duckduckgo.com 代理重定向 Imgur 圖片,並防止頁面重新聚焦時 src 被還原

// ==UserScript==
// @name         Imgur圖片使用duckduckgo代理
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  使用proxy.duckduckgo.com 代理重定向 Imgur 圖片,並防止頁面重新聚焦時 src 被還原
// @author       shanlan
// @match        *://*/*
// @license      MIT
// @icon         https://www.google.com/s2/favicons?sz=64&domain=imgur.com
// ==/UserScript==

(function() {
    'use strict';

    const observer = new MutationObserver((mutations) => {
        for (const mutation of mutations) {
            if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
                const node = mutation.target;
                if (node.nodeName === 'IMG') {
                    redirectImg(node);
                }
            }
            for (const node of mutation.addedNodes) {
                walk(node);
            }
        }
    });

    function walk(root) {
        if (!root.ownerDocument) return;

        const walker = root.ownerDocument.createNodeIterator(
            root,
            NodeFilter.SHOW_ELEMENT,
            (node) => {
                if (node.nodeName === 'IMG') return NodeFilter.FILTER_ACCEPT;
                if (node.nodeType === Node.ELEMENT_NODE && node.shadowRoot) return NodeFilter.FILTER_ACCEPT;
                if (node.nodeName === 'STYLE' || node.nodeName === 'SCRIPT') return NodeFilter.FILTER_REJECT;
                return NodeFilter.FILTER_SKIP;
            }
        );

        let node;
        while ((node = walker.nextNode())) {
            if (node.shadowRoot) {
                for (const child of node.shadowRoot.children) {
                    if (child.nodeName !== 'STYLE' && child.nodeName !== 'SCRIPT') {
                        walk(child);
                    }
                }
                observer.observe(node.shadowRoot, observerConfig);
                continue;
            }

            if (node.nodeName === 'IMG') {
                redirectImg(node);
            }
        }
    }

    const observerConfig = {
        childList: true,
        subtree: true,
        attributes: true,
        attributeFilter: ['src']
    };

    const redirectImg = (elem) => {
        const src = elem.src;
        if (src.startsWith('https://proxy.duckduckgo.com/iu/?u=')) return;

        if (/https?:\/\/(\w+\.)?imgur\.com\/(\w*)+(\.[a-zA-Z]{3,4})/.test(src)) {
            elem.src = 'https://proxy.duckduckgo.com/iu/?u=' + encodeURIComponent(src);
        }
    };

    walk(document.body);
    observer.observe(document.body, observerConfig);
})();