Greasyfork - Add notes to the script

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

От 27.02.2023. Виж последната версия.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==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();
})();