Brazen Framework - Configuration Manager

Configuration management for the Brazen user scripts framework

Hindi dapat direktang i-install ang script na ito. Ito ay isang library para sa iba pang mga script na isasama sa meta directive. // @require https://update.greasyfork.org/scripts/418665/1872288/Brazen%20Framework%20-%20Configuration%20Manager.js

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

Advertisement:

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

Advertisement:

May akda
brazenvoid
Bersyon
2.7.1
Nilikha
2020-12-15
Na update
2026-07-10
Laki
36.4 KB
Lisensya
GPL-3.0-only

Brazen Framework — Configuration Manager (developer guide)

Typed settings schema, pluggable storage drivers (localStorage + Tampermonkey GM), cross-tab sync, backup/restore, and DOM factories bound to View Layer widgets.

Greasy Fork: Configuration Manager · Requires: Utilities, View Layer · Used by: Framework core


Constructor

new BrazenConfigurationManager(scriptPrefix, uiGenerator, tagSelectorGenerator)
Parameter Role
scriptPrefix Prefix for storage keys (per driver)
uiGenerator BrazenViewLayer instance
tagSelectorGenerator (tag: string) => string — used by addTagRulesetField / _optimizeTagRuleset

Framework exposes this as this._configurationManager. Register fields in the subclass constructor; call initialize() during init() before UI build.


Field keys

Display name strings (e.g. 'Tag Blacklist') are normalized to kebab-case keys via Utilities.toKebabCase (tag-blacklist). Use the same display name in createElement, getValue, and getField.


Field types and registration

Constant add* method Stored value type UI
CONFIG_TYPE_FLAG addFlagField(name, helpText) boolean Checkbox
CONFIG_TYPE_TEXT addTextField(name, helpText, defaultValue?) string Text input; empty → defaultValue on read
CONFIG_TYPE_NUMBER addNumberField(name, min, max, helpText) number Number input
CONFIG_TYPE_COLOR addColorField(name, helpText) color string Color input
CONFIG_TYPE_RANGE addRangeField(name, min, max, helpText) { minimum, maximum } Two number inputs
CONFIG_TYPE_SELECT addSelectField(name, pairs, helpText) option value See known limitation in spec
CONFIG_TYPE_CHECKBOXES_GROUP addCheckboxesGroup(name, pairs, helpText) string[] of checked data-values Checkbox group
CONFIG_TYPE_RADIOS_GROUP addRadiosGroup(name, pairs, helpText) selected data-value Radio group
CONFIG_TYPE_RULESET addRulesetField(name, rows, helpText, onTranslate?, onFormat?, onOptimize?, sortRules?) string[] lines Textarea
CONFIG_TYPE_BOOKMARKS addBookmarksField(name, helpText, options?) array (self-managed on gm) Bookmarks panel
CONFIG_TYPE_LEDGER addLedgerField(name, options?) self-managed id set (not in aggregate blob) No UI — GM-backed duplicate ledger

All add* methods return this (fluent). Chain attachStorage('local'|'gm') after any add*Field to assign a non-default driver (default: local).

Ruleset pipeline

On Apply/Save (setFromUserInterface):

  1. Split textarea by REGEX_LINE_BREAK; trim empty lines.
  2. Optional sortRules: true — locale-aware sort.
  3. onTranslateFromUI(values) — normalize (optional).
  4. Deduplicate individual rules (case-sensitive; first occurrence kept). Refreshes the textarea when duplicates are removed.
  5. onOptimize(values) — store result in field.optimized (filters read this at runtime).

On interface refresh (updateUserInterface):

  • onFormatForUI(value) → join with \n for textarea display.

addTagRulesetField(key, useSelectors, rows, helpText?, formatter?, sortRules?) wraps addRulesetField with default onOptimize_optimizeTagRuleset.

Per-rule field API

Every ruleset field exposes methods for programmatic add/remove without going through the textarea. Callers get the field via getField(name) and invoke these directly; side effects (save(), compliance refresh, UI refresh elsewhere) remain the caller's responsibility.

Method Role
onMatchRule(storedRule, target) Optional matcher callback; default is strict equality (storedRule === target)
setRules(lines) Canonical write: onTranslateFromUI → optional sortRulesvalueonOptimizeupdateUserInterface
findRuleIndex(target) Index of first matching rule, or -1
hasRule(target) Membership test via onMatchRule
addRule(rule, target?) Upsert: remove matches for target (defaults to rule), append rule, then setRules
removeRule(target) Drop all matches, then setRules
toggleRule(rule, target?) Add or remove via hasRule
clearRules() setRules([])

setRules does not deduplicate (preserves programmatic edits); setFromUserInterface (Apply/Save) still deduplicates via _deduplicateRulesetRules.

Tag rule syntax (one rule per line):

  • & — AND (all tags in segment must match)
  • | — OR within a segment
  • // — comment suffix (ignored after split)

Optimized output: array of arrays (each inner array = one conjunctive rule). Sorted shortest-first.


