Key-Based Config

Allows end users to configure scripts (deprecated).

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/419978/1308990/Key-Based%20Config.js

  1. // ==UserScript==
  2. // @name Key-Based Config
  3. // @author Callum Latham <callumtylerlatham@gmail.com> (https://github.com/ctl2/key-based-config)
  4. // @exclude *
  5. // @description A script for interfacing with my Key-Based Config UI.
  6. // @grant GM.setValue
  7. // @grant GM.getValue
  8. // ==/UserScript==
  9.  
  10. const FRAME_URL = 'https://callumlatham.com/key-based-config/';
  11. const STYLE = {
  12. 'position': 'fixed',
  13. 'height': '100vh',
  14. 'width': '100vw'
  15. };
  16.  
  17. let isOpen = false;
  18.  
  19. function kbcConfigure(storageKey, title, metaTree, isFixed = false, customStyle = {}) {
  20. return new Promise((resolve, reject) => {
  21. if (isOpen) {
  22. reject(new Error('A Key-Based Config iFrame is already open.'));
  23. } else if (typeof GM.getValue !== 'function' || typeof GM.setValue !== 'function') {
  24. reject(new Error('The key-based config script requires GM.getValue and GM.setValue permissions.'));
  25. } else {
  26. const iframe = document.createElement('iframe');
  27. const style = {
  28. ...STYLE,
  29. ...customStyle
  30. }
  31.  
  32. iframe.src = FRAME_URL;
  33.  
  34. for (const [property, value] of Object.entries(style)) {
  35. iframe.style[property] = value;
  36. }
  37.  
  38. window.document.body.appendChild(iframe);
  39.  
  40. isOpen = true;
  41.  
  42. // Listen for iFrame communication
  43. window.addEventListener('message', async (message) => {
  44. switch (message.data.event) {
  45. case 'open':
  46. // Pass initialisation data
  47. const valueForest = await GM.getValue(storageKey, []);
  48.  
  49. iframe.contentWindow.postMessage({title, metaTree, valueForest, isFixed}, '*');
  50.  
  51. break;
  52.  
  53. case 'close':
  54. // Close iFrame
  55. isOpen = false;
  56. iframe.remove();
  57.  
  58. window.setTimeout(() => {
  59. // Save changes
  60. GM.setValue(storageKey, message.data.valueForest);
  61.  
  62. // Resolve promise
  63. resolve(message.data.valueForest);
  64. }, 1);
  65.  
  66. break;
  67.  
  68. case 'error':
  69. // Close iFrame
  70. isOpen = false;
  71. iframe.remove();
  72.  
  73. // Resolve promise
  74. reject(message.data.reason);
  75.  
  76. break;
  77.  
  78. default:
  79. // No need to error the promise here; I'm probably just observing a message from another script
  80. }
  81. });
  82. }
  83. });
  84. }