gm_config_toolbar

greasyfork configuration toolbar on the script addins

目前为 2020-04-20 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/389774/794982/gm_config_toolbar.js

  1. "use strict";
  2.  
  3. // ==UserScript==
  4. // @name gm_config_toolbar
  5. // @version 2020.4.20
  6. // @namespace https://github.com/niubilityfrontend
  7. // @description greasyfork configuration toolbar on the script addins
  8. // @author kufii
  9. // @license OSL-3.0
  10. // @match *
  11. // @include *
  12. // @supportURL https://github.com/kufii/My-UserScripts
  13. // @grant GM_xmlhttpRequest
  14. // @grant GM_getValue
  15. // @grant GM_setValue
  16. // @grant GM_listValues
  17. // @grant GM_deleteValue
  18. // @grant GM_registerMenuCommand
  19. // ==/UserScript==
  20. (function () {
  21. 'use strict';
  22.  
  23. window.GM_config = function (settings) {
  24. let storage = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'cfg';
  25. let ret = null;
  26. const prefix = 'gm-config';
  27.  
  28. const addStyle = function addStyle() {
  29. const css = "\n\t\t\t\t.".concat(prefix, " {\n\t\t\t\t\tdisplay: grid;\n\t\t\t\t\talign-items: center;\n\t\t\t\t\tgrid-row-gap: 5px;\n\t\t\t\t\tgrid-column-gap: 10px;\n\t\t\t\t\tbackground-color: white;\n\t\t\t\t\tborder: 1px solid black;\n\t\t\t\t\tpadding: 5px;\n\t\t\t\t\tposition: fixed;\n\t\t\t\t\ttop: 0;\n\t\t\t\t\tright: 0;\n\t\t\t\t\tz-index: 2147483647;\n\t\t\t\t}\n\n\t\t\t\t.").concat(prefix, " label {\n\t\t\t\t\tgrid-column: 1 / 2;\n\t\t\t\t\tcolor: black;\n\t\t\t\t\ttext-align: right;\n\t\t\t\t\tfont-size: small;\n\t\t\t\t\tfont-weight: bold;\n\t\t\t\t}\n\n\t\t\t\t.").concat(prefix, " input,\n\t\t\t\t.").concat(prefix, " textarea,\n\t\t\t\t.").concat(prefix, " select {\n\t\t\t\t\tgrid-column: 2 / 4;\n\t\t\t\t}\n\n\t\t\t\t.").concat(prefix, " .").concat(prefix, "-save {\n\t\t\t\t\tgrid-column: 2 / 3;\n\t\t\t\t}\n\n\t\t\t\t.").concat(prefix, " .").concat(prefix, "-cancel {\n\t\t\t\t\tgrid-column: 3 / 4;\n\t\t\t\t}\n\t\t\t");
  30.  
  31. if (typeof GM_addStyle === 'undefined') {
  32. const style = document.createElement('style');
  33. style.textContent = css;
  34. document.head.appendChild(style);
  35. } else {
  36. GM_addStyle(css);
  37. }
  38. };
  39.  
  40. const load = function load() {
  41. const defaults = {};
  42. settings.forEach(function (_ref) {
  43. let {
  44. key,
  45. default: def
  46. } = _ref;
  47. return defaults[key] = def;
  48. });
  49. let cfg = typeof GM_getValue !== 'undefined' ? GM_getValue(storage) : localStorage.getItem(storage);
  50. if (!cfg) return defaults;
  51. cfg = JSON.parse(cfg);
  52. Object.entries(defaults).forEach(function (_ref2) {
  53. let [key, value] = _ref2;
  54.  
  55. if (typeof cfg[key] === 'undefined') {
  56. cfg[key] = value;
  57. }
  58. });
  59. return cfg;
  60. };
  61.  
  62. const save = function save(cfg) {
  63. const data = JSON.stringify(cfg);
  64. typeof GM_setValue !== 'undefined' ? GM_setValue(storage, data) : localStorage.setItem(storage, data);
  65. };
  66.  
  67. const setup = function setup() {
  68. const createContainer = function createContainer() {
  69. const form = document.createElement('form');
  70. form.classList.add(prefix);
  71. return form;
  72. };
  73.  
  74. const createTextbox = function createTextbox(name, value, placeholder, maxLength, multiline, resize) {
  75. const input = document.createElement(multiline ? 'textarea' : 'input');
  76.  
  77. if (multiline) {
  78. input.style.resize = resize ? 'vertical' : 'none';
  79. } else {
  80. input.type = 'text';
  81. }
  82.  
  83. input.name = name;
  84. if (typeof value !== 'undefined') input.value = value;
  85. if (placeholder) input.placeholder = placeholder;
  86. if (maxLength) input.maxLength = maxLength;
  87. return input;
  88. };
  89.  
  90. const createNumber = function createNumber(name, value, placeholder, min, max, step) {
  91. const input = createTextbox(name, value, placeholder);
  92. input.type = 'number';
  93. if (typeof min !== 'undefined') input.min = min;
  94. if (typeof max !== 'undefined') input.max = max;
  95. if (typeof step !== 'undefined') input.step = step;
  96. return input;
  97. };
  98.  
  99. const createSelect = function createSelect(name, options, value, showBlank) {
  100. const select = document.createElement('select');
  101. select.name = name;
  102.  
  103. const createOption = function createOption(val) {
  104. const {
  105. value = val,
  106. text = val
  107. } = val;
  108. const option = document.createElement('option');
  109. option.value = value;
  110. option.textContent = text;
  111. return option;
  112. };
  113.  
  114. if (showBlank) {
  115. select.appendChild(createOption(''));
  116. }
  117.  
  118. options.forEach(function (opt) {
  119. if (typeof opt.optgroup !== 'undefined') {
  120. const optgroup = document.createElement('optgroup');
  121. optgroup.label = opt.optgroup;
  122. select.appendChild(optgroup);
  123. opt.values.forEach(function (value) {
  124. return optgroup.appendChild(createOption(value));
  125. });
  126. } else {
  127. select.appendChild(createOption(opt));
  128. }
  129. });
  130. select.value = value;
  131. return select;
  132. };
  133.  
  134. const createCheckbox = function createCheckbox(name, checked) {
  135. const checkbox = document.createElement('input');
  136. checkbox.id = "".concat(prefix, "-").concat(name);
  137. checkbox.type = 'checkbox';
  138. checkbox.name = name;
  139. checkbox.checked = checked;
  140. return checkbox;
  141. };
  142.  
  143. const createButton = function createButton(text, onclick, classname) {
  144. const button = document.createElement('button');
  145. button.classList.add("".concat(prefix, "-").concat(classname));
  146. button.textContent = text;
  147. button.onclick = onclick;
  148. return button;
  149. };
  150.  
  151. const createLabel = function createLabel(label, htmlFor) {
  152. const lbl = document.createElement('label');
  153. if (htmlFor) lbl.htmlFor = htmlFor;
  154. lbl.textContent = label;
  155. return lbl;
  156. };
  157.  
  158. const init = function init(cfg) {
  159. const controls = {};
  160. const div = createContainer();
  161. settings.filter(function (_ref3) {
  162. let {
  163. type
  164. } = _ref3;
  165. return type !== 'hidden';
  166. }).forEach(function (setting) {
  167. const value = cfg[setting.key];
  168. let control;
  169.  
  170. if (setting.type === 'text') {
  171. control = createTextbox(setting.key, value, setting.placeholder, setting.maxLength, setting.multiline, setting.resizable);
  172. } else if (setting.type === 'number') {
  173. control = createNumber(setting.key, value, setting.placeholder, setting.min, setting.max, setting.step);
  174. } else if (setting.type === 'dropdown') {
  175. control = createSelect(setting.key, setting.values, value, setting.showBlank);
  176. } else if (setting.type === 'bool') {
  177. control = createCheckbox(setting.key, value);
  178. }
  179.  
  180. div.appendChild(createLabel(setting.label, control.id));
  181. div.appendChild(control);
  182. controls[setting.key] = control;
  183. control.addEventListener(setting.type === 'dropdown' ? 'change' : 'input', function () {
  184. if (ret.onchange) {
  185. const control = controls[setting.key];
  186. const value = setting.type === 'bool' ? control.checked : control.value;
  187. ret.onchange(setting.key, value);
  188. }
  189. });
  190. });
  191. div.appendChild(createButton('Save', function () {
  192. settings.filter(function (_ref4) {
  193. let {
  194. type
  195. } = _ref4;
  196. return type !== 'hidden';
  197. }).forEach(function (_ref5) {
  198. let {
  199. key,
  200. type
  201. } = _ref5;
  202. const control = controls[key];
  203. cfg[key] = type === 'bool' ? control.checked : control.value;
  204. });
  205. save(cfg);
  206.  
  207. if (ret.onsave) {
  208. ret.onsave(cfg);
  209. }
  210.  
  211. div.remove();
  212. }, 'save'));
  213. div.appendChild(createButton('Cancel', function () {
  214. if (ret.oncancel) {
  215. ret.oncancel(cfg);
  216. }
  217.  
  218. div.remove();
  219. }, 'cancel'));
  220. document.body.appendChild(div);
  221. };
  222.  
  223. init(load());
  224. };
  225.  
  226. addStyle();
  227. ret = {
  228. load,
  229. save,
  230. setup
  231. };
  232. return ret;
  233. };
  234. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址