Brazen Framework - Framework

Main class of the Brazen framework

Questo script non dovrebbe essere installato direttamente. È una libreria per altri script da includere con la chiave // @require https://update.sleazyfork.org/scripts/416105/1847303/Brazen%20Framework%20-%20Framework.js

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

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

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

Autore
brazenvoid
Versione
7.2.1
Creato il
14/11/2020
Aggiornato il
09/06/2026
Dimensione
46 KB
Licenza
GPL-3.0-only

Brazen Framework — Core (developer guide)

Extend BrazenFramework to build a site userscript. The core owns init order, compliance hiding, filter registration, download queueing, statistics, and shared constants.

Greasy Fork: Framework core · Changelog: append sections from BrazenFramework.changelog.md when publishing.

Sibling modules: UtilitiesView LayerConfiguration ManagerItem Attributes Resolver → optional Paginator / Subscriptions Loaderthis script → your app.


Constructor config

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 undefined Pause between GM_download queue items (ms)
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, Always Show Settings Pane.


Module constants

CSS classes

Constant Value
CLASS_COMPLIANT_ITEM brazen-compliant-item
CLASS_NON_COMPLIANT_ITEM brazen-noncompliant-item

Paginator config keys

Constant Display name
CONFIG_PAGINATOR_THRESHOLD Pagination Threshold
CONFIG_PAGINATOR_LIMIT Pagination Limit

Preset filter keys

Constant Display name
FILTER_DURATION_RANGE Duration
FILTER_PERCENTAGE_RATING_RANGE Rating
FILTER_UNRATED Unrated
FILTER_TAG_BLACKLIST Tag Blacklist
FILTER_TEXT_BLACKLIST Blacklist
FILTER_TEXT_SEARCH Search
FILTER_TEXT_SANITIZATION Text Sanitization Rules
FILTER_TEXT_WHITELIST Whitelist
FILTER_SUBSCRIBED_VIDEOS Hide Subscribed Videos

Option flags

Constant Display name
OPTION_DISABLE_COMPLIANCE_VALIDATION Disable All Filters
OPTION_ENABLE_TEXT_BLACKLIST Enable Text Blacklist
OPTION_ENABLE_TAG_BLACKLIST Enable Tag Blacklist
OPTION_ALWAYS_SHOW_SETTINGS_PANE Always Show Settings Pane
OPTION_ENABLE_DOWNLOAD_DUPLICATE_LEDGER Skip Duplicate Downloads

Item attributes

Constant Normalized key
ITEM_NAME name
ITEM_PROCESSED_ONCE processed_once

Other

Constant Role
STORE_SUBSCRIPTIONS Account Subscriptions text field
ICON_RECYCLE &#x267B recycle symbol
OPTION_ENABLE_DOWNLOAD_DUPLICATE_LEDGER_HELP Default ledger tooltip
DEFAULT_DOWNLOAD_DUPLICATE_LEDGER_MAX_ENTRIES 25000
DOWNLOAD_DUPLICATE_LEDGER_CONFLICT_ACTION 'overwrite' when ledger on

Lifecycle and init()

Runs only when _onValidateInit() is truthy (assign a function returning false to skip init on wrong pages).

configurationManager.initialize()
→ addAttribute(processedOnce); addAttribute(name) if itemNameSelector set
→ paginator.initialize() (if configured)
→ _onBeforeUIBuild[]
→ build #bv-ui (unless _disableUI)
→ _onAfterUIBuild[]
→ configurationManager.updateInterface()
→ _validateCompliance(true) + ChildObserver on lists
→ _onAfterInitialization[]

Hook arrays

Push callbacks in the subclass constructor before init().

Hook Type When
_onValidateInit single fn Before any init; return false to abort
_onBeforeUIBuild [] Register filters, styles, auto-download
_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.

Protected members apps use

Member Role
_configurationManager Settings schema
_uiGen BrazenViewLayer
_itemAttributesResolver Per-tile metadata
_statistics StatisticsRecorder
_userInterface JQuery[] appended to settings section
_disableUI Skip panel when true
_paginator Set by _setupPaginator
_subscriptionsLoader Set by _setupSubscriptionLoader
_complianceRules ComplianceRuleRecorder when trackComplianceRules

Compliance pipeline

The framework hides non-compliant tiles and records statistics (counts = items removed).

_validateCompliance(firstRun)

  • firstRun: ChildObserver on each itemListSelectors node; paginated list also re-runs paginator on add.
  • Re-run: resets statistics (+ compliance rules); re-processes all items.
  • Ends with paginator.run(threshold, limit) and completeResolutionRun().

_complyItemsList(list, fromObserver)

  1. Select tiles (find vs children; observer mode merges added nodes).
  2. Fade to opacity: 0.75.
  3. First hit: sanitize name (if enabled), resolveAttributes, _onFirstHitBeforeCompliance.
  4. _complyItem.
  5. First completion: _onFirstHitAfterCompliance, set processedOnce.
  6. 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.

Filter registration helpers

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?) Tag ruleset + enable flag
`_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.

Config-driven comply (when 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).

Operation helpers

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

UI composition

this._userInterface = [
  this._uiGen.createTabsSection(['Filters', 'Downloads'], [
    this._uiGen.createTabPanel('Filters', true).append([
      this._configurationManager.createElement(FILTER_TAG_BLACKLIST),
      this._uiGen.createStatisticsFormGroup(FILTER_TAG_BLACKLIST),
    ]),
  ]),
  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

Downloads

Requires @grant GM_download on the application script.

this._addDownload(mediaElement, folder, filename, removeMediaOnSuccess?)
  • Serial queue; await Utilities.sleep(downloadsDelay) between tasks.
  • Path: folder truncated to 120 chars; illegal <>:"/\|?*-.
  • Pictures with removeMediaOnSuccess: capture URL, _removeDownloadMediaElement before enqueue.
  • Override _handleDownloadFailed, _handleDuplicateDownloadSkipped.

Download duplicate ledger

Optional constructor block; requires @grant GM_getValue and @grant GM_setValue.

downloadDuplicateLedger: {
  getDownloadId: (item) => stableId,
  storageKey: 'myapp-download-registry',
  primaryField: 'ids',
  legacyIdFields: ['legacyIds'],
  maxEntries: 25000,
  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)
Active _claimDownloadDuplicateLedgerSlot before GM_download; skip if duplicate
conflictAction 'overwrite' when ledger on; 'uniquify' when off
Persist GM_setValue rolling cap (maxEntries)
UI createElement(OPTION_ENABLE_DOWNLOAD_DUPLICATE_LEDGER)

Never use uniquify as the primary duplicate strategy when the ledger is enabled.

Protected helpers: _isDownloadDuplicateLedgerActive(), _getDownloadDuplicateLedgerId(item), _isDownloadDuplicate(id), _mergeDownloadDuplicateLedgerFromStorage().


Optional modules

this._setupPaginator(() => condition, { /* PaginatorConfiguration */ })
this._setupSubscriptionLoader()  // then addConfig + mount _createSubscriptionLoaderControls()

See Paginator and Subscriptions Loader developer guides.


Public methods

Method Role
init() Full startup (see lifecycle)
isUserLoggedIn() Returns config flag
registerHighlightStyleClass(styleClass) Accumulates highlight CSS classes

Protected accessors

this._get(item, attributeName)      // item resolver
this._getConfig(configDisplayName)  // configuration value

Publishing

  1. Bump @version on Greasy Fork and publish framework modules.
  2. Bump dependent apps and @require URLs.
  3. Append changelog to listing descriptions.
  4. Publish framework modules before apps that depend on new APIs.