Greasyfork - Add notes to the script

Add notes (aliases/tags) for scripts to help identify and search

Versión del día 27/2/2023. Echa un vistazo a la versión más reciente.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name                Greasyfork - Add notes to the script
// @name:zh-CN          Greasyfork - 为脚本添加备注(别名/标签)
// @name:zh-TW          Greasyfork - 為指令碼新增備註(別名/標籤)
// @namespace           https://greasyfork.org/zh-CN/users/193133-pana
// @homepage            https://greasyfork.org/zh-CN/users/193133-pana
// @icon                data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDI0IDI0IiBhcmlhLWxhYmVsbGVkYnk9Im5ld0ljb25UaXRsZSIgc3Ryb2tlPSJyZ2JhKDI5LDE2MSwyNDIsMS4wMCkiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIgZmlsbD0ibm9uZSIgY29sb3I9InJnYmEoMjksMTYxLDI0MiwxLjAwKSI+IDx0aXRsZSBpZD0ibmV3SWNvblRpdGxlIj5OZXc8L3RpdGxlPiA8cGF0aCBkPSJNMTkgMTRWMjJIMi45OTk5N1Y0SDEzIi8+IDxwYXRoIGQ9Ik0xNy40NjA4IDQuMDM5MjFDMTguMjQxOCAzLjI1ODE3IDE5LjUwODIgMy4yNTgxNiAyMC4yODkyIDQuMDM5MjFMMjAuOTYwOCA0LjcxMDc5QzIxLjc0MTggNS40OTE4NCAyMS43NDE4IDYuNzU4MTcgMjAuOTYwOCA3LjUzOTIxTDExLjU4NTggMTYuOTE0MkMxMS4yMTA3IDE3LjI4OTMgMTAuNzAyIDE3LjUgMTAuMTcxNiAxNy41TDcuNSAxNy41TDcuNSAxNC44Mjg0QzcuNSAxNC4yOTggNy43MTA3MSAxMy43ODkzIDguMDg1NzkgMTMuNDE0MkwxNy40NjA4IDQuMDM5MjFaIi8+IDxwYXRoIGQ9Ik0xNi4yNSA1LjI1TDE5Ljc1IDguNzUiLz4gPC9zdmc+
// @version             3.0.0
// @description         Add notes (aliases/tags) for scripts to help identify and search
// @description:zh-CN   为脚本添加备注(别名/标签)功能,以帮助识别和搜索
// @description:zh-TW   為指令碼新增備註(別名/標籤)功能,以幫助識別和搜尋
// @author              pana
// @license             GNU General Public License v3.0 or later
// @compatible          chrome
// @compatible          firefox
// @match               *://*.greasyfork.org/*
// @match               *://*.sleazyfork.org/*
// @require             https://gcore.jsdelivr.net/gh/LightAPIs/greasy-fork-library@05dffeb4eefb1a39df31d518cd45a4e6929929f3/Note_Obj.js
// @noframes
// @grant               GM_info
// @grant               GM_getValue
// @grant               GM_setValue
// @grant               GM_deleteValue
// @grant               GM_listValues
// @grant               GM_openInTab
// @grant               GM_addStyle
// @grant               GM_registerMenuCommand
// @grant               GM_unregisterMenuCommand
// @grant               GM_addValueChangeListener
// @grant               GM_removeValueChangeListener
// ==/UserScript==

