Key-Based Config

A script for interfacing with my Key-Based Config UI.

目前为 2021-08-06 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/419978/957932/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, 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({
  50. title: title,
  51. metaTree: metaTree,
  52. valueForest: valueForest === undefined ? [] : valueForest
  53. }, '*');
  54.  
  55. break;
  56.  
  57. case 'close':
  58. // Close iFrame
  59. isOpen = false;
  60. iframe.remove();
  61.  
  62. window.setTimeout(() => {
  63. // Save changes
  64. GM.setValue(storageKey, message.data.valueForest);
  65.  
  66. // Resolve promise
  67. resolve(message.data.valueForest);
  68. }, 1);
  69.  
  70. break;
  71.  
  72. case 'error':
  73. // Close iFrame
  74. isOpen = false;
  75. iframe.remove();
  76.  
  77. // Resolve promise
  78. reject(message.data.reason);
  79.  
  80. break;
  81.  
  82. default:
  83. // No need to error the promise here; I'm probably just observing a message from another script
  84. console.warn(`Unrecognised message 'event' value observed by key-based config script: '${message.data.type}'`);
  85. }
  86. });
  87. }
  88. });
  89. }