Main class of the Brazen framework
Dit script moet niet direct worden geïnstalleerd - het is een bibliotheek voor andere scripts om op te nemen met de meta-richtlijn // @require https://update.sleazyfork.org/scripts/416105/1884337/Brazen%20Framework%20-%20Framework.js
Extend BrazenFramework to build a site userscript. The core owns init order, compliance hiding, filter registration, download queueing, statistics, and shared constants. Tiles, hooks, and UI are native HTMLElement (no jQuery on the active stack).
Greasy Fork: Framework core · Changelog: append sections from BrazenFramework.changelog.md when publishing.
Sibling modules: Utilities → View Layer → IndexedDB Storage → Configuration Manager → optional Tag Query Engine (includes Gelbooru-family adapter class) → optional Paginator / Subscriptions Loader → this script (includes Item Attributes Resolver) → optional Download Manager → your app.
BrazenFramework and let it own boot order, settings plumbing, UI embedding, and the compliance (filtering/hiding) pipeline.This is the smallest “shape” of a Brazen app: define config in the constructor, then call init() at document-end.
class MyApp extends BrazenFramework {
constructor() {
super({
scriptPrefix: 'myapp-',
itemListSelectors: ['#results'],
itemSelectors: '.thumb',
itemNameSelector: '.title',
itemLinkSelector: 'a',
itemDeepAnalysisSelector: '#content',
tagSelectorGenerator: null,
requestDelay: 0,
})
// Define your settings schema here (constructor only).
// Then use hooks below to register filters and build UI.
}
}
new MyApp().init()
Pass one object to super({ ... }):
| Key | Default | Purpose |
|---|---|---|
scriptPrefix |
(required) | localStorage + default ledger key prefix |
itemListSelectors |
(required) | List container(s) observed for new tiles |
itemSelectors |
(required) | Tile selector inside each list |
itemNameSelector |
(required) | Title node; '' disables built-in name attribute |
itemLinkSelector |
'' |
Link for Item Attributes Resolver deep fetch |
itemDeepAnalysisSelector |
'' |
Detail-page root selector for deep attrs |
itemSelectionMethod |
'find' |
'find' or 'children' — tile collection in lists |
itemWrapperResolver |
(item) => item |
Wrapper for show/hide and CSS classes |
tagSelectorGenerator |
null |
(tag) => selector for tag rules/highlights |
isUserLoggedIn |
false |
Gates subscription loader |
requestDelay |
0 |
ms throttle between deep attribute fetches |
downloadsDelay |
(removed v12) | Use downloadInitiationGapMs in Download Manager config |
doItemCompliance |
undefined | () => boolean — skip all compliance when falsy |
trackComplianceRules |
false |
Per-rule hide diagnostics modal |
downloadDuplicateLedger |
undefined | Optional duplicate skip (see below) |
Framework auto-registers config flags: Disable All Filters. Apps with UI enabled must call configureDock() (and implement composeDockRail) before UI embed.
What it does: The framework provides a stable, repeatable app structure:
init() lifecycle with “safe points” for page wiring and config-driven behavior#bv-ui) you populate with config fields and custom widgetsThe big rule: define configuration fields in the constructor only; do page detection, UI mounting, and filter registration in lifecycle hooks.
| Constant | Value |
|---|---|
CLASS_COMPLIANT_ITEM |
brazen-compliant-item |
CLASS_NON_COMPLIANT_ITEM |
brazen-noncompliant-item |
| Constant | Key (stable) | Title (UI label) |
|----------|--------------|
| CONFIG_PAGINATOR_THRESHOLD | pagination-threshold | Pagination Threshold |
| CONFIG_PAGINATOR_LIMIT | pagination-limit | Pagination Limit |
| Constant | Key (stable) | Title (UI label) |
|----------|--------------|
| FILTER_DURATION_RANGE | duration | Duration |
| FILTER_PERCENTAGE_RATING_RANGE | rating | Rating |
| FILTER_UNRATED | unrated | Unrated |
| FILTER_TAG_BLACKLIST | tag-blacklist | Tag Blacklist |
| FILTER_TEXT_BLACKLIST | blacklist | Blacklist |
| FILTER_TEXT_SEARCH | search | Search |
| FILTER_TEXT_SANITIZATION | text-sanitization-rules | Text Sanitization Rules |
| FILTER_TEXT_WHITELIST | whitelist | Whitelist |
| FILTER_SUBSCRIBED_VIDEOS | hide-subscribed-videos | Hide Subscribed Videos |
| Constant | Key (stable) | Title (UI label) |
|----------|--------------|
| OPTION_DISABLE_COMPLIANCE_VALIDATION | disable-all-filters | Disable All Filters |
| OPTION_ENABLE_TEXT_BLACKLIST | enable-text-blacklist | Enable Text Blacklist |
| OPTION_ENABLE_TAG_BLACKLIST | enable-tag-blacklist | Enable Tag Blacklist |
| OPTION_ENABLE_DOWNLOAD_DUPLICATE_LEDGER | skip-duplicate-downloads | Skip Duplicate Downloads |
| OPTION_HIDE_DOWNLOADED_MEDIA | hide-downloaded-media | Hide Downloaded Media |
| Constant | Normalized key |
|---|---|
ITEM_NAME |
name |
ITEM_PROCESSED_ONCE |
processed_once |
| Constant | Role |
|---|---|
STORE_SUBSCRIPTIONS |
account-subscriptions — Account Subscriptions text field |
ICON_RECYCLE |
♻ recycle symbol |
OPTION_ENABLE_DOWNLOAD_DUPLICATE_LEDGER_HELP |
Default ledger tooltip |
OPTION_HIDE_DOWNLOADED_MEDIA_HELP |
Default hide-downloaded tooltip |
DOWNLOAD_DUPLICATE_LEDGER_CONFLICT_ACTION |
'overwrite' (legacy constant; Download Manager always overwrites) |
init() (where to put your code)init() runs a three-phase boot pipeline. When a dock is configured, a migrating dock (script name + spinner, no buttons, 50% viewport width) is painted before IndexedDB initialize() so long schema/data migrations stay visible; showDockMigrationStatus / hideDockMigrationStatus / setForceDockMigrationStatus control that chrome.
Phase 0 (always): detect active pages + resolve layout-aware selectors
Phase 1 (always): run addPageOperation handlers for active pages; halt skips Phase 2
Phase 2 (gated): full init when (init-set page active OR no pages defined) AND _onValidateInit()
When the subclass defines no pages, Phase 0/1 are no-ops and the gate is just _onValidateInit() (default () => true) — unmigrated scripts keep working.
_onBeforeFullInit[] // page-aware UI/event wiring (subclass)
→ paint migrating dock (if dock configured)
configurationManager.initialize({ onMigrationStatus })
→ downloadManager.initialize() (if configured; tag-discovery restore deferred)
→ load dock orientation; addAttribute(processedOnce); addAttribute(name) if itemNameSelector set
→ paginator.initialize() (if configured)
→ _onBeforeUIBuild[]
→ build #bv-ui + dock (unless _disableUI); re-show migrating chrome if force flag set
→ _onAfterUIBuild[]
→ configurationManager.updateInterface()
→ downloadManager.restoreTagDiscoveryPanelIfNeeded() (if configured; after dock exists)
→ _validateCompliance(true) + ChildObserver on lists (when compliance enabled + page allowed)
→ _onAfterInitialization[]
Storage-safety: register all config fields unconditionally in the constructor. Use _forPage / lifecycle hooks for page-specific behaviour only — save() replaces the whole settings blob.
Phase 1 operations (addPageOperation) must be config-independent (reload, redirect). Config-dependent work belongs in _onBeforeUIBuild via _forPage (after config load).
What it does: Lets one script support multiple “pages” (search, details, favorites, etc.) without scattering if (...) checks.
How it works (developer-relevant):
init() (Phase 0).addPageOperation(...) for Phase 1 actions that may redirect/reload and optionally halt full init._forPage(...) from Phase 2 hooks to do page-aware setup after config is loaded.Declare pages in the subclass constructor with definePage / definePages. Detectors run once at the start of init() (Phase 0), not in the constructor — use _onBeforeFullInit or _forPage during Phase 2 for page-aware wiring.
| Method | Role |
|---|---|
definePage(name, detectFn) / definePages({...}) |
Register named pages |
isPage(name) / anyPage(...names) |
Query cached active pages |
getActivePages() / getLayout(name?) |
Active page names / layout variant |
addPageOperation(names, fn) |
Phase 1 boot handler; return truthy to halt full init |
setCompliancePages(names) |
Compliance runs only on listed pages (hard skip elsewhere) |
enableCompliance() / disableCompliance() |
Runtime compliance switch |
Protected linkage: _forPage(names, setup), _gatePage(names, callback), _performOperationOnPage, _performTogglableOperationOnPage.
Selector config values (itemListSelectors, etc.) may be a plain selector, a resolver function, or a {pageOrLayout: selector, default?: selector} map — resolved once in Phase 0.
What it does: You extend the framework by pushing callbacks into hook arrays (and optionally overriding _onItemHide). These hooks are where you register filters, mount UI, and wire site behavior.
Push callbacks in the subclass constructor before init(). Page-aware setup that calls _forPage or isPage must run from _onBeforeFullInit (or later hooks), not from the constructor.
| Hook | Type | When |
|---|---|---|
_onValidateInit |
single fn | Phase 2 gate; default () => true |
_onBeforeFullInit |
[] |
Start of Phase 2, before config load |
_onBeforeUIBuild |
[] |
After config load; register filters, styles, config-dependent auto-actions |
_onAfterUIBuild |
[] |
Patch DOM; set userScript on #bv-ui |
_onAfterInitialization |
[] |
After first compliance pass |
_onFirstHitBeforeCompliance |
[] |
Once per tile, before first _complyItem |
_onBeforeCompliance |
[] |
Every _complyItem, before filters |
_onFirstHitAfterCompliance |
[] |
Once per tile after first compliance |
_onAfterComplianceRun |
[] |
After full list pass |
_onItemShow |
[] |
Item passed filters (default: show + compliant class) |
_onItemHide |
single fn | Item failed (default: hide + noncompliant class) |
Override _onItemHide / push onto _onItemShow when tiles are nested (e.g. table cells) and the default wrapper hide is insufficient.
| Member | Role |
|---|---|
_configurationManager |
Settings schema |
_uiGen |
BrazenViewLayer |
_itemAttributesResolver |
Per-tile metadata |
_statistics |
StatisticsRecorder |
_userInterface |
HTMLElement[] appended to settings section |
_disableUI |
Skip panel when true |
_paginator |
Set by _setupPaginator |
_subscriptionsLoader |
Set by _setupSubscriptionLoader |
_complianceRules |
ComplianceRuleRecorder when trackComplianceRules |
BrazenItemAttributesResolver is defined in this script. Framework constructs one from itemLinkSelector, itemDeepAnalysisSelector, and requestDelay. Register extractors via this._itemAttributesResolver or read values with this._get(item, name).
Resolved values live on item.scriptAttributes (names lowercased, spaces → _).
| Registration | When it runs |
|---|---|
addAttribute(name, extractor) |
During resolveAttributes(item) on first compliance pass |
addAsyncAttribute(name, extractor) |
Not auto-invoked — custom/manual only |
addDeepAttribute(name, extractor) |
Lazy when get() misses and deep attrs exist |
Deep flow: throttled fetch of the detail page + DOMParser + querySelector(itemDeepAnalysisSelector); deep extractors receive the matched Element, then onDeepAttributesResolution (framework re-runs compliance).
Built-in framework attributes: ITEM_NAME / name (from itemNameSelector when set), ITEM_PROCESSED_ONCE / processed_once.
The framework hides non-compliant tiles and records statistics (counts = items removed).
_validateCompliance(firstRun)ChildObserver on each itemListSelectors node; paginated list also re-runs paginator on add.paginator.run(threshold, limit) and completeResolutionRun()._complyItemsList(list, fromObserver)find vs children; observer mode merges added nodes).opacity: 0.75.resolveAttributes, _onFirstHitBeforeCompliance._complyItem._onFirstHitAfterCompliance, set processedOnce.statistics.updateUI(), _onAfterComplianceRun._complyItem(item)Skips when doItemCompliance falsy or Disable All Filters on.
Otherwise: whitelist gate → _onBeforeCompliance → walk _complianceFilters (validate then comply, short-circuit on first fail) → show/hide → clear opacity.
Comply callbacks may return { complies: boolean, rule?: string } for trackComplianceRules.
| Method | Role |
|---|---|
_addItemBlacklistFilter(helpText, rows?) |
Text blacklist + enable flag; whole-word regex optimize |
_addItemWhitelistFilter(helpText) |
Whitelist gate (not in filter chain — runs in _validateItemWhiteList) |
_addItemTextSearchFilter(helpText?) |
Substring search on name |
_addItemTextSanitizationFilter(helpText) |
substitute=word,word rules; mutates title on first pass |
_addItemTagBlacklistFilter(attribute, useSelectors, rows?, help?, key?, optionKey?, dockTemplateName?) |
Tag ruleset + enable flag; default template tagBlacklist; pass a CM template name for other enables (e.g. exploredTags) |
_addItemHideDownloadedMediaFilter(getItemDownloadId, helpText?, optionKey?) |
Enable flag + hideDownloaded dock template + filter hiding tiles already in the ledger; claims when Skip or Hide is on |
| `_addItemDurationRangeFilter(selector\ | fn, help?, separator?)` |
_addItemPercentageRatingRangeFilter(selector, help?, unratedHelp?) |
Rating % + hide unrated flag |
_addItemTagHighlights(config) |
CSS highlight rules on tag sections |
_addItemTagAttribute(key, deep, saveSelectors, extractTags) |
Register tag list or selector string |
_addSubscriptionsFilter(exclusionsFn, getUsernameFn) |
Hide subscribed channels |
_addItemComplianceFilter(key, action?, validate?) |
Generic; action derived from field type if string |
_addItemComplexComplianceFilter(key, validate, comply) |
Explicit validate + comply |
Master bypass: OPTION_DISABLE_COMPLIANCE_VALIDATION.
Compliance modal: trackComplianceRules: true enables _showComplianceRulesModal(). Override _canRemoveComplianceRule / _removeComplianceRule for removable rule rows. _removeComplianceRule may return a Promise; the panel awaits it before refreshing. Override _getComplianceRuleColor for optional per-rule name colors (does not gate which rules appear).
action is attribute name string)| Field type | Comply logic |
|---|---|
| checkboxes | values.includes(attribute) |
| flag | attribute truthy or null passes |
| radios | value === attribute |
| range | Validator.isInRange(attribute, min, max) |
Default validate from generateValidationCallback(key).
| Method | Role |
|---|---|
_performOperation(key, action, validate?) |
Run action when validate passes |
_performComplexOperation(key, validate, action) |
Alias |
_performTogglableOperation(flagKey, key, action, validate?) |
Gated by flag field value |
_performTogglableComplexOperation(flagKey, key, validate, action) |
Gated complex variant |
Per-field ruleset add/remove/toggle is on the config object — see BrazenConfigurationManager ruleset field API (field.addRule, field.removeRule, field.hasRule, field.toggleRule, field.clearRules, field.setRules).
What it does: Your app sets this._userInterface to an array of HTMLElement nodes. The framework embeds #bv-ui and mounts your nodes into it.
Typical workflow:
_onBeforeUIBuild: register filters and config-dependent operations._onAfterUIBuild: patch DOM widgets, wire advanced UI, set userScript pointer on #bv-ui.let filtersPanel = this._uiGen.createTabPanel('Filters', true)
Utilities.appendChildren(filtersPanel, [
this._configurationManager.createElement(FILTER_TAG_BLACKLIST),
this._uiGen.createStatisticsFormGroup(FILTER_TAG_BLACKLIST, 'Tag Blacklist'),
])
this._userInterface = [
this._uiGen.createTabsSection(['Filters', 'Downloads'], [
filtersPanel,
]),
this._uiGen.createBottomSection([
this._uiGen.createStatisticsTotalsGroup(),
this._createSettingsFormActions(),
this._createSettingsBackupRestoreFormActions(),
]),
]
| Protected helper | Returns |
|---|---|
_createSettingsFormActions() |
Apply / Save / Reset |
_createSettingsBackupRestoreFormActions() |
Backup file + restore input |
_createPaginationControls() |
Threshold + limit fields |
_createSubscriptionLoaderControls() |
Load Subscriptions button |
createDonateTabPanel(options?) |
Donate tab panel (Patreon link + icon; thin wrapper over View Layer) |
createBehavioursTabPanel(options?) |
Behaviours tab for Download Manager flags (review-ignored-filename-pins, skip-empty-filename-pins, only-show-download-manager) when registered |
Requires @require Download Manager after this module and @grant GM_download on the Download Manager script (and typically the app).
Call configureDownloadManager(config) in the constructor after configureDock(). See the Download Manager developer guide for the full config shape (pages/roles, downloadPaths including extractTagIncidences, tagDiscovery, rateLimitHandlers with reopenLabel / humanInteraction, initiation gaps).
this.configureDock({ orientations: ['right'], scriptName: 'My App' })
this.configureDownloadManager({ /* see Download Manager guide */ })
Framework delegation (thin forwards to BrazenDownloadManager):
| Method | Role |
|---|---|
configureDownloadManager(config) |
Instantiate manager (requires dock first) |
getDownloadManager() |
Active instance or null |
handleMediaCloudflarePage(options?) |
Phase-1 Cloudflare / challenge page (silence or themed reload pane) |
downloadImmediate(options) |
Immediate GM_download |
enqueueDownload(context) / dequeueDownload(itemId) / isQueued(itemId) |
Resolution + download queues |
confirmTagDiscoveryMappings() |
Unblock tag review; promote or run pending immediate |
skipTagDiscoveryInclusion() |
Skip discovery — drop item without confirming types |
openTagDiscoveryMedia() |
Open media URL for item under review |
toggleDownloadManagerPaused() / clearDownloadQueue() |
Start/pause download queue; clear download queue only |
getDownloadManagerProgress() / getDownloadQueueCount() |
Dock progress and counter |
toggleTagDiscoveryMode() / toggleSelectionMode() / toggleCurrentMediaQueued() |
Dock mode toggles |
isDownloadPageRole(role) / isDashboardPage() / isDownloadManagerEnabled() / isDownloadManagerLeaderTab() / requestDownloadManagerLeadership() |
Page and leader checks / idle-only leader claim (isDashboardPage = DM dashboard role; no auto-claim) |
clearDownloadDuplicateLedger() |
Wipe ledger via Configuration Manager |
Framework-owned toggle for the current search page. Apps register a dock button and supply site config only — no local add/remove/alert handlers.
| Method | Role |
|---|---|
registerCurrentSearchBookmarkDock(actionKey, options?) |
Dock action field: click toggles, getState / tooltip from bookmark state; options: fieldKey, getCurrentUrl, getTags, formatLabel, normalizeUrl, include, tooltip strings |
toggleCurrentSearchBookmark(options?) |
Idempotent URL-keyed toggle (normalized URL identity; raw URL stored on add; empty tags = silent no-op; no alerts) |
isCurrentSearchBookmarked(options?) |
Whether the current URL is bookmarked (widget lastBookmarks or _bookmarkRows URL match) |
toggleTagSearchBookmark(tagName, options) / isTagSearchBookmarked(tagName, options) |
Single-tag search bookmarks (same optimistic write path; status = widget or _bookmarkRows) |
Both toggles share _toggleBookmarkAtUrl (optimistic row mutate + widget render + persist lock). Tag bookmark buttons and the dock bookmark refresh chrome immediately and again after persist settles so stars stay filled after a successful add. Wire pageMatch.onMatchChange to refresh dock button state when the bookmarks panel updates — Framework skips rail compose when the dock is not mounted yet (panel createElement / bookmark hydrate can run before _buildDock).
Path/token helpers (buildDownloadPathFromPatterns, substitution parsing, sanitizePathSegment, …) are on getDownloadManager() — removed from Framework in v12.
Immediate download tip: with removeMediaOnSuccess on pictures, capture the URL then clear src/srcset and detach the node before enqueue so the browser does not also decode a full-res bitmap — important for gallery auto-download RAM usage.
DOM polling: _waitForDomElement(selector, predicate, callback, options?) remains on Framework for elements not ready at document-end (e.g. video <source src>).
Override _handleDownloadFailed, _handleDownloadSucceeded, _handleDuplicateDownloadSkipped for failure/success/duplicate hooks.
Optional constructor block; requires @grant GM_getValue and @grant GM_setValue.
downloadDuplicateLedger: {
getDownloadId: (item) => stableId,
storageKey: 'myapp-download-registry',
primaryField: 'ids',
legacyIdFields: ['legacyIds'],
isValidId: (v) => typeof v === 'string' && v.trim().length > 0,
enableConfigKey: OPTION_ENABLE_DOWNLOAD_DUPLICATE_LEDGER,
enableHelpText: OPTION_ENABLE_DOWNLOAD_DUPLICATE_LEDGER_HELP,
enableDefault: true,
}
| Behaviour | Detail |
|---|---|
| Enable flag | Skip Duplicate Downloads (default on) — applyDockTemplate('skipDuplicates') at ledger init; apps only pushField it on the rail |
| Active | Claims run in Download Manager at download time when Skip or Hide is on; skip re-download only when Skip is on |
conflictAction |
Always 'overwrite' — user pattern filenames must not be uniquified |
| Persist | IndexedDB ledgerEntries via addLedgerField('download-ledger'); included in backup (merge on restore). No entry cap. |
| UI | Dock template + Hide Downloaded Media slide-out (DM setDockSlideOut); Toolbox Clear Download Ledger via clearDownloadDuplicateLedger(); full wipe via clearScriptDatabase() |
Never use uniquify. Filenames come from user patterns; GM_download must always overwrite.
Protected helpers: _isDownloadDuplicateLedgerActive(), _getDownloadDuplicateLedgerId(item), _isDownloadDuplicate(id), _reloadDownloadDuplicateLedgerFromStorage().
this._setupPaginator(() => condition, { /* PaginatorConfiguration */ })
this._setupSubscriptionLoader() // then addConfig + mount _createSubscriptionLoaderControls()
See Paginator and Subscriptions Loader developer guides.
| Method | Role |
|---|---|
init() |
Boot pipeline (see lifecycle) |
definePage / definePages |
Register named pages |
isPage / anyPage / getActivePages / getLayout |
Query active pages |
addPageOperation |
Phase 1 page-scoped boot handler |
enableCompliance / disableCompliance / isComplianceEnabled |
Runtime compliance switch |
setCompliancePages |
Restrict compliance to named pages |
isUserLoggedIn() |
Returns config flag |
registerHighlightStyleClass(styleClass) |
Accumulates highlight CSS classes |
This is the “jump table” for the APIs you’ll actually touch in apps:
init, definePage, definePages, isPage, anyPage, getActivePages, getLayout, addPageOperation, setCompliancePages, enableCompliance, disableCompliance, isComplianceEnabled_onValidateInit, _onBeforeFullInit[], _onBeforeUIBuild[], _onAfterUIBuild[], _onAfterInitialization[], _onFirstHitBeforeCompliance[], _onBeforeCompliance[], _onFirstHitAfterCompliance[], _onAfterComplianceRun[], _onItemShow[], _onItemHide_addItemBlacklistFilter, _addItemWhitelistFilter, _addItemTextSearchFilter, _addItemTextSanitizationFilter, _addItemTagBlacklistFilter, _addItemHideDownloadedMediaFilter, _addItemDurationRangeFilter, _addItemPercentageRatingRangeFilter, _addItemTagHighlights, _addItemTagAttribute, _addSubscriptionsFilter, _addItemComplianceFilter, _addItemComplexComplianceFilter_performOperation, _performComplexOperation, _performTogglableOperation, _performTogglableComplexOperationconfigureDownloadManager, getDownloadManager, handleMediaCloudflarePage, downloadImmediate, enqueueDownload, dequeueDownload, isQueued, confirmTagDiscoveryMappings, skipTagDiscoveryInclusion, openTagDiscoveryMedia, toggleDownloadManagerPaused, clearDownloadQueue, getDownloadManagerProgress, getDownloadQueueCount, toggleTagDiscoveryMode, toggleSelectionMode, toggleCurrentMediaQueued, isDownloadPageRole, isDashboardPage, isDownloadManagerEnabled, isDownloadManagerLeaderTab, requestDownloadManagerLeadership, clearDownloadDuplicateLedger — see Download Manager; _waitForDomElement on FrameworkregisterCurrentSearchBookmarkDock, toggleCurrentSearchBookmark, isCurrentSearchBookmarked, toggleTagSearchBookmark, isTagSearchBookmarked, createTagBookmarkActionButton, appendTagAttributeActions, refreshTagActionSurfaces_setupPaginator, _setupSubscriptionLoader_get(item, attributeName), _getConfig(configDisplayName)BrazenItemAttributesResolver): addAttribute, addAsyncAttribute, addDeepAttribute, resolveAttributes, get, set, completeResolutionRun via _itemAttributesResolverAll framework classes use a fixed 10-tier member order (static → fields → constructor → instance methods). When writing app-side subclasses or adding helper classes in your app, keep related helpers grouped within their tier. (The full maintainer table lives in the repository workspace documentation, not in the Greasy Fork paste.)
this._get(item, attributeName) // item resolver
this._getConfig(configDisplayName) // configuration value
@version on Greasy Fork and publish framework modules.@require URLs.GM_download. Apps may also grant GM_download, and GM_getValue/GM_setValue for legacy ledger import paths.save() writes a full settings blob, so conditional field registration will cause silent data loss.