Greasyfork - Add notes to the script

Add a note(alias/tag) for scripts to help identify and search

As of 2020-09-12. See the latest version.

  1. // ==UserScript==
  2. // @name Greasyfork - Add notes to the script
  3. // @name:en Greasyfork - Add notes(aliases/tags) to the script
  4. // @name:zh-CN Greasyfork - 为脚本添加备注(别名/标签)
  5. // @name:zh-TW Greasyfork - 為腳本新增備註(別名/標籤)
  6. // @name:ja Greasyfork - スクリプトにメモを追加する(エイリアス/タグ)
  7. // @name:ko Greasyfork - 스크립트에 메모 추가 (별칭/태그)
  8. // @name:fr Greasyfork - Ajouter des notes (alias/tag) au script
  9. // @namespace https://greatest.deepsurf.us/zh-CN/users/193133-pana
  10. // @homepage https://www.sailboatweb.com
  11. // @icon data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDI0IDI0IiBhcmlhLWxhYmVsbGVkYnk9Im5ld0ljb25UaXRsZSIgc3Ryb2tlPSJyZ2JhKDI5LDE2MSwyNDIsMS4wMCkiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIgZmlsbD0ibm9uZSIgY29sb3I9InJnYmEoMjksMTYxLDI0MiwxLjAwKSI+IDx0aXRsZSBpZD0ibmV3SWNvblRpdGxlIj5OZXc8L3RpdGxlPiA8cGF0aCBkPSJNMTkgMTRWMjJIMi45OTk5N1Y0SDEzIi8+IDxwYXRoIGQ9Ik0xNy40NjA4IDQuMDM5MjFDMTguMjQxOCAzLjI1ODE3IDE5LjUwODIgMy4yNTgxNiAyMC4yODkyIDQuMDM5MjFMMjAuOTYwOCA0LjcxMDc5QzIxLjc0MTggNS40OTE4NCAyMS43NDE4IDYuNzU4MTcgMjAuOTYwOCA3LjUzOTIxTDExLjU4NTggMTYuOTE0MkMxMS4yMTA3IDE3LjI4OTMgMTAuNzAyIDE3LjUgMTAuMTcxNiAxNy41TDcuNSAxNy41TDcuNSAxNC44Mjg0QzcuNSAxNC4yOTggNy43MTA3MSAxMy43ODkzIDguMDg1NzkgMTMuNDE0MkwxNy40NjA4IDQuMDM5MjFaIi8+IDxwYXRoIGQ9Ik0xNi4yNSA1LjI1TDE5Ljc1IDguNzUiLz4gPC9zdmc+
  12. // @version 2.0.8
  13. // @description Add a note(alias/tag) for scripts to help identify and search
  14. // @description:en Add a note(alias/tag) for scripts to help identify and search
  15. // @description:zh-CN 为脚本添加备注(别名/标签)功能,以帮助识别和搜索
  16. // @description:zh-TW 為腳本新增備註(別名/標籤)功能,以幫助識別和搜尋
  17. // @description:ja 識別と検索に役立つコメント(エイリアス/タグ)関数をスクリプトに追加
  18. // @description:ko 식별 및 검색을 돕기 위해 스크립트에 주석 (별칭/태그) 기능 추가
  19. // @description:fr Ajouter une fonction de commentaire (alias/tag) au script pour aider à identifier et rechercher
  20. // @author pana
  21. // @license GNU General Public License v3.0 or later
  22. // @compatible chrome
  23. // @compatible firefox
  24. // @include http*://*greatest.deepsurf.us/*
  25. // @include http*://*sleazyfork.org/*
  26. // @require https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js
  27. // @require https://greatest.deepsurf.us/scripts/408454-note-obj/code/Note_Obj.js?version=847085
  28. // @grant GM_info
  29. // @grant GM.info
  30. // @grant GM_getValue
  31. // @grant GM.getValue
  32. // @grant GM_setValue
  33. // @grant GM.setValue
  34. // @grant GM_deleteValue
  35. // @grant GM.deleteValue
  36. // @grant GM_listValues
  37. // @grant GM.listValues
  38. // @grant GM_openInTab
  39. // @grant GM.openInTab
  40. // @grant GM_registerMenuCommand
  41. // @grant GM_unregisterMenuCommand
  42. // @grant GM_addValueChangeListener
  43. // ==/UserScript==
  44.  
  45. (async function() {
  46. 'use strict';
  47. const GF_ICON = {
  48. 'NOTE_BLACK': 'url(data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDI0IDI0IiBhcmlhLWxhYmVsbGVkYnk9Im5ld0ljb25UaXRsZSIgc3Ryb2tlPSJyZ2IoMzgsIDM4LCAzOCkiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIgZmlsbD0ibm9uZSIgY29sb3I9InJnYigzOCwgMzgsIDM4KSI+IDx0aXRsZSBpZD0ibmV3SWNvblRpdGxlIj5OZXc8L3RpdGxlPiA8cGF0aCBkPSJNMTkgMTRWMjJIMi45OTk5N1Y0SDEzIi8+IDxwYXRoIGQ9Ik0xNy40NjA4IDQuMDM5MjFDMTguMjQxOCAzLjI1ODE3IDE5LjUwODIgMy4yNTgxNiAyMC4yODkyIDQuMDM5MjFMMjAuOTYwOCA0LjcxMDc5QzIxLjc0MTggNS40OTE4NCAyMS43NDE4IDYuNzU4MTcgMjAuOTYwOCA3LjUzOTIxTDExLjU4NTggMTYuOTE0MkMxMS4yMTA3IDE3LjI4OTMgMTAuNzAyIDE3LjUgMTAuMTcxNiAxNy41TDcuNSAxNy41TDcuNSAxNC44Mjg0QzcuNSAxNC4yOTggNy43MTA3MSAxMy43ODkzIDguMDg1NzkgMTMuNDE0MkwxNy40NjA4IDQuMDM5MjFaIi8+IDxwYXRoIGQ9Ik0xNi4yNSA1LjI1TDE5Ljc1IDguNzUiLz4gPC9zdmc+)'
  49. };
  50. const GF_STYLE = `
  51. .note-obj-gf-note-btn {
  52. background-image: ${GF_ICON.NOTE_BLACK};
  53. background-repeat: no-repeat;
  54. background-position: center;
  55. cursor: pointer;
  56. vertical-align: top;
  57. }
  58. .note-obj-gf-info-note-btn {
  59. background-size: 32px auto;
  60. width: 32px;
  61. height: 32px;
  62. margin-left: 20px;
  63. display: inline-block;
  64. }
  65. .note-obj-gf-library-note-btn {
  66. background-size: 24px auto;
  67. width: 24px;
  68. height: 24px;
  69. margin-left: 20px;
  70. display: inline-block;
  71. }
  72. .note-obj-gf-list-note-btn {
  73. background-size: 24px auto;
  74. width: 24px;
  75. height: 24px;
  76. margin-left: 10px;
  77. display: none;
  78. }
  79. .note-obj-gf-ts-note-btn {
  80. background-size: 16px auto;
  81. width: 16px;
  82. height: 16px;
  83. margin-left: 10px;
  84. display: none;
  85. vertical-align: sub;
  86. }
  87. ol.script-list li:hover .note-obj-gf-list-note-btn,
  88. #script-table tbody tr:hover .note-obj-gf-ts-note-btn {
  89. display: inline-block;
  90. }
  91. .note-obj-gf-note-tag,
  92. .note-obj-gf-ts-note-tag {
  93. background-color: #3c81df;
  94. color: #fff;
  95. display: inline-block;
  96. align-items: center;
  97. white-space: nowrap;
  98. border-radius: 50px;
  99. padding: 0px 10px;
  100. }
  101. .note-obj-gf-list-note-tag {
  102. text-decoration: none;
  103. }
  104. `;
  105. function change_Event(note_obj, id = null) {
  106. let pathname = location.pathname;
  107. if (/^\/[\w-]+\/scripts\/\d+-/i.test(pathname)) {
  108. let script_id = /^\/[\w-]+\/scripts\/(\d+)-/i.exec(pathname)[1];
  109. let ele = document.querySelector('#script-info h2');
  110. ele && (! id || id == script_id) && note_obj.handler(script_id, ele, null, {
  111. 'add': 'span',
  112. 'class': 'note-obj-gf-note-tag'
  113. });
  114. } else if (/^\/[\w-]+\/scripts/i.test(pathname) || /^\/[\w-]+\/users\/\d+/i.test(pathname)) {
  115. let browse_list = document.querySelectorAll('ol.script-list li');
  116. for (let ele of browse_list) {
  117. let script_id = ele.getAttribute('data-script-id');
  118. if (script_id) {
  119. let header = ele.querySelector('article > h2 > a');
  120. header && (! id || id == script_id) && note_obj.handler(script_id, header, null, {
  121. 'add': 'span',
  122. 'class': ['note-obj-gf-note-tag', 'note-obj-gf-list-note-tag']
  123. });
  124. }
  125. }
  126. document.querySelectorAll('#script-table tbody tr').forEach(item => {
  127. let script_title = item.querySelector('.thetitle a');
  128. if (script_title) {
  129. let script_id = script_title.href.match(/\d+$/) && script_title.href.match(/\d+$/)[0];
  130. (! id || id == script_id) && note_obj.handler(script_id, script_title, null, {
  131. 'add': 'span',
  132. 'class': 'note-obj-gf-ts-note-tag'
  133. });
  134. }
  135. });
  136. }
  137. }
  138. function init_TS(note_obj) {
  139. document.querySelectorAll('#script-table tbody tr').forEach(item => {
  140. let script_title = item.querySelector('.thetitle a');
  141. if (script_title) {
  142. let script_id = script_title.href.match(/\d+$/) && script_title.href.match(/\d+$/)[0];
  143. let thetitle = item.querySelector('.thetitle');
  144. script_id && thetitle.appendChild(note_obj.createNoteBtn(script_id, script_title.textContent, ['note-obj-gf-note-btn', 'note-obj-gf-ts-note-btn']));
  145. note_obj.judgeUsers(script_id) && note_obj.handler(script_id, script_title, null, {
  146. 'add': 'span',
  147. 'class': 'note-obj-gf-ts-note-tag'
  148. }, script_title.textContent);
  149. }
  150. });
  151. }
  152. async function init() {
  153. let old_config = await Note_Obj.GM.getValue('greasyfork_config', null);
  154. if (old_config && old_config.scripts_array) {
  155. for (let item of old_config.scripts_array) {
  156. Note_Obj.GM.setValue(item.id, {
  157. 'tag': item.tag
  158. });
  159. }
  160. await Note_Obj.GM.deleteValue('greasyfork_config');
  161. }
  162. let note_obj = new Note_Obj('myGreasyForkNote');
  163. await note_obj.init({
  164. 'style': GF_STYLE,
  165. 'changeEvent': change_Event,
  166. 'script': {
  167. 'author': {
  168. 'name': 'pana',
  169. 'homepage': 'https://www.sailboatweb.com/'
  170. },
  171. 'address': 'https://greatest.deepsurf.us/scripts/404275',
  172. 'updated': '2020-9-12'
  173. },
  174. 'itemClick': key => 'https://greatest.deepsurf.us/scripts/' + key,
  175. 'type': 'script'
  176. });
  177. let pathname = location.pathname;
  178. if (/^\/[\w-]+\/scripts\/\d+-/i.test(pathname)) {
  179. let script_id = /^\/[\w-]+\/scripts\/(\d+)-/i.exec(pathname)[1];
  180. let install_help_link = document.querySelector('#install-area .install-help-link:last-child');
  181. let suggestion = document.querySelector('#script-feedback-suggestion');
  182. let script_name = (document.querySelector('header h2') && document.querySelector('header h2').textContent) || '';
  183. if (install_help_link) {
  184. install_help_link.after(note_obj.createNoteBtn(script_id, script_name, ['note-obj-gf-note-btn', 'note-obj-gf-info-note-btn']));
  185. } else if (suggestion) {
  186. suggestion.appendChild(note_obj.createNoteBtn(script_id, script_name, ['note-obj-gf-note-btn', 'note-obj-gf-library-note-btn']));
  187. }
  188. let ele = document.querySelector('#script-info h2');
  189. ele && note_obj.judgeUsers(script_id) && note_obj.handler(script_id, ele, null, {
  190. 'add': 'span',
  191. 'class': 'note-obj-gf-note-tag'
  192. }, script_name);
  193. } else if (/^\/[\w-]+\/scripts/i.test(pathname) || /^\/[\w-]+\/users\/\d+/i.test(pathname)) {
  194. let browse_list = document.querySelectorAll('ol.script-list li');
  195. for (let ele of browse_list) {
  196. let script_id = ele.getAttribute('data-script-id');
  197. if (script_id) {
  198. let description = ele.querySelector('.description');
  199. let script_name = (ele.querySelector('article > h2 > a') && ele.querySelector('article > h2 > a').textContent) || '';
  200. description && description.before(note_obj.createNoteBtn(script_id, script_name, ['note-obj-gf-note-btn', 'note-obj-gf-list-note-btn']));
  201. let header = ele.querySelector('article > h2 > a');
  202. header && note_obj.judgeUsers(script_id) && note_obj.handler(script_id, header, null, {
  203. 'add': 'span',
  204. 'class': ['note-obj-gf-note-tag', 'note-obj-gf-list-note-tag']
  205. }, script_name);
  206. }
  207. }
  208. init_TS(note_obj);
  209. let ts_tbody = document.querySelector('#script-table tbody');
  210. if (ts_tbody) {
  211. let observer = new MutationObserver(() => {
  212. init_TS(note_obj);
  213. });
  214. observer.observe(ts_tbody, {
  215. 'childList': true
  216. });
  217. }
  218. }
  219. }
  220. init();
  221. })();