DLinker

Link the RJ/VJ code and create a preview.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name         DLinker
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Link the RJ/VJ code and create a preview.
// @author       Traffica
// @match        https://kone.gg/s/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=kone.gg
// @grant        none
// @license MIT
// ==/UserScript==

const regex = /(RJ|VJ)\d{6,8}/gi;
window.addEventListener('load', ()=>setTimeout(main, 500));

function main() {
    const body = document.querySelector('body');
    const observer = new MutationObserver(()=>setTimeout(preload, 500));

    observer.observe(body, {childList: true, subtree: true, characterData:true});
    console.log("0");
}

function preload(_, __) {
    const contents = document.querySelector("#post_content")?.shadowRoot?.querySelector("div");
    if (contents) {
        Array.from(contents.childNodes).forEach(node => process_node(node));
    }
}

function process_node(node) {
    if (node.nodeType === Node.TEXT_NODE) {
        let originalText = node.nodeValue; // 텍스트 노드의 실제 문자열 값

        // 텍스트에 정규식 패턴이 포함되어 있는지 테스트
        if (regex.test(originalText)) {
            // 정규식의 lastIndex를 초기화합니다. (재귀 호출 시 중요)
            // .test()를 먼저 호출했기 때문에 lastIndex가 변경되었을 수 있습니다.
            regex.lastIndex = 0;

            // **핵심 변경 부분:**
            // `replace` 메서드의 콜백을 사용하여 매칭된 부분만 HTML로 교체합니다.
            // 매칭되지 않은 텍스트는 `replace`가 자동으로 처리합니다.
            const newHTMLString = originalText.replace(regex, (match) => {
                const codeUrl = "https://www.dlsite.com/maniax/work/=/product_id/" + match + ".html"; // DLsite 링크 URL 생성

                // <a> 태그로 감싼 HTML 문자열 반환
                return `<a target="_blank" rel="noopener noreferrer nofollow" class="text-blue-500 underline" href="${codeUrl}">${match}</a>`;
            });

            // 새로운 HTML 문자열을 파싱하여 DOM 노드들로 변환합니다.
            const tempDiv = document.createElement('div');
            tempDiv.innerHTML = newHTMLString;

            // 원본 텍스트 노드를 새로 생성된 노드들로 교체합니다.
            // tempDiv.childNodes는 NodeList이므로, Array.from으로 변환하여 순회해야 안전합니다.
            Array.from(tempDiv.childNodes).forEach(child => {
                node.parentNode.insertBefore(child.cloneNode(true), node);
            });
            node.parentNode.removeChild(node); // 원본 텍스트 노드 제거
        }
    }
    else if (node.nodeType === node.ELEMENT_NODE && node.tagName.toLowerCase() !== 'a' && node.tagName.toLowerCase() !== 'img' && node.tagName.toLowerCase() !== 'script' && node.tagName.toLowerCase() !== 'style') {
        Array.from(node.childNodes).forEach(child => { process_node(child); });
    }
}