您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
ConfigManager: Manage(Get, set and update) your config with config path simply with a ruleset!
当前为
此脚本不应直接安装,它是供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.gf.qytechs.cn/scripts/449583/1143537/ConfigManager.js
/* eslint-disable no-multi-spaces */ // ==UserScript== // @name ConfigManager // @namespace ConfigManager // @version 0.6.3 // @description ConfigManager: Manage(Get, set and update) your config with config path simply with a ruleset! // @author PY-DNG // @license GPL-v3 // @grant GM_setValue // @grant GM_getValue // @grant GM_listValues // @grant GM_deleteValue // ==/UserScript== function ConfigManager(Ruleset, storage={}) { const CM = this; const _GM_setValue = storage.GM_setValue || GM_setValue || Err('ConfigManager: could not find GM_setValue'); const _GM_getValue = storage.GM_getValue || GM_getValue || Err('ConfigManager: could not find GM_getValue'); const _GM_listValues = storage.GM_listValues || GM_listValues || Err('ConfigManager: could not find GM_listValues'); const _GM_deleteValue = storage.GM_deleteValue || GM_deleteValue || Err('ConfigManager: could not find GM_deleteValue'); const ConfigBase = new Proxy({}, { get: function(target, property, reciever) { return _GM_getValue(property); }, set: function(target, property, value, reciever) { return (_GM_setValue(property, value), true); }, has: function(target, property) { return _GM_listValues().includes(property); } }); CM.getConfig = getConfig; CM.setConfig = setConfig; CM.updateConfig = updateConfig; CM.updateAllConfigs = updateAllConfigs; CM.setDefaults = setDefaults; CM.readPath = readPath; CM.pathExists = pathExists; CM.mergePath = mergePath; CM.getBaseName = getBaseName; CM.makeSubStorage = makeSubStorage; CM.Config = new Proxy({}, { get: function(target, property, reciever) { return makeProxy(getConfig(property), [property]); function makeProxy(config, path) { return isObject(config) ? new Proxy(config, { get: function(target, property, reciever) { path.push(property); return makeProxy(target[property], path); }, set: function(target, property, value, reciever) { path.push(property); return (setConfig(path, value), true); } }) : config; } }, set: function(target, property, value, reciever) { return (_GM_setValue(property, value), true); }, has: function(target, property) { return _GM_listValues().includes(property); } }); Object.freeze(CM); // Get config value from path (e.g. 'Users/username/' or ['Users', 12345]) function getConfig(path) { // Split path path = arrPath(path); // Init config if need if (!(path[0] in ConfigBase)) { ConfigBase[path[0]] = Ruleset.defaultValues[path[0]]; } // Get config by path const target = path.pop(); let config = readPath(ConfigBase, path); return config[target]; } // Set config value to path function setConfig(path, value) { path = arrPath(path); const target = path.pop(); // Init config if need if (!(path[0] in ConfigBase)) { ConfigBase[path[0]] = Ruleset.defaultValues[path[0]]; } if (path.length > 0) { const basekey = path.shift(); const baseobj = ConfigBase[basekey]; let config = readPath(baseobj, path); if (isObject(config)) { config[target] = value; ConfigBase[basekey] = baseobj; } else { Err('Attempt to set a property to a non-object value') } } else { ConfigBase[target] = value; } } function updateConfig(basename) { let updated = false; // Get updaters and config const updaters = Ruleset.updaters.hasOwnProperty(basename) ? Ruleset.updaters[basename] : []; const verKey = Ruleset['version-key']; const config = getConfig(basename); // Valid check if (Ruleset.ignores.includes(basename)) { return false; } if (!updaters.length) { return save(); } // Update for (let i = (config[verKey] || 0); i < updaters.length; i++) { const updater = updaters[i]; config = updater(config); updated = true; } // Set version and save return save(); function save() { config[verKey] = updaters.length; setConfig(basename, config); return updated; } } function updateAllConfigs() { const keys = _GM_listValues(); keys.forEach((key) => (updateConfig(key))); } function setDefaults() { for (const [key, val] of Object.entries(Ruleset.defaultValues)) { !(key in ConfigBase) && (ConfigBase[key] = val); } } function makeSubStorage(path) { path = arrPath(path); return { GM_setValue: function(key, value) { setConfig([...path, key], value); }, GM_getValue: function(key, defaultValue) { try { return getConfig([...path, key]); } catch (err) { return defaultValue; } }, GM_listValues: function() { return Object.keys(getConfig(path)); }, GM_deleteValue: function(key) { const parent = getConfig(path); delete parent[key]; setConfig(path, parent); } } } function readPath(obj, path) { path = arrPath(path); while (path.length > 0) { const key = path.shift(); if (isObject(obj) && hasProp(obj, key)) { obj = obj[key]; } else { Err('Attempt to read a property that is not exist (reading "' + key + '" in path "' + path + '")'); } } return obj; } function pathExists(obj, path) { path = arrPath(path); while (path.length > 0) { const key = path.shift(); if (isObject(obj) && hasProp(obj, key)) { obj = obj[key]; } else { return false; } } return true; } function mergePath() { return Array.from(arguments).join('/'); } function getBaseName(path) { return arrPath(path)[0]; } function getPathWithoutBase(path) { const p = arrPath(path); p.shift(); return p; } function arrPath(strpath) { return Array.isArray(strpath) ? [...strpath] : strpath.split('/'); } function isObject(obj) { return typeof obj === 'object' && obj !== null; } function hasProp(obj, prop) { return obj === ConfigBase ? prop in obj : obj.hasOwnProperty(prop); } // type: [Error, TypeError] function Err(msg, type=0) { throw new [Error, TypeError][type](msg); } }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址