您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
ConfigManager: Manage(Get, set and update) your config with config path simply with a ruleset!
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/449583/1081638/ConfigManager.js
/* eslint-disable no-multi-spaces */ // ==UserScript== // @name ConfigManager // @namespace ConfigManager // @version 0.1 // @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) { const CM = this; 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.readPath = readPath; CM.pathExists = pathExists; CM.mergePath = mergePath; CM.getBaseName = getBaseName; Object.freeze(CM); // Get config value from path (e.g. 'Users/username/' or ['Users', 12345]) function getConfig(path) { // Split path path = Array.isArray(path) ? path : path.split('/'); // Init config if need if (!GM_listValues().includes(path[0])) { 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 = Array.isArray(path) ? path : path = path.split('/'); const target = path.pop(); 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(path) { const basename = getBaseName(path); if (!Ruleset.updaters.hasOwnProperty(basename)) {return;} const updaters = Ruleset.updaters[basename]; const verKey = Ruleset['version-key']; const config = getConfig(path); for (let i = config[verKey]; i < updaters.length; i++) { const updater = updaters[i]; config = updater(config) } config[verKey] = updaters.length; setConfig(path, config); } function updateAllConfigs() { const keys = GM_listValues(); keys.forEach((key) => (updateConfig(key))); } function readPath(obj, path) { path = [...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 = [...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 path.split('/')[0]; } function getPathWithoutBase(path) { const p = path.split('/'); p.shift(); return p; } 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); } }