Ezt a szkriptet nem ajánlott közvetlenül telepíteni. Ez egy könyvtár más szkriptek számára, amik tartalmazzák a // @require https://update.sleazyfork.org/scripts/416104/870040/Brazen%20UI%20Generator.js
hivatkozást.
// ==UserScript==
// @name Brazen UI Generator
// @namespace brazen
// @version 1.0.1
// @author brazenvoid
// @license GPL-3.0-only
// @description Helper methods to generate a control panel UI for scripts
// @require https://greasyfork.org/scripts/375557-base-resource/code/Base%20Resource.js?version=869326
// @grant GM_addStyle
// ==/UserScript==
/**
* @function GM_addStyle
* @param {string} style
*/
GM_addStyle(
`@keyframes fadeEffect{from{opacity:0}to{opacity:1}}button.form-button{padding:0 5px;width:100%}button.show-settings{background-color:#ffa31a;border:0;color:#000;font-size:.7rem;height:90vh;left:0;margin:0;padding:0;position:fixed;top:5vh;width:.1vw;writing-mode:sideways-lr;z-index:999}button.tab-button{background-color:inherit;border:1px solid #000;border-bottom:0;border-top-left-radius:3px;border-top-right-radius:3px;cursor:pointer;float:left;outline:none;padding:5px 10px;transition:.3s}button.tab-button:hover{background-color:#fff}button.tab-button.active{background-color:#fff;display:block}div.form-actions{text-align:center}div.form-actions button.form-button{padding:0 15px;width:auto}div.form-actions-wrapper{display:inline-flex}div.form-actions-wrapper > div.form-group + *{margin-left:15px}div.form-group{align-items:center;display:flex;min-height:20px;padding:4px 0}div.form-group.form-range-input-group > input{padding:0 5px;width:75px}div.form-group.form-range-input-group > input + input{margin-left:5px}div.form-section{text-align:center}div.form-section button + button{margin-left:5px}div.form-section label.title{display:block;height:20px;width:100%}div.form-section button.form-button{width:auto}div.tab-panel{animation:fadeEffect 1s;border:1px solid #000;display:none;padding:5px 10px}div.tab-panel.active{display:block}div.tabs-nav{overflow:hidden}div.tabs-section{margin-bottom:5px}hr{margin:3px}input.form-input{text-align:center}input.form-input.check-radio-input{margin-right:5px}input.form-input.regular-input{width:100px}label.form-label{flex-grow:1}label.form-stat-label{padding:2px 0}section.form-section{color:#000;font-size:12px;font-weight:700;position:fixed;left:0;padding:5px 10px;z-index:1000}select.form-dropdown{float:right;height:18px;text-align:center;width:100px}textarea.form-input{display:block;height:auto;position:relative;width:98%}`)
class BrazenUIGenerator
{
/**
* @param {JQuery} nodes
*/
static appendToBody (nodes)
{
$('body').append(nodes)
}
/**
* @param {boolean} showUI
* @param {string} selectorPrefix
*/
constructor (showUI, selectorPrefix)
{
/**
* @type {*}
* @private
*/
this._buttonBackroundColor = null
/**
* @type {JQuery}
* @private
*/
this._section = null
/**
* @type {SelectorGenerator}
* @private
*/
this._selectorGenerator = new SelectorGenerator(selectorPrefix)
/**
* @type {string}
* @private
*/
this._selectorPrefix = selectorPrefix
/**
* @type {boolean}
* @private
*/
this._showUI = showUI
/**
* @type {JQuery}
* @private
*/
this._statusLine = null
/**
* @type {string}
* @private
*/
this._statusText = ''
}
/**
* @param {JQuery} node
* @param {string} text
* @return {this}
* @private
*/
_addHelpTextOnHover (node, text)
{
node.on('mouseover', () => this.updateStatus(text, true))
node.on('mouseout', () => this.resetStatus())
}
/**
* @return {JQuery}
*/
createBreakSeparator ()
{
return $('<br/>')
}
/**
* @param {JQuery|JQuery[]} children
* @return {JQuery}
*/
createFormActions (children)
{
return $('<div class="form-actions"/>').append($('<div class="form-actions-wrapper"/>').append(children))
}
/**
* @param {string} caption
* @param {JQuery.EventHandler} onClick
* @param {string} hoverHelp
* @return {JQuery}
*/
createFormButton (caption, onClick, hoverHelp = '')
{
let button = $('<button class="form-button">').
css('backgroundColor', this._buttonBackroundColor ?? 'revert').
text(caption).
on('click', onClick)
if (hoverHelp !== '') {
this._addHelpTextOnHover(button, hoverHelp)
}
return button
}
/**
* @return {JQuery}
*/
createFormGroup ()
{
return $('<div class="form-group"/>')
}
/**
* @param {string} id
* @param {Array} keyValuePairs
* @param {boolean} multiple
*
* @return {JQuery}
*/
createFormGroupDropdown (id, keyValuePairs, multiple = false)
{
let dropdown = $('<select>').
attr('id'.id).
addClass(multiple ? 'form-dropdown-multiple' : 'form-dropdown').
prop('multiple', multiple)
for (let i = 0; i < keyValuePairs.length; i++) {
dropdown.append(
$('<option>').
val(keyValuePairs[i][0]).
text(keyValuePairs[i][1]).
prop('selected', multiple ? false : (i === 0)),
)
}
return dropdown
}
/**
* @param {string} id
* @param {string} type
*
* @return {JQuery}
*/
createFormGroupInput (id, type)
{
let inputFormGroup = $('<input class="form-input">').attr('id', id).attr('type', type)
switch (type) {
case 'number':
case 'text':
inputFormGroup.addClass('regular-input')
break
case 'radio':
case 'checkbox':
inputFormGroup.addClass('check-radio-input')
break
}
return inputFormGroup
}
/**
* @param {string} label
* @param {string} inputID
* @param {string} inputType
* @return {JQuery}
*/
createFormGroupLabel (label, inputID = '', inputType = '')
{
let labelFormGroup = $('<label class="form-label">').attr('for', inputID).text(label)
if (inputType !== '') {
switch (inputType) {
case 'number':
case 'text':
labelFormGroup.addClass('regular-input')
labelFormGroup.text(labelFormGroup.text() + ': ')
break
case 'radio':
case 'checkbox':
labelFormGroup.addClass('check-radio-input')
break
}
}
return labelFormGroup
}
/**
* @param {string} statisticType
* @return {JQuery}
*/
createFormGroupStatLabel (statisticType)
{
return $('<label class="form-stat-label">').
attr('id', this._selectorGenerator.getStatLabelSelector(statisticType)).
text('0')
}
/**
* @param {string} label
* @param {string} inputType
* @param {string} hoverHelp
* @return {JQuery}
*/
createFormInputGroup (label, inputType = 'text', hoverHelp = '')
{
let inputID = this._selectorGenerator.getSettingsInputSelector(label)
let divFormInputGroup = this.createFormGroup().append([
this.createFormGroupLabel(label, inputID, inputType),
this.createFormGroupInput(inputID, inputType),
])
if (hoverHelp !== '') {
this._addHelpTextOnHover(divFormInputGroup, hoverHelp)
}
return divFormInputGroup
}
/**
* @param {string} label
* @param {string} inputsType
*
* @return {JQuery}
*/
createFormRangeInputGroup (label, inputsType = 'text')
{
let divFormInputGroup = this.createFormGroup().append([
this.createFormGroupLabel(label, '', inputsType),
this.createFormGroupInput(this._selectorGenerator.getSettingsRangeInputSelector(label, true), inputsType),
this.createFormGroupInput(this._selectorGenerator.getSettingsRangeInputSelector(label, false), inputsType),
])
return divFormInputGroup.addClass('form-range-input-group')
}
/**
* @param {string} title
* @return {JQuery}
*/
createFormSection (title = '')
{
let sectionDiv = $('<div class="form-section">')
if (title !== '') {
sectionDiv.append($('<label class="title">').text(title))
}
return sectionDiv
}
/**
* @param {string} caption
* @param {string} tooltip
* @param {JQuery.EventHandler} onClick
* @param {string} hoverHelp
* @return {JQuery}
*/
createFormSectionButton (caption, tooltip, onClick, hoverHelp = '')
{
return this.createFormButton(caption, onClick, hoverHelp).attr('title', tooltip)
}
/**
* @param {string} label
* @param {int} rows
* @param {string} hoverHelp
* @return {JQuery}
*/
createFormTextAreaGroup (label, rows, hoverHelp = '')
{
let group = this.createFormGroup().append([
this.createFormGroupLabel(label).css('textAlign', 'center'),
$('<textarea class="form-input">').
attr('id', this._selectorGenerator.getSettingsInputSelector(label)).
attr('rows', rows),
])
if (hoverHelp !== '') {
this._addHelpTextOnHover(group, hoverHelp)
}
return group
}
/**
* @return {JQuery}
*/
createSection ()
{
this._section = $('<section class="form-section">')
return this._section
}
/**
* @return {JQuery}
*/
createSeparator ()
{
return $('<hr/>')
}
/**
* @param {LocalStore} localStore
* @param {JQuery.EventHandler} onClick
* @return {JQuery}
*/
createSettingsFormActions (localStore, onClick)
{
return this.createFormSection().append([
this.createFormActions([
this.createFormButton('Apply', onClick, 'Filter items as per the settings in the dialog.'),
this.createFormButton('Reset', (event) => {
localStore.retrieve()
onClick(event)
}, 'Restore and apply saved configuration.'),
]),
])
}
/**
* @param {string} label
* @param {Array} keyValuePairs
* @param {boolean} multiple
*
* @return {JQuery}
*/
createSettingsDropDownFormGroup (label, keyValuePairs, multiple = false)
{
let dropdownID = this._selectorGenerator.getSettingsInputSelector(label)
let optionsSelector = '#' + dropdownID + ' option'
if (multiple) {
return this.createFormSection(label).append([
this.createFormGroup().append([
this.createFormGroupDropdown(dropdownID, keyValuePairs, multiple),
]),
this.createFormActions([
this.createFormButton(
'Select All',
() => {
$(optionsSelector).each((index, element) => {
$(element).prop('selected', true)
})
},
'Select all options.',
),
this.createFormButton(
'Deselect All',
() => {
$(optionsSelector).each((index, element) => {
$(element).prop('selected', false)
})
},
'Deselect all options.',
),
]),
])
}
return this.createFormGroup().append([
this.createFormGroupLabel(label, dropdownID, 'text'),
this.createFormGroupDropdown(dropdownID, keyValuePairs, multiple),
])
}
/**
* @return {JQuery}
*/
createSettingsHideButton ()
{
return this.createFormButton('<< Hide', () => this._section.style.display = 'none')
}
/**
* @param {string} caption
* @param {JQuery} settingsSection
* @param {JQuery.EventHandler|null} onMouseLeave
*
* @return {JQuery}
*/
createSettingsShowButton (caption, settingsSection, onMouseLeave = null)
{
return $('<button class="show-settings">').
text(caption).
on('click', () => settingsSection.toggle(500)).
on('mouseleave', onMouseLeave ? () => onMouseLeave() : () => settingsSection.hide(500))
}
/**
* @param {string} statisticsType
* @param {string} label
* @return {JQuery}
*/
createStatisticsFormGroup (statisticsType, label = '')
{
return this.createFormGroup().append([
this.createFormGroupLabel((label === '' ? statisticsType : label) + ' Filter'),
this.createFormGroupStatLabel(statisticsType),
])
}
/**
* @return {JQuery}
*/
createStatisticsTotalsGroup ()
{
return this.createFormGroup().append([
this.createFormGroupLabel('Total'),
this.createFormGroupStatLabel('Total'),
])
}
/**
* @return {JQuery}
*/
createStatusSection ()
{
this._statusLine = this.createFormGroupLabel('Status').attr('id', this._selectorGenerator.getSelector('status'))
return this.createFormSection().append(this._statusLine)
}
/**
* @param {LocalStore} localStore
* @return {JQuery}
*/
createStoreFormSection (localStore)
{
return this.createFormSection('Cached Configuration').append([
this.createFormActions([
this.createFormSectionButton(
'Update',
'Save UI settings in store',
() => localStore.save(), 'Saves applied settings.',
),
this.createFormSectionButton(
'Purge',
'Purge store',
() => localStore.delete(),
'Removes saved settings. Settings will then be sourced from the defaults defined in the script.',
),
]),
])
}
/**
* @param {string} tabName
* @param {boolean} isFirst
* @return {JQuery}
*/
createTabButton (tabName, isFirst)
{
let tabButton = $('<button class="tab-button">').
text(tabName).
on('click', (event) => {
let button = $(event.currentTarget)
button.parents('.tabs-section:first').find('.tab-button,.tab-panel').removeClass('active')
button.addClass('active')
console.log(button.text())
console.log(Utilities.toKebabCase(button.text()))
console.log('#' + Utilities.toKebabCase(button.text()))
$('#' + Utilities.toKebabCase(button.text())).addClass('active')
})
if (isFirst) {
tabButton.addClass('active')
}
return tabButton
}
/**
* @param {string} tabName
* @param {boolean} isFirst
* @return {JQuery}
*/
createTabPanel (tabName, isFirst = false)
{
let tabPanel = $('<div class="tab-panel">').attr('id', Utilities.toKebabCase(tabName))
if (isFirst) {
tabPanel.addClass('active')
}
return tabPanel
}
/**
* @param {string[]} tabNames
* @param {JQuery[]} tabPanels
* @return {JQuery}
*/
createTabsSection (tabNames, tabPanels)
{
let tabButtons = []
for (let i = 0; i < tabNames.length; i++) {
tabButtons.push(this.createTabButton(tabNames[i], i === 0))
}
let nav = $('<div class="tabs-nav">').append(tabButtons)
return $('<div class="tabs-section">').append(nav).append(...tabPanels)
}
/**
* @return {JQuery}
*/
getSelectedSection ()
{
return this._section
}
/**
* @param {string} label
* @return {JQuery}
*/
getSettingsInput (label)
{
return $(this._selectorGenerator.getSettingsInputSelector(label))
}
/**
* @param {string} label
* @return {number}
*/
getSettingsInputNumberValue (label)
{
return parseInt(this.getSettingsInput(label).val())
}
/**
* @param {string} label
* @return {string|string[]|boolean}
*/
getSettingsInputValue (label)
{
let input = this.getSettingsInput(label)
if (input.attr('type') === 'checkbox') {
return input.prop('checked')
}
return input.val()
}
/**
* @param {string} label
* @param {boolean} getMinInput
* @return {JQuery}
*/
getSettingsRangeInput (label, getMinInput)
{
return $(this._selectorGenerator.getSettingsRangeInputSelector(label, getMinInput))
}
/**
* @param {string} label
* @param {boolean} getMinInputValue
* @return {number}
*/
getSettingsRangeInputValue (label, getMinInputValue)
{
return parseInt(this.getSettingsRangeInput(label, getMinInputValue).val())
}
resetStatus ()
{
this._statusLine.text(this._statusText)
}
/**
* @param {string} label
* @param {*} value
*/
setSettingsInputValue (label, value)
{
let input = this.getSettingsInput(label)
if (input.attr('type') === 'checkbox') {
input.prop('checked', value)
} else {
input.val(value)
}
}
/**
* @param {string} label
* @param {number} lowerBound
* @param {number} upperBound
*/
setSettingsRangeInputValue (label, lowerBound, upperBound)
{
this.getSettingsRangeInput(label, true).val(lowerBound)
this.getSettingsRangeInput(label, false).val(upperBound)
}
/**
* @param {string} status
* @param {boolean} transient
*/
updateStatus (status, transient = false)
{
if (!transient) {
this._statusText = status
}
this._statusLine.text(status)
}
}