View layer for the Brazen user scripts framework
Version vom
Dieses Skript sollte nicht direkt installiert werden. Es handelt sich hier um eine Bibliothek für andere Skripte, welche über folgenden Befehl in den Metadaten eines Skriptes eingebunden wird // @require https://update.sleazyfork.org/scripts/416104/1877283/Brazen%20Framework%20-%20View%20Layer.js
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.
createElement(...).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(),
]),
]
const uiGen = new BrazenViewLayer(scriptPrefix)
scriptPrefix feeds SelectorGenerator for stat label element ids.
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):
mouseleave unless resizing or Always Show Settings Pane is enabled.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:
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.userScript on #bv-ui: Optional app reference for widgets that need the host instance (getSelectedSection()[0].userScript = this in _onAfterUIBuild). Tab buttons only switch visible panels — they do not call updateInterface() (that would discard unsaved edits).
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 |
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.
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. Does not reload field values from storage.
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.
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 |
createModal builds .bv-modal-dialog > header (.bv-modal-title) + .bv-modal-body.
Dock-list panels (tag discovery, compliance rules, human interaction) share .bv-dock-list-* chrome (intro, groups, rows, name/meta, footer).
What it does: Dock-anchored slide panels that stack beside the rail — settings (#bv-ui), compliance rules, tag discovery, and human-interaction verification. Framework owns show/hide orchestration; View Layer supplies the DOM factories and animation helpers.
When to use: Apps rarely call these directly — Download Manager and Framework wire tag discovery and human-interaction panels. Compliance apps with trackComplianceRules get the compliance rules panel from Framework. Use the static helpers when building a custom dock slide panel that should match Brazen chrome.
| Method | Role |
|---|---|
createDockSlidePanel(id, title) |
Static. Base #bv-* slide panel shell with close button |
isDockSlidePanelVisible(panel) |
Static. Whether panel is on-screen |
setDockSlidePanelOrientations(orientation) |
Static. Apply bv-dock-panel-left/right/bottom to all slide panels |
syncDockSlidePanelStack(dockElement, orientation, panels) |
Static. Position stacked panels relative to dock |
showDockSlidePanel(panel, orientation, beforeAnimate?) |
Static. Slide in (no restart if already visible) |
hideDockSlidePanel(panel, orientation, animate?, onHidden?) |
Static. Slide out |
setDockSlidePanelHidden(panel, hidden) |
Static. Toggle hidden class |
wireDockSlidePanel(panel, { onClose, onMouseLeave }) |
Static. Bind close / mouseleave |
updateDockSlidePanelToggleButtons({ mainPanel, compliancePanel }) |
Static. Sync active class on dock toggle buttons |
Shared list chrome: .bv-dock-list-intro, .bv-dock-list-groups, .bv-dock-list-group, .bv-dock-list, .bv-dock-list-row, .bv-dock-list-name, .bv-dock-list-meta, .bv-dock-list-footer.
What it does: #bv-tag-discovery-panel — dock slide panel for reviewing unknown tags before downloads continue. Download Manager creates and drives it; apps supply tagDiscovery config (types, colors, actions).
| Method | Role |
|---|---|
createTagDiscoveryPanel({ onConfirm, onSkip?, onOpenMedia? }) |
Static. Panel with Skip / Open media / Confirm footer |
renderTagDiscoveryPanelContent(panel, tags, renderActions, options?) |
Static. Unknown + known tag sections, grouped rows, incidence meta |
prepareTagDiscoveryPanelOptions(config) |
Static. Merge tagTypes into group/row class resolvers |
applyTagDiscoveryTypeColors(tagTypes) |
Static. Inject per-type name colors |
renderTagActions(row, tag, actionsElement, config) |
Static. Reusable per-tag action row helper |
Confirm / Skip / Open media map to Framework confirmTagDiscoveryMappings, skipTagDiscoveryInclusion, openTagDiscoveryMedia.
What it does: #bv-human-interaction-panel — shown on the processor-leader tab when a rate-limit handler sets humanInteractionBlocked. Does not auto-close on mouseleave.
| Method | Role |
|---|---|
createHumanInteractionPanel({ onConfirm?, onReopen?, title?, message?, confirmLabel?, reopenLabel?, showReopen? }) |
Static. Queue pane (Done — resume / Reopen) or standalone reload pane (showReopen: false) |
updateHumanInteractionPanelContent(panel, { title?, message?, confirmLabel?, reopenLabel? }) |
Static. Refresh copy (e.g. consumer reopenLabel) |
What it does: #bv-compliance-rules — dock slide panel listing active hide rules when trackComplianceRules is enabled (replaces the old modal).
| Method | Role |
|---|---|
createComplianceRulesSlidePanel() |
Instance factory — intro + .bv-dock-list-groups shell |
renderComplianceRulesPanelContent(panel, report, { canRemoveRule?, onRemoveRule? }) |
Grouped filter sections with name, count meta, Remove action |
What it does: Ready-to-append Patreon support tab for settings panels.
this._userInterface = [
this._uiGen.createTabsSection(['Filters', 'Donate'], [
this._uiGen.createTabPanel('Filters', true).append([/* … */]),
this.createDonateTabPanel({ tabName: 'Donate', patreonUrl: 'https://…' }),
]),
]
| Method | Role |
|---|---|
createDonateTabPanel({ tabName?, isFirst?, patreonUrl?, linkLabel?, message? }) |
Tab panel with Patreon link + icon |
createPatreonIcon(iconClass?) |
Static. SVG Patreon mark |
Framework exposes createDonateTabPanel(options?) as a thin wrapper.
Used by Download Manager for dock progress, selection marks, and search-tile pipeline overlays.
| Method | Role |
|---|---|
createDownloadManagerProgressSlot() |
Static. .bv-dock-progress-panel + bar + label |
updateDownloadManagerProgressSlot(slot, progress) |
Static. Download-queue current/total display |
setDownloadManagerProgressSlotVisible(slot, visible) |
Static. Toggle .bv-dock-progress-hidden |
setDownloadManagerSelectionMark(element, selected) |
Static. .bv-dm-selected on tiles |
updateDownloadManagerItemProgress(element, progress) |
Static. Blur overlay + step label + segmented bar |
clearDownloadManagerItemProgress(element) |
Static. Remove .bv-dm-item-progress overlay |
updateDockFieldButton(field, presentation) |
Refresh dock button icon/tooltip/active/disabled from CM field |
progress for item overlays: { label, stepIndex, stepCount, failed?, complete? }.
| Method | Role |
|---|---|
ensureIdbBlockedBanner() |
Static. Prepends #bv-idb-blocked-banner when persistence is disabled |
| Method | Role |
|---|---|
showConfirmDialog({ title, message, confirmLabel?, cancelLabel?, showCancel? }) |
Static. Promise<boolean> modal |
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
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) |
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).
enhanceTagSidebarCountsWhat 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.
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.
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-dock-list-*, .bv-dock-slide-panel-* |
Dock slide list panels (discovery, compliance, human interaction) |
.bv-tag-actions-slot, .bv-tag-actions, .bv-tag-row-active |
Sidebar tag actions |
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
createSettingsSection, createSettingsShowButton, createSettingsHideButton, createResizer, isSettingsPaneBeingResized, getSelectedSectionappendToBody, createContainer, createBottomSection, createTitle, createSeparator, createBreakSeparator, createFormSectioncreateFormGroup*, createFormInputGroup, createFormRangeInputGroup, createFormTextAreaGroup, createFormCheckBoxesGroupSection, createFormRadiosGroupSection, createFormGroupDropdown, createFormButton, createFormActionscreateTabsSection, createTabButton, createTabPanelcreateFormGroupStatLabel, createStatisticsFormGroup, createStatisticsTotalsGroupcreateModal, showModal, hideModalcreateBookmarksPanel (and BrazenBookmarksPanel methods)enhanceTagSidebarCountscreatePatternTokenChip, createSharedPatternTokenBuilder, insertIntoPatternInput, patchPatternTokenBuilder, patchStackedPatternFieldGroups, patchRangeInputLayoutcreateDockSlidePanel, isDockSlidePanelVisible, setDockSlidePanelOrientations, syncDockSlidePanelStack, showDockSlidePanel, hideDockSlidePanel, setDockSlidePanelHidden, wireDockSlidePanel, updateDockSlidePanelToggleButtonscreateTagDiscoveryPanel, renderTagDiscoveryPanelContent, prepareTagDiscoveryPanelOptions, applyTagDiscoveryTypeColors, renderTagActionscreateHumanInteractionPanel, updateHumanInteractionPanelContentcreateComplianceRulesSlidePanel, renderComplianceRulesPanelContentcreateDonateTabPanel, createPatreonIconcreateDownloadManagerProgressSlot, updateDownloadManagerProgressSlot, setDownloadManagerProgressSlotVisible, setDownloadManagerSelectionMark, updateDownloadManagerItemProgress, clearDownloadManagerItemProgress, updateDockFieldButtonensureIdbBlockedBanner, showConfirmDialog@grant GM_addStyle on this script or the app (styles are injected when this module loads).id match after Utilities.toKebabCase(...).