// ==UserScript==
// @name Greasyfork - Add notes to the script
// @name:zh-CN Greasyfork - 为脚本添加备注(别名/标签)
// @name:zh-TW Greasyfork - 為指令碼新增備註(別名/標籤)
// @namespace https://gf.qytechs.cn/zh-CN/users/193133-pana
// @homepage https://gf.qytechs.cn/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 *://*.gf.qytechs.cn/*
// @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://gf.qytechs.cn/zh-CN/users/193133-pana',
},
url: 'https://gf.qytechs.cn/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();
})();