Greasy Fork镜像 支持简体中文。

IdlePixel+ Zlef's Modal & Settings Manager

Modal framework for Idle-Pixel with a Settings manager, modal optional for settings

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/500003/1408507/IdlePixel%2B%20Zlef%27s%20Modal%20%20Settings%20Manager.js

  1. // ==UserScript==
  2. // @name IdlePixel+ Zlef's Modal & Settings Manager
  3. // @namespace com.zlef.modallibrary
  4. // @version 1.0.2
  5. // @description Modal framework for Idle-Pixel with a Settings manager, modal optional for settings
  6. // @author Zlef
  7. // @match *://idle-pixel.com/*
  8. // @grant none
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (function() {
  13. 'use strict';
  14.  
  15. if(window.ZlefsModal ) {
  16. return;
  17. }
  18.  
  19. class ZlefsModal {
  20. constructor(pluginName) {
  21. this.pluginName = pluginName;
  22. this.modals = [];
  23. this.overlay = null;
  24. this.closeCallbacks = [];
  25. this.initCustomCSS();
  26. }
  27.  
  28. initCustomCSS() {
  29. const css = `
  30. .zlefs-modal {
  31. position: absolute; /* Ensure it works with draggable */
  32. background-color: #fff;
  33. border-radius: 8px;
  34. box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  35. max-height: 80vh;
  36. max-width: 80vh;
  37. display: flex;
  38. flex-direction: column;
  39. overflow: hidden; /* Ensures rounded corners are visible */
  40. }
  41. .zlefs-modal-header {
  42. cursor: move;
  43. padding-bottom: 40px;
  44. margin-bottom: 10px;
  45. background-color: #f1f1f1;
  46. border-bottom: 1px solid #ccc;
  47. position: sticky;
  48. top: 0;
  49. left: 0;
  50. right: 0;
  51. width: 100%;
  52. box-sizing: border-box;
  53. border-top-left-radius: 8px; /* Rounded corners */
  54. border-top-right-radius: 8px; /* Rounded corners */
  55. z-index: 10; /* Ensure header is above the content */
  56. }
  57. .zlefs-modal-header-text {
  58. position: absolute;
  59. top: 50%;
  60. left: 10px;
  61. transform: translateY(-50%);
  62. pointer-events: none;
  63. height: 20px;
  64. font-weight: bold;
  65. }
  66. .zlefs-modal-content {
  67. padding: 0 20px 20px 20px;
  68. overflow-y: auto;
  69. flex-grow: 1; /* Allows the content to grow and fill the remaining space */
  70. }
  71. .zlefs-close-button {
  72. position: absolute;
  73. top: 10px;
  74. right: 10px;
  75. background: none;
  76. border: none;
  77. cursor: pointer;
  78. z-index: 11; /* Ensure close button is above the header */
  79. }
  80. #zlefs-modal-overlay {
  81. position: fixed;
  82. top: 0;
  83. left: 0;
  84. width: 100%;
  85. height: 100%;
  86. background-color: rgba(0, 0, 0, 0.7);
  87. z-index: 1000;
  88. display: flex;
  89. justify-content: center;
  90. align-items: center;
  91. }
  92. .zlefs-section {
  93. border: 1px solid black;
  94. background-color: white;
  95. padding: 10px 10px 0px 10px;
  96. margin-bottom: 10px;
  97. }
  98. .zlefs-section-title {
  99. margin-bottom: 10px;
  100. margin-left: 2px;
  101. font-weight: bold;
  102. cursor: pointer;
  103. }
  104. .zlefs-section-content {
  105. display: none;
  106. }
  107. .zlefs-section-content.zlefs-hidden {
  108. display: block;
  109. }
  110. .zlefs-item {
  111. width: 100%;
  112. display: flex;
  113. justify-content: space-between;
  114. align-items: center;
  115. margin-bottom: 5px;
  116. }
  117. .zlefs-checkbox-container {
  118. display: flex;
  119. justify-content: space-between;
  120. align-items: center;
  121. width: 100%;
  122. max-width: 400px;
  123. }
  124. .zlefs-checkbox-label {
  125. flex: 1;
  126. text-align: left;
  127. margin-right: 10px;
  128. }
  129. .zlefs-checkbox-input {
  130. flex: 0;
  131. text-align: right;
  132. }
  133. .zlefs-vertical-divider {
  134. width: 1px;
  135. background-color: #ccc;
  136. padding: 0;
  137. display: flex;
  138. }
  139. `;
  140. this.addCSS(css)
  141.  
  142. }
  143.  
  144. addCSS(cssString) {
  145. const style = document.createElement('style');
  146. style.type = 'text/css';
  147. style.appendChild(document.createTextNode(cssString));
  148. document.head.appendChild(style);
  149. }
  150.  
  151. createOverlay() {
  152. if (this.overlay) return;
  153.  
  154. this.overlay = document.createElement('div');
  155. this.overlay.id = 'zlefs-modal-overlay';
  156.  
  157. this.overlay.addEventListener('click', (event) => {
  158. if (event.target === this.overlay) {
  159. this.closeTopModal();
  160. }
  161. });
  162.  
  163. document.body.appendChild(this.overlay);
  164. }
  165.  
  166. addModal(content, name, width = 'auto', height = 'auto', closeCallback = null) {
  167. this.createOverlay();
  168.  
  169. const modalBox = document.createElement('div');
  170. modalBox.className = 'zlefs-modal';
  171. modalBox.style.width = typeof width === 'number' ? `${width}px` : width;
  172. modalBox.style.height = typeof height === 'number' ? `${height}px` : height;
  173.  
  174. const closeButton = document.createElement('button');
  175. closeButton.className = 'zlefs-close-button';
  176. closeButton.textContent = '✖';
  177. closeButton.addEventListener('click', () => {
  178. this.closeModal(modalBox);
  179. if (closeCallback) closeCallback();
  180. });
  181.  
  182. const header = document.createElement('div');
  183. header.className = 'zlefs-modal-header';
  184.  
  185. const nameSpan = document.createElement('span');
  186. nameSpan.textContent = name;
  187. nameSpan.className = 'zlefs-modal-header-text';
  188.  
  189. header.appendChild(nameSpan);
  190.  
  191. const contentWrapper = document.createElement('div');
  192. contentWrapper.className = 'zlefs-modal-content';
  193. contentWrapper.appendChild(content);
  194.  
  195. modalBox.appendChild(header);
  196. modalBox.appendChild(closeButton);
  197. modalBox.appendChild(contentWrapper);
  198. this.overlay.appendChild(modalBox);
  199. this.modals.push(modalBox);
  200. this.closeCallbacks.push(closeCallback);
  201.  
  202. this.makeDraggable(modalBox, header);
  203.  
  204. // Ensure modal is fully rendered before centering
  205. setTimeout(() => {
  206. this.centreModal(modalBox);
  207. }, 0);
  208. }
  209.  
  210. centreModal(modalBox) {
  211. if (!modalBox) {
  212. console.log("modalBox is not defined. If you're seeing this good luck lol.");
  213. return;
  214. }
  215. const rect = modalBox.getBoundingClientRect();
  216.  
  217. // Window dimensions
  218. const windowHeight = window.innerHeight;
  219. const windowWidth = window.innerWidth;
  220. console.log(`windowHeight: ${windowHeight}`);
  221. console.log(`windowWidth: ${windowWidth}`);
  222. console.log(`modalBox height: ${rect.height}`);
  223. console.log(`modalBox width: ${rect.width}`);
  224.  
  225. const newModalTop = (windowHeight - rect.height) / 2;
  226. const newModalLeft = (windowWidth - rect.width) / 2;
  227. console.log(`newModalTop: ${Math.floor(newModalTop)}`);
  228. console.log(`newModalLeft: ${Math.floor(newModalLeft)}`);
  229.  
  230. // Set the top and left positions
  231. modalBox.style.position = 'absolute'; // Ensure the positioning context
  232. modalBox.style.top = `${Math.floor(newModalTop)}px`;
  233. modalBox.style.left = `${Math.floor(newModalLeft)}px`;
  234.  
  235. // Set min width as moving the modal against the side can squish it. Should probably solve that behavior instead but here we are.
  236. modalBox.style.minWidth = `${rect.width}px`;
  237.  
  238. // Additional log to check the final style
  239. console.log(`modalBox final top: ${modalBox.style.top}`);
  240. console.log(`modalBox final left: ${modalBox.style.left}`);
  241. console.log(`modalBox final minWidth: ${modalBox.style.minWidth}`);
  242.  
  243. }
  244.  
  245. closeModal(modal) {
  246. const modalIndex = this.modals.indexOf(modal);
  247. if (modalIndex !== -1) {
  248. this.modals.splice(modalIndex, 1);
  249. this.closeCallbacks.splice(modalIndex, 1);
  250. }
  251. if (modal && modal.parentElement) {
  252. this.overlay.removeChild(modal);
  253. }
  254. if (this.modals.length === 0 && this.overlay) {
  255. document.body.removeChild(this.overlay);
  256. this.overlay = null;
  257. }
  258. }
  259.  
  260. closeTopModal() {
  261. if (this.modals.length > 0) {
  262. const topmodal = this.modals[this.modals.length - 1];
  263. const topCallback = this.closeCallbacks[this.closeCallbacks.length - 1];
  264. this.closeModal(topmodal);
  265. if (topCallback) topCallback();
  266. }
  267. }
  268.  
  269. makeDraggable(modalBox, header) {
  270. let offsetX = 0, offsetY = 0, startX = 0, startY = 0;
  271.  
  272. const onMouseDown = (e) => {
  273. e.preventDefault();
  274.  
  275. startX = e.clientX;
  276. startY = e.clientY;
  277.  
  278. offsetX = modalBox.offsetLeft;
  279. offsetY = modalBox.offsetTop;
  280. document.addEventListener('mousemove', onMouseMove);
  281. document.addEventListener('mouseup', onMouseUp);
  282. };
  283.  
  284. const onMouseMove = (e) => {
  285. e.preventDefault();
  286. let dx = e.clientX - startX;
  287. let dy = e.clientY - startY;
  288.  
  289. let newLeft = offsetX + dx;
  290. let newTop = offsetY + dy;
  291.  
  292. modalBox.style.left = `${newLeft}px`;
  293. modalBox.style.top = `${newTop}px`;
  294. };
  295.  
  296. const onMouseUp = (e) => {
  297. const rect = modalBox.getBoundingClientRect();
  298. const corners = {
  299. topLeft: { left: rect.left, top: rect.top },
  300. bottomRight: { left: rect.right, top: rect.bottom }
  301. };
  302.  
  303. if (rect.left < 0) {
  304. modalBox.style.left = '0px';
  305. }
  306. if (rect.top < 0) {
  307. modalBox.style.top = '0px';
  308. }
  309. if (rect.right > window.innerWidth) {
  310. modalBox.style.left = (window.innerWidth - rect.width) + 'px';
  311. }
  312. if (rect.bottom > window.innerHeight) {
  313. modalBox.style.top = (window.innerHeight - rect.height) + 'px';
  314. }
  315.  
  316. document.removeEventListener('mousemove', onMouseMove);
  317. document.removeEventListener('mouseup', onMouseUp);
  318. };
  319.  
  320.  
  321. header.addEventListener('mousedown', onMouseDown);
  322. }
  323.  
  324. repositionModal(modalBox) {
  325. if (!modalBox) return;
  326.  
  327. const rect = modalBox.getBoundingClientRect();
  328. const corners = {
  329. topLeft: { left: rect.left, top: rect.top },
  330. bottomRight: { left: rect.right, top: rect.bottom }
  331. };
  332.  
  333. if (rect.left < 0) {
  334. modalBox.style.left = (rect.width) + 'px';
  335. }
  336. if (rect.top < 0) {
  337. modalBox.style.top = (rect.height) + 'px';
  338. }
  339. if (rect.right > window.innerWidth) {
  340. modalBox.style.left = (window.innerWidth - (rect.width)) + 'px';
  341. }
  342. if (rect.bottom > window.innerHeight) {
  343. modalBox.style.top = (window.innerHeight - (rect.height)) + 'px';
  344. }
  345. }
  346.  
  347. titleCaseUnderscore(input) {
  348. const words = input.split('_');
  349. const convertedText = words.map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ');
  350. return convertedText;
  351. }
  352.  
  353. addTitle(parent, text, level = 2, textAlign = 'left') {
  354. const title = document.createElement(`h${level}`);
  355. title.textContent = text;
  356. title.style.textAlign = textAlign;
  357. parent.appendChild(title);
  358. return title
  359. }
  360.  
  361. addSection(parent, sectionTitleText) {
  362. const sectionDiv = document.createElement('div');
  363. sectionDiv.className = 'zlefs-section';
  364.  
  365. const sectionTitle = document.createElement('div');
  366. sectionTitle.className = 'zlefs-section-title';
  367. sectionTitle.textContent = sectionTitleText;
  368.  
  369. const sectionContent = document.createElement('div');
  370. sectionContent.className = 'zlefs-section-content';
  371.  
  372. sectionTitle.addEventListener('click', () => {
  373. const modal = this.findParentmodal(sectionDiv);
  374.  
  375. const originalTop = modal.getBoundingClientRect().top;
  376. const originalScrollTop = document.documentElement.scrollTop || document.body.scrollTop;
  377.  
  378. sectionContent.classList.toggle('zlefs-hidden');
  379.  
  380. const newTop = modal.getBoundingClientRect().top;
  381. const deltaHeight = parseInt((originalTop - newTop));
  382.  
  383. const currentTop = parseInt(window.getComputedStyle(modal).top);
  384. modal.style.top = `${(currentTop + deltaHeight)}px`;
  385.  
  386. this.repositionModal(modal);
  387.  
  388. });
  389.  
  390. sectionDiv.appendChild(sectionTitle);
  391. sectionDiv.appendChild(sectionContent);
  392. parent.appendChild(sectionDiv);
  393.  
  394. return sectionContent;
  395. }
  396.  
  397. findParentmodal(element) {
  398. while (element && !element.classList.contains('zlefs-modal')) {
  399. element = element.parentElement;
  400. }
  401. return element;
  402. }
  403.  
  404. addDiv(parent) {
  405. const div = document.createElement('div');
  406. parent.appendChild(div);
  407. return div;
  408. }
  409.  
  410. addContainer(parent) {
  411. const container = document.createElement('div');
  412. container.className = 'container';
  413. parent.appendChild(container);
  414. return container;
  415. }
  416.  
  417. addRow(parent) {
  418. const row = document.createElement('div');
  419. row.className = 'row';
  420. parent.appendChild(row);
  421. return row;
  422. }
  423.  
  424. addCol(parent, size = '', align = 'left') {
  425. const col = document.createElement('div');
  426. col.className = size ? `col-${size}` : 'col';
  427. col.style.textAlign = align === 'centre' ? 'center' : align;
  428. parent.appendChild(col);
  429. return col;
  430. }
  431.  
  432. addDivider(parent, margin = 5) {
  433. const divider = document.createElement('hr');
  434. divider.style.width = `calc(100% - ${2 * margin}px)`;
  435. divider.style.marginLeft = `${margin}px`;
  436. divider.style.marginRight = `${margin}px`;
  437. parent.appendChild(divider);
  438. return divider;
  439. }
  440.  
  441. addVDivider(parent) {
  442. const divider = document.createElement('div');
  443. divider.className = 'zlefs-vertical-divider';
  444. parent.appendChild(divider);
  445. }
  446.  
  447. addInput(parent, type, value, placeholder, min, max, onChange, label = undefined) {
  448. const inputContainer = document.createElement('div');
  449. inputContainer.style.display = 'flex';
  450. inputContainer.style.alignItems = 'center';
  451. inputContainer.style.marginBottom = '10px';
  452.  
  453. if (label){
  454. const inputLabel = document.createElement('label');
  455. inputLabel.textContent = this.titleCaseUnderscore(label);
  456. inputLabel.style.marginRight = '10px';
  457. inputLabel.style.flex = '1';
  458. inputLabel.style.cursor = 'pointer';
  459. inputContainer.appendChild(inputLabel);
  460. }
  461.  
  462. const input = document.createElement('input');
  463. input.type = type;
  464. input.value = value;
  465. input.style.flex = '0';
  466. if (placeholder) input.placeholder = placeholder;
  467. if (min !== undefined) input.min = min;
  468. if (max !== undefined) input.max = max;
  469. input.addEventListener('input', (event) => {
  470. let inputValue = event.target.value;
  471. if (type === 'number') {
  472. if (inputValue < min) inputValue = min;
  473. if (inputValue > max) inputValue = max;
  474. event.target.value = inputValue;
  475. }
  476. onChange(inputValue);
  477. });
  478.  
  479. inputContainer.appendChild(input);
  480. parent.appendChild(inputContainer);
  481. }
  482.  
  483. addCheckbox(parent, checked, onChange, label = undefined) {
  484. const checkboxContainer = document.createElement('div');
  485. checkboxContainer.className = 'zlefs-checkbox-container';
  486. checkboxContainer.style.display = 'flex';
  487. checkboxContainer.style.alignItems = 'center';
  488. checkboxContainer.style.marginBottom = '10px';
  489.  
  490. const checkbox = document.createElement('input');
  491. checkbox.type = 'checkbox';
  492. checkbox.checked = checked;
  493. checkbox.className = 'zlefs-checkbox-input';
  494. checkbox.style.flex = '0';
  495. checkbox.style.cursor = 'pointer';
  496. checkbox.addEventListener('change', (event) => onChange(event.target.checked));
  497.  
  498.  
  499. if (label){
  500. const checkboxLabel = document.createElement('label');
  501. checkboxLabel.textContent = this.titleCaseUnderscore(label);
  502. checkboxLabel.className = 'zlefs-checkbox-label';
  503. checkboxLabel.style.flex = '1';
  504. checkboxLabel.style.cursor = 'pointer';
  505.  
  506. checkboxContainer.appendChild(checkboxLabel);
  507. checkboxLabel.addEventListener('click', () => checkbox.click());
  508. }
  509.  
  510. checkboxContainer.appendChild(checkbox);
  511. parent.appendChild(checkboxContainer);
  512. }
  513.  
  514. addButton(parent, text, onClick, className = 'btn') {
  515. const button = document.createElement('button');
  516. button.textContent = text;
  517. button.className = className;
  518. button.addEventListener('click', onClick);
  519. parent.appendChild(button);
  520. return button;
  521. }
  522.  
  523. addCombobox(parent, options, selectedValue, onChange, label = undefined) {
  524. const comboboxContainer = document.createElement('div');
  525. comboboxContainer.style.display = 'flex';
  526. comboboxContainer.style.alignItems = 'center';
  527. comboboxContainer.style.marginBottom = '10px';
  528.  
  529. if (label) {
  530. const comboboxLabel = document.createElement('label');
  531. comboboxLabel.textContent = this.titleCaseUnderscore(label);
  532. comboboxLabel.style.marginRight = '10px';
  533. comboboxLabel.style.flex = '1';
  534. comboboxLabel.style.cursor = 'pointer';
  535. comboboxContainer.appendChild(comboboxLabel);
  536. }
  537.  
  538. const combobox = document.createElement('select');
  539. combobox.style.flex = '0';
  540. options.forEach(option => {
  541. const optionElement = document.createElement('option');
  542. optionElement.value = option;
  543. optionElement.text = option;
  544. if (option === selectedValue) optionElement.selected = true;
  545. combobox.appendChild(optionElement);
  546. });
  547.  
  548. combobox.addEventListener('change', (event) => onChange(event.target.value));
  549.  
  550. comboboxContainer.appendChild(combobox);
  551. parent.appendChild(comboboxContainer);
  552. return comboboxContainer;
  553. }
  554. }
  555.  
  556. class ZlefsSettingsManager {
  557. constructor(prefix, settings) {
  558. this.prefix = prefix;
  559. this.defaultSettings = JSON.parse(JSON.stringify(settings));
  560. this.settings = settings;
  561. this.modalContent = null;
  562. this.loadSettings();
  563. }
  564.  
  565. saveSettings() {
  566. const settingsToSave = {};
  567.  
  568. const processSettings = (settings, saveObj) => {
  569. for (const key in settings) {
  570. const setting = settings[key];
  571. if (setting.type === 'button') {
  572. continue; // Skip button types
  573. }
  574. if (setting.type === 'section') {
  575. saveObj[key] = {
  576. type: 'section',
  577. name: setting.name,
  578. settings: {}
  579. };
  580. processSettings(setting.settings, saveObj[key].settings);
  581. } else if (setting.type === 'multicheckbox') {
  582. saveObj[key] = {
  583. type: 'multicheckbox',
  584. values: {}
  585. };
  586. for (const subKey in setting.values) {
  587. saveObj[key].values[subKey] = setting.values[subKey];
  588. }
  589. } else if (setting.type === 'combobox') {
  590. saveObj[key] = {
  591. type: 'combobox',
  592. options: setting.options,
  593. value: setting.value
  594. };
  595. } else {
  596. saveObj[key] = {
  597. type: setting.type,
  598. value: setting.value
  599. };
  600. }
  601. }
  602. };
  603.  
  604. processSettings(this.settings, settingsToSave);
  605. localStorage.setItem(`${this.prefix}_settings`, JSON.stringify(settingsToSave));
  606. }
  607.  
  608. loadSettings() {
  609. const savedSettings = JSON.parse(localStorage.getItem(`${this.prefix}_settings`));
  610. if (savedSettings) {
  611. const processLoadedSettings = (loadedSettings, currentSettings) => {
  612. for (const key in currentSettings) {
  613. if (loadedSettings[key] !== undefined) {
  614. const setting = currentSettings[key];
  615. if (setting.type === 'button') {
  616. continue; // Skip button types
  617. }
  618. if (setting.type === 'section') {
  619. processLoadedSettings(loadedSettings[key].settings, setting.settings);
  620. } else if (setting.type === 'multicheckbox') {
  621. for (const subKey in setting.values) {
  622. setting.values[subKey] = loadedSettings[key].values[subKey] !== undefined
  623. ? loadedSettings[key].values[subKey]
  624. : setting.values[subKey];
  625. }
  626. } else {
  627. setting.value = loadedSettings[key].value;
  628. }
  629. }
  630. }
  631.  
  632. for (const key in loadedSettings) {
  633. if (currentSettings[key] === undefined) {
  634. delete loadedSettings[key];
  635. }
  636. }
  637. };
  638.  
  639. processLoadedSettings(savedSettings, this.settings);
  640. localStorage.setItem(`${this.prefix}_settings`, JSON.stringify(this.settings));
  641. }
  642. }
  643.  
  644. resetSettings() {
  645. this.settings = JSON.parse(JSON.stringify(this.defaultSettings));
  646. this.saveSettings();
  647. }
  648.  
  649. deleteSettings() {
  650. localStorage.removeItem(`${this.prefix}_settings`);
  651. }
  652.  
  653. getSettings() {
  654. return this.settings;
  655. }
  656.  
  657. settingsChanged(fullKey, value, subKey = null) {
  658. const keys = fullKey.split('.');
  659. let currentSettings = this.settings;
  660.  
  661. for (let i = 0; i < keys.length - 1; i++) {
  662. if (currentSettings[keys[i]].type === 'section') {
  663. currentSettings = currentSettings[keys[i]].settings;
  664. } else if (currentSettings[keys[i]].type === 'multicheckbox' && subKey) {
  665. currentSettings = currentSettings[keys[i]].values;
  666. } else {
  667. currentSettings = currentSettings[keys[i]];
  668. }
  669. }
  670.  
  671. const finalKey = keys[keys.length - 1];
  672.  
  673. if (!currentSettings[finalKey]) {
  674. console.error(`settingsChanged - Key ${finalKey} not found in settings`);
  675. return;
  676. }
  677.  
  678. if (subKey) {
  679. currentSettings[finalKey].values[subKey] = value;
  680. } else {
  681. currentSettings[finalKey].value = value;
  682. }
  683. this.saveSettings();
  684. }
  685.  
  686. createSettingsModal(modalFramework, width = 'auto', height = 'auto', closeCallback = null) {
  687. return () => {
  688. const content = document.createElement('div');
  689.  
  690. const buildSettings = (settings, parent) => {
  691. if (!parent) {
  692. console.error('Parent element is null');
  693. return;
  694. }
  695.  
  696. for (const key in settings) {
  697. const setting = settings[key];
  698. const fullKey = key;
  699.  
  700. if (setting.type === 'section') {
  701. const sectionContent = modalFramework.addSection(parent, setting.name);
  702. buildSettings(setting.settings, sectionContent);
  703. } else if (setting.type === 'multicheckbox') {
  704. const sectionContent = modalFramework.addSection(parent, setting.name);
  705. for (const subKey in setting.values) {
  706. modalFramework.addCheckbox(sectionContent, setting.values[subKey], (value) => {
  707. this.settingsChanged(`${fullKey}.${subKey}`, value, subKey);
  708. }, subKey);
  709. }
  710. } else if (setting.type === 'checkbox') {
  711. modalFramework.addCheckbox(parent, setting.value, (value) => {
  712. this.settingsChanged(fullKey, value);
  713. }, key);
  714. } else if (setting.type === 'numinput') {
  715. modalFramework.addInput(parent, 'number', setting.value, '', setting.minValue, setting.maxValue, (value) => {
  716. this.settingsChanged(fullKey, value);
  717. }, key);
  718. } else if (setting.type === 'text') {
  719. modalFramework.addInput(parent, 'text', setting.value, setting.placeholder, undefined, undefined, (value) => {
  720. this.settingsChanged(fullKey, value);
  721. }, key);
  722. } else if (setting.type === 'combobox') {
  723. modalFramework.addCombobox(parent, setting.options, setting.value, (value) => {
  724. this.settingsChanged(fullKey, value);
  725. }, key);
  726. } else if (setting.type === 'button') {
  727. modalFramework.addButton(parent, setting.name, setting.function, 'btn');
  728. }
  729. }
  730. };
  731.  
  732. buildSettings(this.settings, content);
  733.  
  734. modalFramework.addModal(content, `${this.prefix} Settings`, width, height, closeCallback);
  735. };
  736. }
  737.  
  738. }
  739.  
  740. window.ZlefsModal = ZlefsModal;
  741. window.ZlefsSettingsManager = ZlefsSettingsManager;
  742. console.log(`Zlef's Modal and Settings Manager version ${GM_info.script.version} loaded.`);
  743. })();

QingJ © 2025

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