Sleazy Fork is available in English.

Brazen Framework - View Layer

View layer for the Brazen user scripts framework

Устаревшая версия за 13.07.2026. Перейдите к последней версии.

Этот скрипт недоступен для установки пользователем. Он является библиотекой, которая подключается к другим скриптам мета-ключом // @require https://update.sleazyfork.org/scripts/416104/1875150/Brazen%20Framework%20-%20View%20Layer.js

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey, Greasemonkey или Violentmonkey.

Для установки этого скрипта вам необходимо установить расширение, такое как Tampermonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Violentmonkey.

Чтобы установить этот скрипт, вы сначала должны установить расширение браузера, например Tampermonkey или Userscripts.

Чтобы установить этот скрипт, сначала вы должны установить расширение браузера, например Tampermonkey.

Чтобы установить этот скрипт, вы должны установить расширение — менеджер скриптов.

(у меня уже есть менеджер скриптов, дайте мне установить скрипт!)

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение браузера, например Stylus.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

Чтобы установить этот стиль, сначала вы должны установить расширение — менеджер стилей.

(у меня уже есть менеджер стилей, дайте мне установить скрипт!)

Автор
brazenvoid
Версия
3.4.1
Создано
14.11.2020
Обновлено
13.07.2026
Размер
48,4 КБ
Лицензия
GPL-3.0-only

Brazen Framework — View Layer (developer guide)

Shared settings panel UI: #bv-ui, tabs, form controls, modals, bookmarks panel, compliance statistics widgets, and tag-sidebar enhancements. Apps and other framework modules use this as a UI “toolbox” to build a consistent panel without per-site UI code.

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

Styles ship inlined at runtime via GM_addStyle when this module loads. Requires @grant GM_addStyle on this script or the app.


When to use / when not to use

  • Use this module when you need to build (or extend) the Brazen settings panel: layout sections, tabs, form groups, action rows, statistics labels, modals, or the bookmarks UI.
  • Don’t use this module to persist settings — that’s the Configuration Manager.
  • Don’t build custom DOM for settings fields unless you have to. Prefer defining fields in Configuration Manager and mounting them via createElement(...).

Quick start

In most apps you don’t “build the panel from scratch”; the framework embeds #bv-ui, and you mount your fields and extra widgets into tab panels.

// In your app (extending BrazenFramework), you compose nodes during the framework UI build
// (e.g. via _onBeforeUIBuild / _onAfterUIBuild):
this._userInterface = [
  this._uiGen.createTabsSection(['Filters', 'Downloads'], [
    this._uiGen.createTabPanel('Filters', true).append([
      this._configurationManager.createElement('Tag Blacklist'),
    ]),
    this._uiGen.createTabPanel('Downloads').append([
      /* app-specific controls */
    ]),
  ]),
  this._uiGen.createBottomSection([
    this._uiGen.createStatisticsTotalsGroup(),
  ]),
]

Constructor

const uiGen = new BrazenViewLayer(scriptPrefix)

scriptPrefix feeds SelectorGenerator for stat label element ids.


Features

Panel lifecycle and embed behavior

