ClipTags (RED/OPS)

Adds a button to copy tags as comma-separated from RED/OPS torrents, artists and requests pages.

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         ClipTags (RED/OPS)
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Adds a button to copy tags as comma-separated from RED/OPS torrents, artists and requests pages.
// @match        https://redacted.sh/torrents.php?id=*
// @match        https://orpheus.network/torrents.php?id=*
// @match        https://redacted.sh/artist.php?id=*
// @match        https://orpheus.network/artist.php?id=*
// @match        https://redacted.sh/requests.php?action=view&id=*
// @match        https://orpheus.network/requests.php?action=view&id=*
// @grant        GM_setClipboard
// @author       rodriguito
// ==/UserScript==

(function() {
    'use strict';

    function extractTags(container) {
        const tagLinks = container.querySelectorAll('a[href*="taglist="]');

        const tags = Array.from(tagLinks)
            .map(a => a.textContent.trim())
            .filter(Boolean);

        return [...new Set(tags)].join(',');
    }

    function findTagsContainer() {
        const elements = document.querySelectorAll('div, td, li');

        for (let el of elements) {
            const text = (el.innerText || el.textContent || "").trim();

            if (text.startsWith("Tags")) {
                return el;
            }
        }

        return null;
    }

    function findTagsLabel(container) {
        const walker = document.createTreeWalker(container, NodeFilter.SHOW_TEXT);

        let node;
        while (node = walker.nextNode()) {
            if (node.nodeValue.trim() === "Tags") {
                return node.parentElement;
            }
        }

        return null;
    }

    function insertButton(labelEl, container) {
        if (!labelEl || labelEl.querySelector('.copy-tags-btn')) return;

        labelEl.style.display = 'flex';
        labelEl.style.justifyContent = 'space-between';
        labelEl.style.alignItems = 'center';

        const btn = document.createElement('button');
        btn.textContent = "Copy Tags";
        btn.className = "copy-tags-btn";
        btn.style.padding = "2px 6px";
        btn.style.fontSize = "11px";
        btn.style.cursor = "pointer";

        btn.addEventListener('click', () => {
            const result = extractTags(container);

            if (!result) {
                alert("No tags found.");
                return;
            }

            GM_setClipboard(result);

            btn.textContent = "Copied!";
            setTimeout(() => btn.textContent = "Copy Tags", 1500);
        });

        labelEl.appendChild(btn);
    }

    function init() {
        const container = findTagsContainer();
        if (!container) return;

        const label = findTagsLabel(container);
        if (!label) return;

        insertButton(label, container);
    }

    window.addEventListener('load', () => {
        setTimeout(init, 500);
    });

})();