addBookmarksField

addBookmarksField('Bookmarks', 'Add pages you visit often.', {
  storageKey: 'myscript-bookmarks',  // default: {scriptPrefix}bookmarks
  storage: 'gm',                     // default
  normalizeBookmarks: (stored) => /* sanitize array */,
  showAddButton: true,
  pageMatch: { getCurrentUrl, normalizeUrl, onMatchChange, watchSelectors, isActive },
  onAdd, onSort, onRemove(id), onNavigate(url),
  getRowActions(bookmark),  // optional → HTMLElement[] | JQuery[]
})
Behaviour Detail
persist false — not in aggregate blob; dedicated GM key via GmStorageDriver
storage 'gm' by default
Field API reload(), save(), serializeForBackup(), applyFromBackup() (replace on restore)
widget BrazenBookmarksPanel from createBookmarksPanel
setFromUserInterface No-op — mutations call field.save() from site handlers
updateUserInterface reload() then widget.render(value)

DOM binding: createElement

this._configurationManager.createElement('My Setting')  // display name

Invokes the field's createElement() which:

  1. Builds View Layer DOM.
  2. Stores jQuery reference on field.element.
  3. Returns the mountable node (input group or section).

Fields without createElement called remain memory-only until mounted.

Each field implements:

Callback When
createElement() First mount
setFromUserInterface() Apply/Save — read DOM → field.value (+ ruleset optimize)
updateUserInterface() Load/reset/tab switch — write field.value → DOM

Reading values

this._configurationManager.getValue('My Setting')
this._configurationManager.getField('My Setting')       // ConfigurationField | null
this._configurationManager.getFieldOrFail('My Setting') // throws if missing
this._configurationManager.hasField('My Setting')

ConfigurationField properties: title, type, element, value, optimized?, helpText, minimum, maximum, options, persist, widget, ruleset callbacks.


Persistence

Each field has a storage driver key (local by default). Simple fields persist in a per-driver aggregate blob; self-managed types (persist: false, e.g. ledger, bookmarks) use driver primitives directly and participate in backup v2 when they implement serializeForBackup.

Store Driver Key Content
Settings local {scriptPrefix}settings JSON object: kebab keys → values (skips persist: false)
Sync id local {scriptPrefix}settings-id { id: number } — bumps on save
Settings gm {scriptPrefix}settings Same shape in GM namespace (lazy; only when a field uses gm)
Sync id gm {scriptPrefix}settings-id Same in GM namespace

initialize()

  1. Creates the local driver stores (LocalStore).
  2. _syncDriverStores('local') — merge disk into fields; rulesets run onOptimize.
  3. onChange on settings store → updateInterface().
  4. visibilitychange — if tab visible and local id changed, re-sync + onExternalConfigurationChange.

Save / apply / restore

Method Behaviour
update() All mounted fields: setFromUserInterface() (rulesets: trim → optional sort → onTranslateFromUI → dedupe rules case-sensitively → onOptimize)
save() update() → write store → bump sync id
revertChanges() Re-read store into fields + updateInterface()
updateInterface() All mounted fields: updateUserInterface()

Framework button wiring:

  • Applyupdate() + re-run compliance (no disk).
  • Save — apply + save().
  • ResetrevertChanges() + compliance.

Backup format (v2)

backup() downloads {scriptPrefix}backup.json:

{
  "version": 2,
  "id": 123456789,
  "drivers": {
    "local": {
      "tag-blacklist": ["rule1", "rule2"],
      "pagination-threshold": 20
    },
    "gm": {
      "download-ledger": { "postIds": ["123", "456"] },
      "bookmarks": [{ "id": "…", "label": "…", "tags": "…", "url": "…" }]
    }
  }
}

Legacy flat backups (no version / drivers) still import as local values.

restore(response)fetch/Response with JSON body; each field's applyFromBackup handles semantics (ledger merges ids; bookmarks replace list); restores values + sync id; alerts success/failure. Legacy v1 backups without a bookmarks key leave local bookmarks untouched.

Cross-tab sync

onExternalConfigurationChange(handler)(manager) => void when another tab saved. Framework registers compliance re-run.


Validation helper

generateValidationCallback(configKey) → default enable checks:

Type Active when
flag / radios / select truthy value
checkboxes length > 0
number value > 0
range `minimum > 0 \
ruleset / text length > 0

Used by framework _addItemComplianceFilter when no custom validate callback is supplied.


Integration checklist

  1. Register all fields before init() builds UI.
  2. Use stable English labels — they appear in the panel and backup JSON keys.
  3. Mount with createElement inside tab panels.
  4. Pair enable flags with filters (addFlagField + ruleset).
  5. Self-managed fields (addLedgerField, addBookmarksField) use dedicated driver keys — no ad-hoc GM_setValue in apps.
  6. Set #bv-ui userScript reference if tabs need updateInterface from custom widgets.

Next in stack: Item Attributes Resolver (before Framework core).