(function () {
    'use strict';
    const UPDATED = '2023-02-27';
    const GF_ICON = {
        NOTE_BLACK: 'url(data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDI0IDI0IiBhcmlhLWxhYmVsbGVkYnk9Im5ld0ljb25UaXRsZSIgc3Ryb2tlPSJyZ2IoMzgsIDM4LCAzOCkiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIgZmlsbD0ibm9uZSIgY29sb3I9InJnYigzOCwgMzgsIDM4KSI+IDx0aXRsZSBpZD0ibmV3SWNvblRpdGxlIj5OZXc8L3RpdGxlPiA8cGF0aCBkPSJNMTkgMTRWMjJIMi45OTk5N1Y0SDEzIi8+IDxwYXRoIGQ9Ik0xNy40NjA4IDQuMDM5MjFDMTguMjQxOCAzLjI1ODE3IDE5LjUwODIgMy4yNTgxNiAyMC4yODkyIDQuMDM5MjFMMjAuOTYwOCA0LjcxMDc5QzIxLjc0MTggNS40OTE4NCAyMS43NDE4IDYuNzU4MTcgMjAuOTYwOCA3LjUzOTIxTDExLjU4NTggMTYuOTE0MkMxMS4yMTA3IDE3LjI4OTMgMTAuNzAyIDE3LjUgMTAuMTcxNiAxNy41TDcuNSAxNy41TDcuNSAxNC44Mjg0QzcuNSAxNC4yOTggNy43MTA3MSAxMy43ODkzIDguMDg1NzkgMTMuNDE0MkwxNy40NjA4IDQuMDM5MjFaIi8+IDxwYXRoIGQ9Ik0xNi4yNSA1LjI1TDE5Ljc1IDguNzUiLz4gPC9zdmc+)',
    };
    const GF_STYLE = `
        .note-obj-gf-note-btn {
            background-image: ${GF_ICON.NOTE_BLACK};
            background-repeat: no-repeat;
            background-position: center;
            cursor: pointer;
            vertical-align: top;
        }
        .note-obj-gf-info-note-btn {
            background-size: 32px auto;
            width: 32px;
            height: 32px;
            margin-left: 20px;
            display: inline-block;
        }
        .note-obj-gf-library-note-btn {
            background-size: 24px auto;
            width: 24px;
            height: 24px;
            margin-left: 20px;
            display: inline-block;
        }
        .note-obj-gf-list-note-btn {
            background-size: 24px auto;
            width: 24px;
            height: 24px;
            margin-left: 10px;
            display: none;
        }
        .note-obj-gf-ts-note-btn {
            background-size: 16px auto;
            width: 16px;
            height: 16px;
            margin-left: 10px;
            display: none;
            vertical-align: sub;
        }
        ol.script-list li:hover .note-obj-gf-list-note-btn,
        #script-table tbody tr:hover .note-obj-gf-ts-note-btn {
            display: inline-block;
        }
        .note-obj-gf-note-tag,
        .note-obj-gf-ts-note-tag {
            background-color: #3c81df;
            color: #fff;
            display: inline-block;
            align-items: center;
            white-space: nowrap;
            border-radius: 50px;
            padding: 1px 10px;
            line-height: 1em;
        }
        .note-obj-gf-list-note-tag {
            text-decoration: none;
        }
    `;
    const noteObj = new Note_Obj({
        id: 'myGreasyForkNote',
        script: {
            author: {
                name: 'pana',
                homepage: 'https://greasyfork.org/zh-CN/users/193133-pana',
            },
            url: 'https://greasyfork.org/scripts/404275',
            updated: UPDATED,
        },
        itemClick: (key) => `${location.origin}/scripts/${key}`,
        language: {
            userIdText: {
                en: 'Script ID',
                zhHans: '脚本 ID',
                zhHant: '指令碼 ID',
            },
            userNameText: {
                en: 'Script name',
                zhHans: '脚本名',
                zhHant: '指令碼名',
            },
        },
        changeEvent,
        style: GF_STYLE,
    });
    function changeEvent(id) {
        const scriptId = getScriptIdFromPathname(location.pathname);
        if (scriptId) {
            infoPageNotes(scriptId, undefined, id);
        }
        else {
            listPageNotes(id);
            initTS(id);
        }
    }
    function initTS(changeId) {
        Note_Obj.fn.docQueryAll('#script-table tbody tr').forEach(item => {
            const scriptTitle = Note_Obj.fn.queryAnchor(item, '.thetitle a');
            if (scriptTitle) {
                const res = scriptTitle.href.match(/\d+$/);
                if (res) {
                    const scriptId = res[0];
                    const scriptName = scriptTitle.textContent?.trim();
                    const thetitle = Note_Obj.fn.query(item, '.thetitle');
                    if (thetitle && !Note_Obj.fn.query(thetitle, '.' + Note_Obj.btnClassName, 'none')) {
                        thetitle.appendChild(noteObj.createNoteBtn(scriptId, scriptName, ['note-obj-gf-note-btn', 'note-obj-gf-ts-note-btn']));
                    }
                    if (!changeId || changeId === scriptId) {
                        noteObj.handler(scriptId, scriptTitle, undefined, {
                            add: 'span',
                            className: ['note-obj-gf-ts-note-tag'],
                        }, scriptName);
                    }
                }
            }
        });
    }
    function getScriptIdFromPathname(pathname) {
        const res = pathname.match(/^\/[\w-]+\/scripts\/(\d+)-/);
        if (res && res.length === 2) {
            return res[1];
        }
        return null;
    }
    function infoPageNotes(scriptId, scriptName, changeId) {
        const ele = Note_Obj.fn.docQuery('#script-info h2', 'info');
        if (ele) {
            if (!changeId || changeId === scriptId)
                noteObj.handler(scriptId, ele, undefined, {
                    add: 'sapn',
                    className: ['note-obj-gf-note-tag'],
                }, scriptName);
        }
    }
    function listPageNotes(changeId) {
        const list = Note_Obj.fn.docQueryAll('ol.script-list li', 'info');
        for (const ele of list) {
            const scriptId = ele.dataset.scriptId;
            if (scriptId) {
                const description = Note_Obj.fn.query(ele, '.description');
                const scriptName = Note_Obj.fn.getText(ele, 'article > h2 > a', 'warn');
                if (description) {
                    const desParent = description.parentElement;
                    if (desParent && !Note_Obj.fn.query(desParent, '.' + Note_Obj.btnClassName, 'none')) {
                        description.before(noteObj.createNoteBtn(scriptId, scriptName, ['note-obj-gf-note-btn', 'note-obj-gf-list-note-btn']));
                    }
                }
                const header = Note_Obj.fn.query(ele, 'article > h2 > a');
                if (header) {
                    if (!changeId || changeId === scriptId)
                        noteObj.handler(scriptId, header, undefined, {
                            add: 'span',
                            className: ['note-obj-gf-note-tag', 'note-obj-gf-list-note-tag'],
                        }, scriptName);
                }
            }
        }
    }
    function init() {
        const scriptId = getScriptIdFromPathname(location.pathname);
        if (scriptId) {
            const installHelpLink = Note_Obj.fn.docQuery('#install-area .install-help-link:last-child', 'info');
            const scriptName = Note_Obj.fn.docGetText('header h2');
            if (installHelpLink) {
                installHelpLink.after(noteObj.createNoteBtn(scriptId, scriptName, ['note-obj-gf-note-btn', 'note-obj-gf-info-note-btn']));
            }
            else {
                const suggestion = Note_Obj.fn.docQuery('#script-feedback-suggestion');
                suggestion?.appendChild(noteObj.createNoteBtn(scriptId, scriptName, ['note-obj-gf-note-btn', 'note-obj-gf-library-note-btn']));
            }
            infoPageNotes(scriptId, scriptName);
        }
        else {
            listPageNotes();
            const scriptList = Note_Obj.fn.docQuery('#browse-script-list', 'info');
            if (scriptList) {
                const listObserver = new MutationObserver(() => {
                    listPageNotes();
                });
                listObserver.observe(scriptList, {
                    childList: true,
                });
            }
            initTS();
            const tsTbody = Note_Obj.fn.docQuery('#script-table tbody', 'none');
            if (tsTbody) {
                const tsObserver = new MutationObserver(() => {
                    initTS();
                });
                tsObserver.observe(tsTbody, {
                    childList: true,
                });
            }
        }
    }
    init();
})();