Brazen Framework - Configuration Manager

Configuration management for the Brazen user scripts framework

이 스크립트는 직접 설치하는 용도가 아닙니다. 다른 스크립트에서 메타 지시문 // @require https://update.greasyfork.org/scripts/418665/1847371/Brazen%20Framework%20-%20Configuration%20Manager.js을(를) 사용하여 포함하는 라이브러리입니다.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

작성자
brazenvoid
버전
2.3.0
생성일
2020-12-15
갱신일
2026-06-10
크기
20.7KB
라이선스
GPL-3.0-only

Brazen Framework — Configuration Manager (developer guide)

Typed settings schema, localStorage persistence, 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 localStorage keys
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, handlers) array (not persisted) Bookmarks panel

All add* methods return this (fluent).

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.

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.', {
  load: () => /* array from GM_setValue */,
  showAddButton: true,
  pageMatch: { getCurrentUrl, normalizeUrl, onMatchChange, watchSelectors, isActive },
  onAdd, onSort, onRemove(id), onNavigate(url),
})
Behaviour Detail
persist false — excluded from localStorage backup object
widget BrazenBookmarksPanel from createBookmarksPanel
setFromUserInterface No-op
updateUserInterface Calls handlers.load() 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

Store Key Content
Settings {scriptPrefix}settings JSON object: kebab keys → values (skips persist: false)
Sync id {scriptPrefix}settings-id { id: number } — bumps on save

initialize()

  1. Creates both LocalStore instances.
  2. _syncLocalStore() — merge disk into fields; rulesets run onOptimize.
  3. onChange on settings store → updateInterface().
  4. visibilitychange — if tab visible and 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

backup() downloads {scriptPrefix}backup.json:

{
  "tag-blacklist": ["rule1", "rule2"],
  "pagination-threshold": 20,
  "id": 123456789
}

restore(response)fetch/Response with JSON body; restores values + sync id; alerts success/failure.

Not included: GM_setValue data (bookmarks, download ledger) unless stored in a persisted config field.

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. Document keys stored outside backup (persist: false, GM_setValue).
  6. Set #bv-ui userScript reference if tabs need updateInterface from custom widgets.

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