MonkeyConfig Mod

EEnhanced Configuration Dialog Builder with column layout , custom styling , and Additional input types

当前为 2025-03-09 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/528923/1550628/MonkeyConfig%20Mod.js

  1. // ==UserScript==
  2. // @name MonkeyConfig Mod
  3. // @namespace http://odyniec.net/
  4. // @description EEnhanced Configuration Dialog Builder with column layout , custom styling , and Additional input types
  5. // @version 1.7
  6. // ==/UserScript==
  7.  
  8. /*
  9. * MonkeyConfig Modern Reloaded Enhanced
  10. * Based on version 0.1.4 by Michal Wojciechowski (odyniec.net)
  11. * v0.1.4 - January 2020 - David Hosier (https://github.com/david-hosier/MonkeyConfig)
  12. * Enhanced by Bloggerpemula - March 2025
  13. * Additions: Column layout, font size/color customization, new input types (textarea, range, radio, file, button, group)
  14. * Modified: Checkbox, number, and text inputs aligned inline with labels - March 2025
  15. * Modified: Added text-align option for labels, reduced width of number and text fields - March 2025
  16. * Modified: Added per-parameter font-size and font-color customization - March 2025
  17. * Fixed: Ensured per-parameter font-size and font-color apply correctly - March 2025
  18. * Added Shadow DOM for consistent styling across sites - March 2025
  19. */
  20.  
  21. function MonkeyConfig(data) {
  22. var cfg = this,
  23. params,
  24. values = {},
  25. storageKey,
  26. displayed,
  27. openLayer,
  28. shadowRoot,
  29. container,
  30. overlay;
  31.  
  32. function init() {
  33. params = data.parameters || data.params;
  34. data.buttons = data.buttons === undefined ? ['save', 'defaults', 'cancel'] : data.buttons;
  35. data.fontSize = data.fontSize || '11pt';
  36. data.fontColor = data.fontColor || '#000000';
  37. data.width = data.width || '600px'; // Default width
  38. data.height = data.height || 'auto'; // Default height
  39.  
  40. if (!data.title) {
  41. data.title = typeof GM_getMetadata === 'function' ? GM_getMetadata('name') + ' Configuration' : 'Configuration';
  42. }
  43.  
  44. var safeTitle = data.title.replace(/[^a-zA-Z0-9]/g, '_');
  45. storageKey = '_MonkeyConfig_' + safeTitle + '_cfg';
  46.  
  47. var storedValues = GM_getValue(storageKey) ? JSON.parse(GM_getValue(storageKey)) : {};
  48.  
  49. for (var paramName in params) {
  50. var param = params[paramName];
  51. if (param.value !== undefined) {
  52. set(paramName, param.value);
  53. } else if (storedValues[paramName] !== undefined) {
  54. set(paramName, storedValues[paramName]);
  55. } else if (param.default !== undefined) {
  56. set(paramName, param.default);
  57. } else {
  58. set(paramName, '');
  59. }
  60. }
  61.  
  62. if (data.menuCommand) {
  63. var caption = data.menuCommand !== true ? data.menuCommand : data.title;
  64. GM_registerMenuCommand(caption, function () { cfg.open(); });
  65. }
  66.  
  67. cfg.open = open;
  68. cfg.close = close;
  69. cfg.get = get;
  70. cfg.set = function (name, value) { set(name, value); update(); };
  71. }
  72.  
  73. function get(name) { return values[name]; }
  74. function set(name, value) { values[name] = value; }
  75. function setDefaults() {
  76. for (var paramName in params) {
  77. if (params[paramName].default !== undefined) {
  78. set(paramName, params[paramName].default);
  79. }
  80. }
  81. update();
  82. }
  83.  
  84. function render() {
  85. var html = '<div class="__MonkeyConfig_container">' +
  86. '<h1>' + data.title + '</h1>' +
  87. '<div class="__MonkeyConfig_content">' +
  88. '<div class="__MonkeyConfig_top">';
  89. for (var paramName in params) {
  90. if (params[paramName].column === 'top') {
  91. html += MonkeyConfig.formatters.tr(paramName, params[paramName]);
  92. }
  93. }
  94. html += '</div>' +
  95. '<div class="__MonkeyConfig_columns">' +
  96. '<div class="__MonkeyConfig_left_column">';
  97. for (var paramName in params) {
  98. if (params[paramName].column === 'left') {
  99. html += MonkeyConfig.formatters.tr(paramName, params[paramName]);
  100. }
  101. }
  102. html += '</div><div class="__MonkeyConfig_right_column">';
  103. for (var paramName in params) {
  104. if (params[paramName].column === 'right') {
  105. html += MonkeyConfig.formatters.tr(paramName, params[paramName]);
  106. }
  107. }
  108. html += '</div></div>' +
  109. '<table class="__MonkeyConfig_default">';
  110. for (var paramName in params) {
  111. if (!params[paramName].column) {
  112. html += MonkeyConfig.formatters.tr(paramName, params[paramName]);
  113. }
  114. }
  115. html += '</table>' +
  116. '<div class="__MonkeyConfig_bottom">';
  117. for (var paramName in params) {
  118. if (params[paramName].column === 'bottom') {
  119. html += MonkeyConfig.formatters.tr(paramName, params[paramName]);
  120. }
  121. }
  122. html += '</div></div><div class="__MonkeyConfig_buttons_container"><table><tr>';
  123.  
  124. for (var i = 0; i < data.buttons.length; i++) {
  125. html += '<td>';
  126. switch (data.buttons[i]) {
  127. case 'cancel':
  128. html += '<button type="button" id="__MonkeyConfig_button_cancel"><img src="data:image/png;base64,' + MonkeyConfig.res.icons.cancel + '" alt="Cancel"/> Cancel</button>';
  129. break;
  130. case 'defaults':
  131. html += '<button type="button" id="__MonkeyConfig_button_defaults"><img src="data:image/png;base64,' + MonkeyConfig.res.icons.arrow_undo + '" alt="Defaults"/> Set Defaults</button>';
  132. break;
  133. case 'save':
  134. html += '<button type="button" id="__MonkeyConfig_button_save"><img src="data:image/png;base64,' + MonkeyConfig.res.icons.tick + '" alt="Save"/> Save</button>';
  135. break;
  136. }
  137. html += '</td>';
  138. }
  139.  
  140. html += '</tr></table></div></div>';
  141. return html;
  142. }
  143.  
  144. function update() {
  145. if (!displayed) return;
  146.  
  147. for (var paramName in params) {
  148. var value = values[paramName];
  149. var elem = shadowRoot.querySelector('[name="' + paramName + '"]'); // Gunakan shadowRoot
  150. if (!elem) continue;
  151. switch (params[paramName].type) {
  152. case 'checkbox':
  153. elem.checked = !!value;
  154. break;
  155. case 'custom':
  156. if (params[paramName].set) {
  157. params[paramName].set(value, shadowRoot.querySelector('#__MonkeyConfig_parent_' + paramName));
  158. }
  159. break;
  160. case 'number':
  161. case 'text':
  162. case 'color':
  163. case 'textarea':
  164. case 'range':
  165. elem.value = value;
  166. break;
  167. case 'radio':
  168. var radio = shadowRoot.querySelector('[name="' + paramName + '"][value="' + value + '"]');
  169. if (radio) radio.checked = true;
  170. break;
  171. case 'file':
  172. elem.value = '';
  173. break;
  174. case 'select':
  175. if (elem.tagName.toLowerCase() === 'input' && elem.type === 'checkbox') {
  176. var checkboxes = shadowRoot.querySelectorAll('input[name="' + paramName + '"]');
  177. for (var i = 0; i < checkboxes.length; i++) {
  178. checkboxes[i].checked = value.indexOf(checkboxes[i].value) > -1;
  179. }
  180. } else if (elem.multiple) {
  181. var options = shadowRoot.querySelectorAll('select[name="' + paramName + '"] option');
  182. for (var i = 0; i < options.length; i++) {
  183. options[i].selected = value.indexOf(options[i].value) > -1;
  184. }
  185. } else {
  186. elem.value = value;
  187. }
  188. break;
  189. }
  190. elem.style.fontSize = params[paramName].fontSize || data.fontSize;
  191. elem.style.color = params[paramName].fontColor || data.fontColor;
  192. var label = shadowRoot.querySelector('label[for="__MonkeyConfig_field_' + paramName + '"]');
  193. if (label) {
  194. label.style.fontSize = params[paramName].fontSize || data.fontSize;
  195. label.style.color = params[paramName].fontColor || data.fontColor;
  196. label.style.textAlign = params[paramName].labelAlign || 'left';
  197. }
  198. }
  199. }
  200.  
  201. function saveClick() {
  202. for (var paramName in params) {
  203. var elem = shadowRoot.querySelector('[name="' + paramName + '"]');
  204. if (!elem) continue;
  205. switch (params[paramName].type) {
  206. case 'checkbox':
  207. values[paramName] = elem.checked;
  208. break;
  209. case 'custom':
  210. if (params[paramName].get) {
  211. values[paramName] = params[paramName].get(shadowRoot.querySelector('#__MonkeyConfig_parent_' + paramName));
  212. }
  213. break;
  214. case 'number':
  215. case 'text':
  216. case 'color':
  217. case 'textarea':
  218. case 'range':
  219. values[paramName] = elem.value;
  220. break;
  221. case 'radio':
  222. var checkedRadio = shadowRoot.querySelector('[name="' + paramName + '"]:checked');
  223. values[paramName] = checkedRadio ? checkedRadio.value : '';
  224. break;
  225. case 'file':
  226. values[paramName] = elem.dataset.value || values[paramName];
  227. break;
  228. case 'select':
  229. if (elem.tagName.toLowerCase() === 'input' && elem.type === 'checkbox') {
  230. values[paramName] = [];
  231. var inputs = shadowRoot.querySelectorAll('input[name="' + paramName + '"]');
  232. for (var i = 0; i < inputs.length; i++) {
  233. if (inputs[i].checked) values[paramName].push(inputs[i].value);
  234. }
  235. } else if (elem.multiple) {
  236. values[paramName] = [];
  237. var options = shadowRoot.querySelectorAll('select[name="' + paramName + '"] option');
  238. for (var i = 0; i < options.length; i++) {
  239. if (options[i].selected) values[paramName].push(options[i].value);
  240. }
  241. } else {
  242. values[paramName] = elem.value;
  243. }
  244. break;
  245. }
  246. }
  247.  
  248. GM_setValue(storageKey, JSON.stringify(values));
  249. close();
  250. if (data.onSave) data.onSave(values);
  251. location.reload();
  252. }
  253.  
  254. function cancelClick() { close(); }
  255.  
  256. function open() {
  257. function openDone() {
  258. var saveBtn = shadowRoot.querySelector('#__MonkeyConfig_button_save');
  259. var defaultsBtn = shadowRoot.querySelector('#__MonkeyConfig_button_defaults');
  260. var cancelBtn = shadowRoot.querySelector('#__MonkeyConfig_button_cancel');
  261.  
  262. if (saveBtn) saveBtn.addEventListener('click', saveClick, false);
  263. if (defaultsBtn) defaultsBtn.addEventListener('click', function () { setDefaults(); }, false);
  264. if (cancelBtn) cancelBtn.addEventListener('click', cancelClick, false);
  265.  
  266. displayed = true;
  267. update();
  268. }
  269.  
  270. // Buat layer dan overlay
  271. var body = document.querySelector('body');
  272. openLayer = document.createElement('div');
  273. openLayer.className = '__MonkeyConfig_layer';
  274. overlay = document.createElement('div');
  275. overlay.className = '__MonkeyConfig_overlay';
  276. overlay.style.cssText = 'position:fixed;left:0;top:0;width:100%;height:100%;z-index:9999;background-color:#000;opacity:0.6;';
  277.  
  278. // Buat Shadow DOM
  279. shadowRoot = openLayer.attachShadow({ mode: 'open' });
  280. shadowRoot.innerHTML = '<style>' + MonkeyConfig.res.stylesheets.main.replace(/__FONT_SIZE__/g, data.fontSize).replace(/__FONT_COLOR__/g, data.fontColor) + '</style>' + render();
  281. container = shadowRoot.querySelector('.__MonkeyConfig_container');
  282.  
  283. // Atur posisi dan ukuran layer
  284. openLayer.style.cssText = 'position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);max-height:80vh;overflow-y:auto;z-index:10000;width:' + data.width + ';height:' + data.height + ';';
  285.  
  286. // Tambahkan ke dokumen
  287. body.appendChild(overlay);
  288. body.appendChild(openLayer);
  289. openDone();
  290.  
  291. window.addEventListener('resize', function () {
  292. overlay.style.width = window.innerWidth + 'px';
  293. overlay.style.height = window.innerHeight + 'px';
  294. });
  295. }
  296.  
  297. function close() {
  298. if (openLayer) { openLayer.parentNode.removeChild(openLayer); openLayer = undefined; }
  299. if (overlay) { overlay.parentNode.removeChild(overlay); overlay = undefined; }
  300. shadowRoot = undefined;
  301. displayed = false;
  302. }
  303.  
  304. init();
  305. }
  306.  
  307. MonkeyConfig.esc = function (string) { return string.replace(/"/g, '"'); };
  308.  
  309. MonkeyConfig.HTML = {
  310. '_field': function (name, options) {
  311. return options.type && MonkeyConfig.HTML[options.type] ? options.html ? options.html.replace(/\[FIELD\]/, MonkeyConfig.HTML[options.type](name, options)) : MonkeyConfig.HTML[options.type](name, options) : '';
  312. },
  313. '_label': function (name, options) {
  314. var label = options.label || name.substring(0, 1).toUpperCase() + name.substring(1).replace(/_/g, ' ');
  315. var styles = [];
  316. if (options.labelAlign) styles.push('text-align:' + options.labelAlign);
  317. if (options.fontSize) styles.push('font-size:' + options.fontSize);
  318. if (options.fontColor) styles.push('color:' + options.fontColor);
  319. var styleAttr = styles.length > 0 ? ' style="' + styles.join(';') + ';"' : '';
  320. return '<label for="__MonkeyConfig_field_' + name + '"' + styleAttr + '>' + label + '</label>';
  321. },
  322. 'checkbox': function (name) { return '<input id="__MonkeyConfig_field_' + name + '" type="checkbox" name="' + name + '" />'; },
  323. 'custom': function (name, options) { return options.html || ''; },
  324. 'number': function (name, options) { return '<input id="__MonkeyConfig_field_' + name + '" type="number" class="__MonkeyConfig_field_number" name="' + name + '" min="' + (options.min || '') + '" max="' + (options.max || '') + '" step="' + (options.step || '1') + '" />'; },
  325. 'text': function (name) { return '<input id="__MonkeyConfig_field_' + name + '" type="text" class="__MonkeyConfig_field_text" name="' + name + '" />'; },
  326. 'color': function (name) { return '<input id="__MonkeyConfig_field_' + name + '" type="color" class="__MonkeyConfig_field_text" name="' + name + '" />'; },
  327. 'textarea': function (name, options) { return '<textarea id="__MonkeyConfig_field_' + name + '" class="__MonkeyConfig_field_text" name="' + name + '" rows="' + (options.rows || 4) + '" cols="' + (options.cols || 20) + '"></textarea>'; },
  328. 'range': function (name, options) { return '<input id="__MonkeyConfig_field_' + name + '" type="range" name="' + name + '" min="' + (options.min || 0) + '" max="' + (options.max || 100) + '" step="' + (options.step || 1) + '" />'; },
  329. 'radio': function (name, options) {
  330. var html = '';
  331. for (var value in options.choices) {
  332. html += '<label><input type="radio" name="' + name + '" value="' + MonkeyConfig.esc(value) + '" /> ' + options.choices[value] + '</label><br/>';
  333. }
  334. return html;
  335. },
  336. 'file': function (name, options) { return '<input id="__MonkeyConfig_field_' + name + '" type="file" name="' + name + '" accept="' + (options.accept || '*/*') + '" />'; },
  337. 'button': function (name, options) { return '<button type="button" id="__MonkeyConfig_field_' + name + '" name="' + name + '">' + (options.label || 'Click') + '</button>'; },
  338. 'group': function (name, options) {
  339. var html = '<fieldset><legend>' + (options.label || name) + '</legend>';
  340. for (var subName in options.params) {
  341. html += MonkeyConfig.formatters.tr(subName, options.params[subName]);
  342. }
  343. html += '</fieldset>';
  344. return html;
  345. },
  346. 'select': function (name, options) {
  347. var choices = options.choices.constructor === Array ? options.choices.reduce(function (obj, val) { obj[val] = val; return obj; }, {}) : options.choices;
  348. var html = '<select id="__MonkeyConfig_field_' + name + '" class="__MonkeyConfig_field_select" name="' + name + '"' + (options.multiple ? ' multiple="multiple"' : '') + '>';
  349. for (var value in choices) {
  350. html += '<option value="' + MonkeyConfig.esc(value) + '">' + choices[value] + '</option>';
  351. }
  352. html += '</select>';
  353. return html;
  354. }
  355. };
  356.  
  357. MonkeyConfig.formatters = {
  358. 'tr': function (name, options) {
  359. var html = '<tr>';
  360. if (options.type === 'checkbox' || options.type === 'number' || options.type === 'text') {
  361. html += '<td id="__MonkeyConfig_parent_' + name + '" colspan="2" class="__MonkeyConfig_inline">' +
  362. MonkeyConfig.HTML._label(name, options) + ' ' +
  363. MonkeyConfig.HTML._field(name, options) +
  364. '</td>';
  365. } else if (options.type === 'group') {
  366. html += '<td colspan="2">' + MonkeyConfig.HTML._field(name, options) + '</td>';
  367. } else {
  368. html += '<td>' + MonkeyConfig.HTML._label(name, options) + '</td><td id="__MonkeyConfig_parent_' + name + '">' + MonkeyConfig.HTML._field(name, options) + '</td>';
  369. }
  370. html += '</tr>';
  371. return html;
  372. }
  373. };
  374.  
  375. MonkeyConfig.res = {
  376. icons: {
  377. 'arrow_undo': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAIJSURBVDjLpVM9aJNRFD35GsRSoUKKzQ/B0NJJF3EQlKrVgijSCBmC4NBFKihIcXBwEZdSHVoUwUInFUEkQ1DQ4CKiFsQsTrb5xNpgaZHw2Uog5t5zn0NJNFaw0guX97hwzuPcc17IOYfNlIdNVrhxufR6xJkZjAbSQGXjNAorqixSWFDV3KPhJ+UGLtSQMPryrDscPwLnAHOEOQc6gkbUpIagGmApWIb/pZRX4fjj889nWiSQtgYyBZ1BTUEj6AjPa0P71nb0Jfqwa+futIheHrzRn2yRQCUK/lOQhApBJVQJChHfnkCqOwWEQ+iORJHckUyX5ksvAEyGNuJC+s6xCRXNHNxzKMmQ4luwgjfvZp69uvr2+IZcyJ8rjIporrxURggetnV0QET3rrPxzMNM2+n7p678jUTrCiWhphAjVHR9DlR0WkSzf4IHxg5MSF0zXZEuVKWKSlCBCostS8zeG7oV64wPqxInbw86lbVXKEQ8mkAqmUJ4SxieeVhcnANFC02C7N2h69HO2IXeWC8MDj2JnqaFNAMd8f3HKjx6+LxQRmnOz1OZaxKIaF1VISYwB9ARZoQaYY6o1WpYCVYxt+zDn/XzVBv/MOWXW5J44ubRyVgkelFpmF/4BJVfOVDlVyqLVBZI5manPjajDOdcswfG9k/3X9v3/vfZv7rFBanriIo++J/f+BMT+YWS6hXl7QAAAABJRU5ErkJggg==',
  378. 'cancel': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHdSURBVDjLpZNraxpBFIb3a0ggISmmNISWXmOboKihxpgUNGWNSpvaS6RpKL3Ry//Mh1wgf6PElaCyzq67O09nVjdVlJbSDy8Lw77PmfecMwZg/I/GDw3DCo8HCkZl/RlgGA0e3Yfv7+DbAfLrW+SXOvLTG+SHV/gPbuMZRnsyIDL/OASziMxkkKkUQTJJsLaGn8/iHz6nd+8mQv87Ahg2H9Th/BxZqxEkEgSrq/iVCvLsDK9awtvfxb2zjD2ARID+lVVlbabTgWYTv1rFL5fBUtHbbeTJCb3EQ3ovCnRC6xAgzJtOE+ztheYIEkqbFaS3vY2zuIj77AmtYYDusPy8/zuvunJkDKXM7tYWTiyGWFjAqeQnAD6+7ueNx/FLpRGAru7mcoj5ebqzszil7DggeF/DX1nBN82rzPqrzbRayIsLhJqMPT2N83Sdy2GApwFqRN7jFPL0tF+10cDd3MTZ2AjNUkGCoyO6y9cRxfQowFUbpufr1ct4ZoHg+Dg067zduTmEbq4yi/UkYidDe+kaTcP4ObJIajksPd/eyx3c+N2rvPbMDPbUFPZSLKzcGjKPrbJaDsu+dQO3msfZzeGY2TCvKGYQhdSYeeJjUt21dIcjXQ7U7Kv599f4j/oF55W4g/2e3b8AAAAASUVORK5CYII=',
  379. 'tick': 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAGrSURBVDjLvZPZLkNhFIV75zjvYm7VGFNCqoZUJ+roKUUpjRuqp61Wq0NKDMelGGqOxBSUIBKXWtWGZxAvobr8lWjChRgSF//dv9be+9trCwAI/vIE/26gXmviW5bqnb8yUK028qZjPfoPWEj4Ku5HBspgAz941IXZeze8N1bottSo8BTZviVWrEh546EO03EXpuJOdG63otJbjBKHkEp/Ml6yNYYzpuezWL4s5VMtT8acCMQcb5XL3eJE8VgBlR7BeMGW9Z4yT9y1CeyucuhdTGDxfftaBO7G4L+zg91UocxVmCiy51NpiP3n2treUPujL8xhOjYOzZYsQWANyRYlU4Y9Br6oHd5bDh0bCpSOixJiWx71YY09J5pM/WEbzFcDmHvwwBu2wnikg+lEj4mwBe5bC5h1OUqcwpdC60dxegRmR06TyjCF9G9z+qM2uCJmuMJmaNZaUrCSIi6X+jJIBBYtW5Cge7cd7sgoHDfDaAvKQGAlRZYc6ltJlMxX03UzlaRlBdQrzSCwksLRbOpHUSb7pcsnxCCwngvM2Rm/ugUCi84fycr4l2t8Bb6iqTxSCgNIAAAAAElFTkSuQmCC'
  380. },
  381. stylesheets: {
  382. main: `
  383. /* Styling dalam Shadow DOM tidak perlu !important berlebihan */
  384. .__MonkeyConfig_container {
  385. display: flex;
  386. flex-direction: column;
  387. padding: 1em;
  388. font-size: __FONT_SIZE__;
  389. color: __FONT_COLOR__;
  390. background: #eee linear-gradient(180deg, #f8f8f8 0, #ddd 100%);
  391. border-radius: 0.5em;
  392. box-shadow: 2px 2px 16px #000;
  393. max-width: 90vw;
  394. width: 100%;
  395. height: 100%;
  396. position: relative;
  397. box-sizing: border-box;
  398. }
  399. .__MonkeyConfig_container h1 {
  400. border-bottom: solid 1px #999;
  401. font-size: 120%;
  402. margin: 0 0 0.5em 0;
  403. padding: 0 0 0.3em 0;
  404. text-align: center;
  405. }
  406. .__MonkeyConfig_content {
  407. flex: 1;
  408. overflow-y: auto;
  409. max-height: 60vh;
  410. }
  411. .__MonkeyConfig_top, .__MonkeyConfig_bottom {
  412. margin-bottom: 1em;
  413. }
  414. .__MonkeyConfig_columns {
  415. display: flex;
  416. justify-content: space-between;
  417. margin-bottom: 1em;
  418. }
  419. .__MonkeyConfig_left_column, .__MonkeyConfig_right_column {
  420. width: 48%;
  421. }
  422. .__MonkeyConfig_container table {
  423. border-spacing: 0;
  424. margin: 0;
  425. width: 100%;
  426. }
  427. .__MonkeyConfig_container td {
  428. border: none;
  429. line-height: 100%;
  430. padding: 0.3em;
  431. text-align: left;
  432. vertical-align: middle;
  433. white-space: normal;
  434. }
  435. .__MonkeyConfig_container td.__MonkeyConfig_inline {
  436. display: flex;
  437. align-items: center;
  438. white-space: nowrap;
  439. }
  440. .__MonkeyConfig_container td.__MonkeyConfig_inline label {
  441. margin-right: 0.5em;
  442. flex-shrink: 0;
  443. display: block;
  444. }
  445. .__MonkeyConfig_container td.__MonkeyConfig_inline input[type="checkbox"] {
  446. flex-grow: 0;
  447. margin: 0 0.3em 0 0;
  448. display: inline-block;
  449. width: 16px;
  450. height: 16px;
  451. }
  452. .__MonkeyConfig_container td.__MonkeyConfig_inline input[type="number"],
  453. .__MonkeyConfig_container td.__MonkeyConfig_inline input[type="text"] {
  454. flex-grow: 0;
  455. width: 100px;
  456. min-width: 50px;
  457. }
  458. .__MonkeyConfig_buttons_container {
  459. margin-top: 1em;
  460. border-top: solid 1px #999;
  461. padding-top: 0.6em;
  462. text-align: center;
  463. }
  464. .__MonkeyConfig_buttons_container table {
  465. width: auto;
  466. margin: 0 auto;
  467. }
  468. .__MonkeyConfig_buttons_container td {
  469. padding: 0.3em;
  470. }
  471. .__MonkeyConfig_container button {
  472. background: #ccc linear-gradient(180deg, #ddd 0, #ccc 45%, #bbb 50%, #aaa 100%);
  473. border: solid 1px;
  474. border-radius: 0.5em;
  475. box-shadow: 0 0 1px #000;
  476. padding: 3px 8px 3px 24px;
  477. white-space: nowrap;
  478. }
  479. .__MonkeyConfig_container button img {
  480. vertical-align: middle;
  481. }
  482. .__MonkeyConfig_container label {
  483. line-height: 120%;
  484. vertical-align: middle;
  485. display: inline-block;
  486. width: 100%;
  487. }
  488. .__MonkeyConfig_container textarea {
  489. vertical-align: text-top;
  490. width: 100%;
  491. white-space: pre-wrap;
  492. resize: vertical;
  493. text-align: left;
  494. }
  495. .__MonkeyConfig_container input[type="text"],
  496. .__MonkeyConfig_container input[type="number"],
  497. .__MonkeyConfig_container input[type="color"] {
  498. background: #fff;
  499. }
  500. .__MonkeyConfig_container button:hover {
  501. background: #d2d2d2 linear-gradient(180deg, #e2e2e2 0, #d2d2d2 45%, #c2c2c2 50%, #b2b2b2 100%);
  502. }
  503. `
  504. }
  505. };

QingJ © 2025

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