-
Notifications
You must be signed in to change notification settings - Fork 11
GM_config
This is a draft proposal for a new API for userscript engines, GM_config
.
See here for the original proposal.
A popup page similar to MonkeyConfig's UI or
Greasemonkey 3's options panel (Tools -> Greasemonkey -> Greasemonkey Options...).
The page can be opened manually (config.open()
) or via a menu command (see below).
GM_config
is a function which takes a config spec (Object). The spec combines features of:
const config = GM_config({
title: "Example.com Declutterer",
fields: [
{
// field name (required)
name: "blacklist",
// optional: defaults to the name in title-case [1]
// e.g. "disableComments" -> "Disable Comments"
// [1] https://www.npmjs.com/package/title-case
label: "Blacklist",
// "checkbox", "multi", "radio", "select" or "text"
type: "text",
// optional default/initial value
// a primitive, or an array of strings
// (selected option values)
value: null,
// optional description, displayed e.g. in a tooltip
title: "A comma-separated list of tags to hide",
},
{
name: "disableComments",
label: "Disable Comments",
type: "checkbox",
value: false,
},
{
name: "style",
label: "Style",
type: "radio",
value: "Modern",
// an array of strings (option values/labels)
// or { value: ..., label: ... } pairs
options: ["Compact", "Classic", "Modern"],
}
]
})
// register listeners with `on`
config.on("save", values => { ... }) // values: { blacklist: ..., style: ..., ... }
// open the page with `open` e.g. via a menu command
GM_registerMenuCommand("Configure Example.com Declutterer", () => config.open())
Each entry in the fields
array is rendered as a line of form controls.
Multiple controls can be included in the same line by grouping them in
an array e.g.:
{
fields: [
{ ... }, // line 1 (1 control)
[ { ... }, { ... } ], // line 2 (2 controls)
{ ... }, // line 3 (1 control)
]
}
It's up to the user to pull default values from storage (via GM_getValue
)
to populate the UI, and to persist the new values to storage (via GM_setValue
)
when the save
event fires.
Userscripts can portably take advantage of this feature by checking for
it with typeof
e.g.:
if (typeof GM_config === "function") {
// ...
} else {
// fall back to menu commands instead
GM_registerMenuCommand("Disable Comments", ...)
}
- GM_config:
(options: Object) ⇒ GMConfig
- GMConfig#on
- GMConfig#open
- save
- checkbox
- multi (or multiselect)
- radio
- select
- text
- GMConfig#close
- GMConfig#off
- GMConfig#once
- cancel
- close
- open
- color
- date
- datetime (or time or timestamp)
- textarea
Localization support would be nice (and could be done automatically for the "Save" and "Cancel" buttons).
Checkbox, radio, multi, and select fields could be a single type
(e.g. "select")
with an optional style
property e.g.:
- checkbox
- multi
- radio
The options are pure JSON (-serializable) and can easily be represented as — and loaded from — a static resource e.g:
const options = JSON.parse(GM_getResourceText("config"))
const config = GM_config(options)
Although it's out of scope for this proposal, this could even be used as a convention to declare config pages statically:
// ==UserScript==
// ...
// @resource GM_config https://example.com/js/config.json
// ...
// ==/UserScript==