What it does: Creates the root panel (#bv-ui), the show/hide controls, and the resize handle used by the framework’s _embedUI step.

How it behaves (developer-relevant):

  • The panel is hidden by default, and revealed by the left-edge show strip.
  • The framework schedules an auto-hide on mouseleave unless resizing or Always Show Settings Pane is enabled.
  • The resize handle enforces a minimum width (150px).

APIs:

Factory / method Role
createSettingsSection() Root #bv-ui section (hidden by default); includes #bv-resizer
createSettingsShowButton(caption, settingsSection) Left-edge .bv-show-settings strip; slideDown(300) on click
createSettingsHideButton() << Hide — sets panel display: none
getSelectedSection() Returns the container from createContainer() / createSettingsSection()
isSettingsPaneBeingResized() true while #bv-resizer drag is active
createResizer() Width drag handle (min width 150px)

Framework _embedUI:

  • Appends panel + show strip to body.
  • mouseleave on panel schedules a 1 s hide; re-entering the panel cancels it. After the delay, slides up (300 ms) unless resizing or Always Show Settings Pane is on.
  • When always-show is enabled, panel is shown immediately.

userScript on #bv-ui: Tab buttons call root.userScript._configurationManager.updateInterface(). Set getSelectedSection()[0].userScript = this in _onAfterUIBuild so custom widgets can reach the app instance.


Layout factories (sections, titles, separators)

What it does: Provides simple building blocks for consistent panel layout.

Method Returns Notes
appendToBody(nodes) Static. Appends jQuery nodes to body
createContainer() JQuery <section class="bv-section bv-font-primary">
createBottomSection(children) JQuery .bv-bottom-section footer column
createTitle(title) JQuery .bv-title label
createSeparator() JQuery <hr/>
createBreakSeparator() JQuery <br class="bv-break"/>
createFormSection(title) JQuery Titled block with inner .bv-title

Form building blocks (labels, inputs, actions)

What it does: Creates consistent “form group” markup. Configuration Manager fields use these factories when you mount a field via createElement.

Method Returns Notes
createFormGroup() JQuery .bv-group row
createFormGroupLabel(label, inputType?) JQuery .bv-label; adds : for text/number
createFormGroupInput(type) JQuery .bv-input; adds .bv-text or .bv-checkbox-radio
createFormInputGroup(label, type, hoverHelp?) JQuery Label + single input
createFormRangeInputGroup(label, type, min, max, help?) JQuery .bv-range-group with two inputs (min/max)
createFormTextAreaGroup(label, rows, help?) JQuery .bv-textarea-group
createFormCheckBoxesGroupSection(label, pairs, help?) JQuery .bv-checkboxes-group; data-value on each input
createFormRadiosGroupSection(label, pairs, help?) JQuery .bv-radios-group; mutual exclusive on change
createFormGroupDropdown(id, pairs) JQuery <select class="bv-input"> — use directly if needed
createFormButton(caption, hoverHelp, onClick) JQuery .bv-button
createFormActions(children, wrapperClasses?) JQuery .bv-actions button row

Configuration Manager uses these factories via each field's createElement binding.


Tabs (nav + panels)

What it does: Builds a tabbed section used by most scripts to separate Filters / Options / Downloads etc.

Critical rule: createTabPanel(tabName) sets the panel id to Utilities.toKebabCase(tabName). Your tab button text must match the panel id after kebab-casing (e.g. "My Filters"id="my-filters").

Method Notes
createTabsSection(tabNames[], tabPanels[]) .bv-tabs-section with nav + panels
createTabButton(tabName, isFirst) .bv-tab-button; first tab gets .bv-active
createTabPanel(tabName, isFirst?) .bv-tab-panel; id = Utilities.toKebabCase(tabName)

Critical: Tab button label text must kebab-case to the panel id. Example: button "My Filters" → panel id="my-filters". Active panel gets .bv-active (display: flex).

On tab click: deactivates other buttons/panels, activates matching #kebab-tab-name, calls updateInterface() on linked userScript.


Statistics widgets (filter hide counts)

What it does: Provides UI nodes that StatisticsRecorder updates to show how many items each filter removed.

Method Notes
createFormGroupStatLabel(statisticType) <label class="bv-stat-label"> with id from SelectorGenerator.getStatLabelSelector
createStatisticsFormGroup(statisticType, label?) .bv-stat-group; when label is omitted, humanizes kebab-case statisticType and appends Filter
createStatisticsTotalsGroup() Total row wired to Total stat key

Pair statisticType with framework filter config keys passed to StatisticsRecorder.record.


Modals

What it does: Creates a consistent modal dialog with overlay, close controls, and Escape-to-close wiring.

let modal = this._uiGen.createModal('Title', bodyNodes)  // bodyNodes: JQuery | JQuery[]
this._uiGen.showModal(modal)
this._uiGen.hideModal(modal)
Behaviour Detail
Overlay .bv-modal-overlay; click outside closes
Close control .bv-modal-close button
Escape keydown.bvModal on document
Compliance lists .bv-compliance-rule-list, .bv-compliance-rule-row, .bv-compliance-rule-label, .bv-compliance-rule-remove

createModal builds .bv-modal-dialog > header (.bv-modal-title) + .bv-modal-body.


Bookmarks panel

What it does: A reusable bookmarks UI component (search, sort, add/remove, optional per-row actions, and optional “current page bookmarked?” state).

Typical use case: Use via Configuration Manager addBookmarksField(...), which handles persistence and wires render(...).

createBookmarksPanel(options?)BrazenBookmarksPanel

Options (BrazenBookmarksPanelOptions)

Option Default Role
showAddButton true Show add button above list
addCaption 'Add Bookmark' Add button text
addHelpText '' Add button tooltip
searchPlaceholder 'Search bookmarks…' Filter input placeholder
searchHelpText Filter tooltip
sortHelpText Sort tooltip
emptyMessage 'No bookmarks yet.' No bookmarks state
noMatchMessage 'No matching bookmarks.' Filter miss state
onAdd / onSort / onRemove(id) / onNavigate(url) callbacks onNavigate defaults to location.href = url
getRowActions(bookmark) () => [] Optional extra buttons per row (see .bv-bookmark-main, .bv-bookmark-action)
pageMatch optional Current-page bookmark detection (below)

pageMatch (BrazenBookmarksPageMatchOptions)

Option Role
getCurrentUrl() URL to compare (default location.href)
normalizeUrl(url) Trim/normalize before compare
onMatchChange(isBookmarked) Called when match state changes
watchSelectors[] Re-check on input events
isActive() If returns false, forces onMatchChange(false)

Panel API (BrazenBookmarksPanel)

Method Role
element Root .bv-bookmarks-group jQuery node
render(bookmarks[]) BrazenBookmarkEntry[]{ id, label, tags, url }
getFilterQuery() Current search string
isCurrentPageBookmarked(url?) Compare normalized URL to list
checkPageMatch() Refresh pageMatch state

Wired by Configuration Manager addBookmarksField — self-managed on the gm driver (reload / save, included in backup v2).


Tag sidebar enhancement: enhanceTagSidebarCounts

What it does: Enhances a tag sidebar by wrapping the “count” span in a hover-reveal actions slot (e.g. bookmark/add-to-rule buttons).

enhanceTagSidebarCounts(options?) — wraps tag count spans with hover-reveal action slots.

Option Default
sidebarSelector '#tag-sidebar'
rowSelector 'li[class*="tag-type-"]'
countSelector 'span.tag-count'
hideDelayMs 2000 (0 if prefers-reduced-motion)
extractTag(row) () => ({ name: '' })
renderActions(row, tag, actionsEl, ctx) ctx.isBookmarked from isBookmarked(tagName)
isBookmarked(name) () => false

DOM: .bv-tag-actions-slot wraps count; .bv-tag-actions shown on pointer enter; count hidden while actions visible; .bv-tag-row-active on row.


Download pattern token builder

What it does: Shared “token chip” UI to help users build filename/subfolder patterns by clicking tokens and separators into focused inputs.

When to call it: Typically from _onAfterUIBuild, after your Downloads tab exists in the DOM.

Shared chip UI for filename/subfolder pattern fields:

Method Role
createPatternTokenChip(chip) One token/separator button
createSharedPatternTokenBuilder(sections, separators) Full builder panel (.bv-pattern-builder-shared)
insertIntoPatternInput(input, text) Insert at caret with flash feedback
patchPatternTokenBuilder(filenameInput, subfolderInput, builder, eventNamespace?) Wire focus + click handlers
patchStackedPatternFieldGroups(configurationManager, configKeys) Add .bv-pattern-group to folder/pattern fields
patchRangeInputLayout() Wrap paired range inputs in .bv-range-inputs

Call patchPatternTokenBuilder from _onAfterUIBuild after the Downloads tab is in the DOM.


CSS class vocabulary

What it is: The stable class/id set the view layer uses. This is mainly useful when you write custom CSS or build custom widgets that should visually match the built-ins.

Class / id Role
#bv-ui Main settings panel
#bv-resizer, #bv-resizer-icon Width handle
.bv-show-settings / .show-settings Left reveal strip
.bv-section, .bv-bg-colour, .bv-font-primary Panel chrome
.bv-tab-button, .bv-tab-panel, .bv-tabs-nav, .bv-tabs-section Tabs
.bv-active Active tab button or panel
.bv-group, .bv-label, .bv-input, .bv-button, .bv-actions Form
.bv-checkboxes-group, .bv-radios-group, .bv-range-group, .bv-textarea-group Group layouts
.bv-stat-group, .bv-stat-label Statistics
.bv-pattern-builder, .bv-pattern-builder-shared, .bv-token-row, .bv-token-bar, .bv-token-btn, .bv-token-sep, .bv-pattern-group, .bv-pattern-active, .bv-range-inputs Pattern token builder
.bv-bookmarks-group, .bv-bookmark-* Bookmarks UI
.bv-modal-overlay, .bv-modal-dialog, .bv-modal-* Modals
.bv-compliance-rule-* Compliance rule modal rows
.bv-tag-actions-slot, .bv-tag-actions, .bv-tag-row-active Sidebar tag actions

Typical composition

this._userInterface = [
  this._uiGen.createTabsSection(['Filters', 'Options'], [
    this._uiGen.createTabPanel('Filters', true).append([
      this._configurationManager.createElement('Tag Blacklist'),
    ]),
    this._uiGen.createTabPanel('Options').append([/* ... */]),
  ]),
  this._uiGen.createBottomSection([
    this._uiGen.createStatisticsTotalsGroup(),
    this._uiGen.createSettingsFormActions(), // from framework helper
  ]),
]

Next in stack: Configuration Manager


Public API reference (index)

  • Panel: createSettingsSection, createSettingsShowButton, createSettingsHideButton, createResizer, isSettingsPaneBeingResized, getSelectedSection
  • Layout: appendToBody, createContainer, createBottomSection, createTitle, createSeparator, createBreakSeparator, createFormSection
  • Forms: createFormGroup*, createFormInputGroup, createFormRangeInputGroup, createFormTextAreaGroup, createFormCheckBoxesGroupSection, createFormRadiosGroupSection, createFormGroupDropdown, createFormButton, createFormActions
  • Tabs: createTabsSection, createTabButton, createTabPanel
  • Statistics: createFormGroupStatLabel, createStatisticsFormGroup, createStatisticsTotalsGroup
  • Modals: createModal, showModal, hideModal
  • Bookmarks: createBookmarksPanel (and BrazenBookmarksPanel methods)
  • Sidebar: enhanceTagSidebarCounts
  • Pattern builder: createPatternTokenChip, createSharedPatternTokenBuilder, insertIntoPatternInput, patchPatternTokenBuilder, patchStackedPatternFieldGroups, patchRangeInputLayout

Integration notes (grants, load order, pitfalls)

  • Grant: requires @grant GM_addStyle on this script or the app (styles are injected when this module loads).
  • Load order: after Utilities, before Configuration Manager.
  • Pitfall: tab ids are kebab-cased. If a tab doesn’t switch correctly, check that the tab button text and the panel id match after Utilities.toKebabCase(...).