K-Drama Link Enhancer

A new, robust, and stable script to enhance K-drama links and convert IDs, with a working dark-mode settings panel.

目前為 2025-07-02 提交的版本,檢視 最新版本

// ==UserScript==
// @name         K-Drama Link Enhancer
// @namespace    http://tampermonkey.net/
// @version      5.1
// @description  A new, robust, and stable script to enhance K-drama links and convert IDs, with a working dark-mode settings panel.
// @author       asurpbs
// @match        https://rentry.co/sin-flix
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// @run-at       document-idle
// ==/UserScript==

(function() {
    'use strict';

    // --- Configuration ---
    const config = {
        showGoogleCircle: GM_getValue('showGoogleCircle', true),
        showMdlCircle: GM_getValue('showMdlCircle', true),
        convertBuzzheavierLinks: GM_getValue('convertBuzzheavierLinks', true)
    };

    // --- Style Definitions ---
    GM_addStyle(`
        #kdrama-settings-button {
            position: fixed; top: 10px; right: 10px; z-index: 10001;
            cursor: pointer; width: 24px; height: 24px;
        }
        #kdrama-settings-modal {
            display: none; position: fixed; z-index: 10002;
            left: 0; top: 0; width: 100%; height: 100%;
            background-color: rgba(0,0,0,0.5);
            justify-content: center; align-items: center;
        }
        .kdrama-modal-content {
            background-color: #fefefe; color: #111; padding: 20px; border: 1px solid #888;
            width: 80%; max-width: 500px; border-radius: 5px;
        }
        .dark-mode .kdrama-modal-content {
            background-color: #333; color: #eee; border-color: #555;
        }
        .kdrama-modal-content h2 { margin-top: 0; }
        .kdrama-modal-content label { display: block; margin-bottom: 10px; cursor: pointer; }
        .kdrama-modal-content input { vertical-align: middle; margin-right: 5px; }
        #kdrama-settings-close { float: right; font-size: 28px; font-weight: bold; cursor: pointer; line-height: 1; }
        .kdrama-circle {
            display: inline-block; width: 14px; height: 14px; border-radius: 50%;
            border: 1px solid #333; margin-right: 6px; cursor: pointer; z-index: 10000;
            flex-shrink: 0; vertical-align: middle;
        }
        .google-circle { background: linear-gradient(45deg, #4285F4 25%, #EA4335 25%, #EA4335 50%, #FBBC05 50%, #FBBC05 75%, #34A853 75%); }
        .mdl-circle { background: #fff; border: 2px solid #4285F4; }
    `);

    // --- Main Processing Function ---
    function enhancePageContent() {
        const content = document.querySelector('.entry-text article');
        if (!content || content.dataset.enhancedv51) return;

        console.log('K-Drama Link Enhancer (v5.1): Processing...');
        content.dataset.enhancedv51 = 'true';

        const dramaRegex = /^(?:\(reup\)|\(redo\))?\s*([^[(]+?)\s*\[[^\]]+\]\s*\((?:e\d+\s+of\s+\d+|\d+)ep\)/i;
        const buzzRegex = /\b(?![a-zA-Z]{12}\b)([a-zA-Z0-9]{12})\b/g;

        // --- Pass 1: Add Circles ---
        if (config.showGoogleCircle || config.showMdlCircle) {
            const walker = document.createTreeWalker(content, NodeFilter.SHOW_TEXT);
            const dramaNodes = [];
            while (walker.nextNode()) dramaNodes.push(walker.currentNode);

            dramaNodes.forEach(node => {
                if (node.parentNode.closest('a, .kdrama-circle-container')) return;

                const dramaMatch = node.textContent.trim().match(dramaRegex);
                if (dramaMatch && dramaMatch[1]) {
                    const cleanDramaName = dramaMatch[1].trim().replace(/:$/, '').trim();

                    const container = document.createElement('span');
                    container.className = 'kdrama-circle-container';

                    if (config.showGoogleCircle) {
                        const googleUrl = `https://www.google.com/search?q=${encodeURIComponent(cleanDramaName)}`;
                        const googleCircle = document.createElement('span');
                        googleCircle.className = 'kdrama-circle google-circle';
                        googleCircle.title = `Search '${cleanDramaName}' on Google`;
                        googleCircle.onclick = (e) => { e.stopPropagation(); window.open(googleUrl, '_blank'); };
                        container.appendChild(googleCircle);
                    }

                    if (config.showMdlCircle) {
                         const mdlUrl = `https://mydramalist.com/search?q=${encodeURIComponent(cleanDramaName)}&adv=titles&ty=68&co=3&so=relevance`;
                         const mdlCircle = document.createElement('span');
                         mdlCircle.className = 'kdrama-circle mdl-circle';
                         mdlCircle.title = `Search '${cleanDramaName}' on MyDramaList`;
                         mdlCircle.onclick = (e) => { e.stopPropagation(); window.open(mdlUrl, '_blank'); };
                         container.appendChild(mdlCircle);
                    }

                    node.parentNode.insertBefore(container, node);
                }
            });
        }

        // --- Pass 2: Convert Links ---
        if (config.convertBuzzheavierLinks) {
            const linkWalker = document.createTreeWalker(content, NodeFilter.SHOW_TEXT);
            const linkNodes = [];
            let n;
            while (n = linkWalker.nextNode()) {
                 buzzRegex.lastIndex = 0;
                 if (!n.parentNode.closest('a') && buzzRegex.test(n.textContent)) {
                    linkNodes.push(n);
                 }
            }

            linkNodes.forEach(node => {
                if (!document.body.contains(node)) return;

                const fragment = document.createDocumentFragment();
                const text = node.textContent;
                let lastIndex = 0;
                buzzRegex.lastIndex = 0;

                text.replace(buzzRegex, (match, id, offset) => {
                    fragment.appendChild(document.createTextNode(text.slice(lastIndex, offset)));
                    const link = document.createElement('a');
                    link.href = `https://buzzheavier.com/${id}`;
                    link.textContent = link.href;
                    link.target = '_blank';
                    fragment.appendChild(link);
                    lastIndex = offset + match.length;
                });
                fragment.appendChild(document.createTextNode(text.slice(lastIndex)));

                if (node.parentNode) {
                    node.parentNode.replaceChild(fragment, node);
                }
            });
        }
        console.log('K-Drama Link Enhancer: Processing complete. ✨');
    }

    // --- Settings UI ---
    function createSettingsUI() {
        const settingsButton = document.createElement('div');
        settingsButton.id = 'kdrama-settings-button';
        settingsButton.innerHTML = `<svg fill="currentColor" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49 1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z"/></svg>`;
        document.body.appendChild(settingsButton);

        const modal = document.createElement('div');
        modal.id = 'kdrama-settings-modal';
        modal.innerHTML = `
            <div class="kdrama-modal-content">
                <span id="kdrama-settings-close">&times;</span>
                <h2>K-Drama Link Enhancer Settings</h2>
                <div id="kdrama-settings-form">
                    <label>
                        <input type="checkbox" id="setting-google" ${config.showGoogleCircle ? 'checked' : ''}>
                        Show Google Search Icon
                    </label>
                    <label>
                        <input type="checkbox" id="setting-mdl" ${config.showMdlCircle ? 'checked' : ''}>
                        Show MyDramaList Search Icon
                    </label>
                    <label>
                        <input type="checkbox" id="setting-buzz" ${config.convertBuzzheavierLinks ? 'checked' : ''}>
                        Convert buzzheavier.com Links
                    </label>
                </div>
                <button id="kdrama-save-button" style="display:none; margin-top: 15px;">Save & Refresh</button>
            </div>
        `;
        document.body.appendChild(modal);

        const saveButton = document.getElementById('kdrama-save-button');

        settingsButton.addEventListener('click', () => { modal.style.display = 'flex'; });
        document.getElementById('kdrama-settings-close').addEventListener('click', () => { modal.style.display = 'none'; saveButton.style.display = 'none'; });
        modal.addEventListener('click', (e) => { if (e.target === modal) { modal.style.display = 'none'; saveButton.style.display = 'none'; }});

        document.getElementById('kdrama-settings-form').addEventListener('change', () => {
            saveButton.style.display = 'block';
        });

        saveButton.addEventListener('click', () => {
            GM_setValue('showGoogleCircle', document.getElementById('setting-google').checked);
            GM_setValue('showMdlCircle', document.getElementById('setting-mdl').checked);
            GM_setValue('convertBuzzheavierLinks', document.getElementById('setting-buzz').checked);
            location.reload();
        });
    }

    // --- Lightweight Initialization ---
    function initialize() {
        createSettingsUI();
        try { enhancePageContent(); } catch (e) { console.error(e); }
        setTimeout(() => { try { enhancePageContent(); } catch (e) { console.error(e); } }, 1500);
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initialize);
    } else {
        initialize();
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址