From 357da3219b6686616c3435524fa23ac987eff840 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Sun, 15 Feb 2026 01:16:34 +0200 Subject: [PATCH] Chore: Add code formatting conventions as eslint rules (#5158) * Add code formatting conventions as eslint rules * Improve formatting in addQuickReply --- .eslintrc.cjs | 23 ++ public/script.js | 16 +- public/scripts/BulkEditOverlay.js | 4 +- public/scripts/PromptManager.js | 2 - public/scripts/RossAscends-mods.js | 3 - public/scripts/autocomplete/AutoComplete.js | 5 - .../autocomplete/AutoCompleteFuzzyScore.js | 3 - .../autocomplete/AutoCompleteNameResult.js | 1 - .../AutoCompleteNameResultBase.js | 5 +- .../autocomplete/AutoCompleteOption.js | 3 +- public/scripts/bulk-edit.js | 2 +- public/scripts/cfg-scale.js | 1 - public/scripts/chat-backups.js | 2 +- public/scripts/data-maid.js | 1 - public/scripts/extensions/assets/index.js | 3 +- .../scripts/extensions/expressions/index.js | 4 +- public/scripts/extensions/gallery/index.js | 1 - .../quick-reply/api/QuickReplyApi.js | 24 +- .../scripts/extensions/quick-reply/index.js | 30 ++- .../quick-reply/src/AutoExecuteHandler.js | 6 +- .../extensions/quick-reply/src/QuickReply.js | 218 +++++++++--------- .../quick-reply/src/QuickReplyConfig.js | 32 +-- .../quick-reply/src/QuickReplyContextLink.js | 2 - .../quick-reply/src/QuickReplySet.js | 51 ++-- .../quick-reply/src/QuickReplySetLink.js | 20 +- .../quick-reply/src/QuickReplySettings.js | 10 +- .../quick-reply/src/SlashCommandHandler.js | 34 ++- .../extensions/quick-reply/src/ui/ButtonUi.js | 20 +- .../quick-reply/src/ui/SettingsUi.js | 68 +++--- .../quick-reply/src/ui/ctx/ContextMenu.js | 4 - .../quick-reply/src/ui/ctx/MenuItem.js | 3 - .../quick-reply/src/ui/ctx/SubMenu.js | 4 - public/scripts/extensions/regex/index.js | 1 - .../scripts/extensions/token-counter/index.js | 1 - public/scripts/extensions/tts/alltalk.js | 1 - public/scripts/extensions/tts/chatterbox.js | 3 - public/scripts/extensions/tts/coqui.js | 25 +- public/scripts/extensions/tts/cosyvoice.js | 6 - public/scripts/extensions/tts/elevenlabs.js | 2 +- .../scripts/extensions/tts/google-native.js | 2 - .../scripts/extensions/tts/gpt-sovits-v2.js | 8 - public/scripts/extensions/tts/gsvi.js | 9 - public/scripts/extensions/tts/index.js | 4 - .../scripts/extensions/tts/kokoro-worker.js | 2 +- public/scripts/extensions/tts/minimax.js | 2 - public/scripts/extensions/tts/openai.js | 1 - public/scripts/extensions/tts/silerotts.js | 1 - public/scripts/extensions/tts/xtts.js | 1 - public/scripts/extensions/vectors/index.js | 1 - public/scripts/f-localStorage.js | 1 - public/scripts/filters.js | 1 - public/scripts/group-chats.js | 1 - public/scripts/input-md-formatting.js | 9 +- public/scripts/instruct-mode.js | 1 - public/scripts/openai.js | 4 - public/scripts/personas.js | 2 - public/scripts/popup.js | 1 - public/scripts/power-user.js | 9 +- public/scripts/preset-manager.js | 1 - public/scripts/reasoning.js | 1 - public/scripts/samplerSelect.js | 1 - public/scripts/showdown-underscore.js | 2 +- public/scripts/slash-commands.js | 2 - public/scripts/slash-commands/SlashCommand.js | 9 +- .../slash-commands/SlashCommandArgument.js | 3 +- .../SlashCommandAutoCompleteNameResult.js | 26 +-- .../slash-commands/SlashCommandBrowser.js | 30 +-- .../slash-commands/SlashCommandClosure.js | 34 +-- .../SlashCommandCommandAutoCompleteOption.js | 2 - .../SlashCommandCommonEnumsProvider.js | 2 +- .../SlashCommandDebugController.js | 13 +- .../SlashCommandEnumAutoCompleteOption.js | 3 +- .../SlashCommandExecutionError.js | 1 - .../slash-commands/SlashCommandExecutor.js | 12 +- .../slash-commands/SlashCommandParser.js | 40 ++-- .../slash-commands/SlashCommandScope.js | 8 +- public/scripts/tags.js | 1 - public/scripts/textgen-settings.js | 5 +- public/scripts/user.js | 4 - public/scripts/utils.js | 1 - public/scripts/world-info.js | 2 - src/endpoints/assets.js | 2 - src/endpoints/backends/text-completions.js | 2 - src/endpoints/backups.js | 2 +- src/endpoints/characters.js | 4 +- src/endpoints/extensions.js | 2 - src/endpoints/groups.js | 2 +- src/endpoints/horde.js | 2 - src/endpoints/image-metadata.js | 1 - src/endpoints/minimax.js | 2 - src/endpoints/stable-diffusion.js | 1 - src/endpoints/thumbnails.js | 1 - src/prompt-converters.js | 3 +- src/util.js | 1 - 94 files changed, 366 insertions(+), 566 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 331f0cbfe..bcb7db18b 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -102,5 +102,28 @@ module.exports = { // These rules should eventually be enabled. 'no-async-promise-executor': 'off', 'no-inner-declarations': 'off', + 'brace-style': 'off', + // Additional formatting rules based on codebase conventions + 'array-bracket-spacing': ['error', 'never'], + 'computed-property-spacing': ['error', 'never'], + 'block-spacing': ['error', 'always'], + 'keyword-spacing': ['error', { before: true, after: true }], + 'space-before-blocks': ['error', 'always'], + 'space-before-function-paren': ['error', { anonymous: 'always', named: 'never', asyncArrow: 'always' }], + 'space-in-parens': ['error', 'never'], + 'comma-spacing': ['error', { before: false, after: true }], + 'key-spacing': ['error', { beforeColon: false, afterColon: true }], + 'func-call-spacing': ['error', 'never'], + 'no-multiple-empty-lines': ['error', { max: 2, maxEOF: 1, maxBOF: 0 }], + 'padded-blocks': ['error', 'never'], + 'no-whitespace-before-property': 'error', + 'space-unary-ops': ['error', { words: true, nonwords: false }], + 'arrow-spacing': ['error', { before: true, after: true }], + 'template-curly-spacing': ['error', 'never'], + 'rest-spread-spacing': ['error', 'never'], + 'generator-star-spacing': ['error', { before: false, after: true }], + 'yield-star-spacing': ['error', { before: false, after: true }], + 'template-tag-spacing': ['error', 'never'], + 'switch-colon-spacing': ['error', { after: true, before: false }], }, }; diff --git a/public/script.js b/public/script.js index 296e078e5..d74301184 100644 --- a/public/script.js +++ b/public/script.js @@ -2516,7 +2516,6 @@ export function addOneMessage(mes, { type = undefined, insertAfter = null, scrol * @returns {JQuery} Rendered HTMLElement. */ export function updateMessageElement(mes, { messageId = chat.length - 1, messageElement = messageTemplate.clone(), adjustMediaScroll = SCROLL_BEHAVIOR.NONE } = {}) { - let avatarImg = getThumbnailUrl('persona', user_avatar); //for non-user messages @@ -3709,9 +3708,9 @@ class StreamingProcessor { } /** - * @returns {Generator<{ text: string, swipes: string[], logprobs: import('./scripts/logprobs.js').TokenLogprobs, toolCalls: any[], state: any }, void, void>} + * @returns {AsyncGenerator<{ text: string, swipes: string[], logprobs: import('./scripts/logprobs.js').TokenLogprobs, toolCalls: any[], state: any }, void, void>} */ - *nullStreamingGeneration() { + async* nullStreamingGeneration() { throw new Error('Generation function for streaming is not hooked up'); } @@ -4862,7 +4861,6 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro // Add quiet generation prompt at depth 0 if (quiet_prompt && quiet_prompt.length) { - // here name1 is forced for all quiet prompts..why? const name = name1; //checks if we are in instruct, if so, formats the chat as such, otherwise just adds the quiet prompt @@ -5399,7 +5397,6 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro if (!isAborted && power_user.auto_swipe && generatedTextFiltered(getMessage)) { is_send_press = false; return await swipe(null, SWIPE_DIRECTION.RIGHT, { source: SWIPE_SOURCE.AUTO_SWIPE, repeated: true, forceMesId: chat.length - 1 }); - } console.debug('/api/chats/save called by /Generate'); @@ -6517,7 +6514,6 @@ export async function saveReply({ type, getMessage, fromStreaming = false, title !fromStreaming && await eventSource.emit(event_types.MESSAGE_RECEIVED, chat_id, type); addOneMessage(chat[chat_id], { type: 'swipe' }); !fromStreaming && await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, chat_id, type); - } else { console.debug('entering chat update routine for non-swipe post'); const newMessage = {}; @@ -8247,7 +8243,6 @@ export async function getChatsFromFiles(data, isGroupChat) { currentChat.shift(); } chat_dict[file_name] = currentChat; - } catch (error) { console.error(error); } @@ -9588,7 +9583,6 @@ export async function createOrEditCharacter(e) { select_rm_info('char_create', avatarId, oldSelectedChar); crop_data = undefined; - } catch (error) { console.error('Error creating character', error); toastr.error(t`Failed to create character`); @@ -9984,7 +9978,6 @@ export async function swipe(event, direction, { source, repeated, message = chat duration: 0, //used to be 100 //Disabled on Cohee's request. https://github.com/SillyTavern/SillyTavern/pull/4610/files#r2408731744 queue: false, progress: function (animation, progress, remainingMs) { - if (is_animation_scroll) chatElement.scrollTop(getMessageBottomHeight(thisMesDiv)); }, complete: function () { @@ -10001,7 +9994,6 @@ export async function swipe(event, direction, { source, repeated, message = chat * @param {boolean} [skipSwipeOut=false] */ async function animateSwipe(run_generate = false, skipSwipeOut = false) { - if (!skipSwipeOut) { //Swipe out. await animateSwipeTransition(mesId, { xEnd: `${swipeRange}px`, duration: swipeDuration }); @@ -10069,7 +10061,6 @@ export async function swipe(event, direction, { source, repeated, message = chat //If the swipe is not being deleted. if (source != SWIPE_SOURCE.DELETE && source != SWIPE_SOURCE.BACK) { - // Make sure ad-hoc changes to extras are saved before swiping away syncMesToSwipe(mesId); @@ -10382,7 +10373,6 @@ export async function doNewChat({ deleteCurrentChat = false } = {}) { await createOrEditCharacter(new CustomEvent('newChat')); if (deleteCurrentChat) await delChat(chat_file_for_del + '.jsonl'); } - } /** @@ -11407,9 +11397,7 @@ jQuery(async function () { divchat.style.borderRadius = ''; divchat.style.backgroundColor = ''; - } else { - divchat.style.borderRadius = '10px'; // Adjust the value to control the roundness of the corners divchat.style.backgroundColor = ''; // Set the background color to your preference diff --git a/public/scripts/BulkEditOverlay.js b/public/scripts/BulkEditOverlay.js index ef31f68ab..135ed558f 100644 --- a/public/scripts/BulkEditOverlay.js +++ b/public/scripts/BulkEditOverlay.js @@ -101,7 +101,7 @@ class CharacterContextMenu { * @param {number} characterId * @returns {Promise} */ - static persona = async (characterId) => void(await convertCharacterToPersona(characterId)); + static persona = async (characterId) => void (await convertCharacterToPersona(characterId)); /** * Delete one or more characters, @@ -754,7 +754,7 @@ class BulkEditOverlay { handleContextMenuShow = (event) => { event.preventDefault(); - const [x,y] = this.#getContextMenuPosition(event); + const [x, y] = this.#getContextMenuPosition(event); CharacterContextMenu.show(x, y); this.#contextMenuOpen = true; }; diff --git a/public/scripts/PromptManager.js b/public/scripts/PromptManager.js index 3006e4b53..2dd0d055f 100644 --- a/public/scripts/PromptManager.js +++ b/public/scripts/PromptManager.js @@ -986,7 +986,6 @@ class PromptManager { * @returns {void} */ addPrompt(prompt, identifier) { - if (typeof prompt !== 'object' || prompt === null) throw new Error('Object is not a prompt'); const newPrompt = { @@ -1318,7 +1317,6 @@ class PromptManager { this.updatePromptByIdentifier(identifier, prompt); debouncedSaveServiceSettings().then(() => this.render()); }); - } /** diff --git a/public/scripts/RossAscends-mods.js b/public/scripts/RossAscends-mods.js index c76d0a11f..b841b00f4 100644 --- a/public/scripts/RossAscends-mods.js +++ b/public/scripts/RossAscends-mods.js @@ -101,7 +101,6 @@ observer.observe(document.documentElement, observerConfig); * @returns {string} - A human-readable string that represents the time spent generating characters. */ export function humanizeGenTime(total_gen_time) { - //convert time_spent to humanized format of "_ Hours, _ Minutes, _ Seconds" from milliseconds let time_spent = total_gen_time || 0; time_spent = Math.floor(time_spent / 1000); @@ -1274,8 +1273,6 @@ export function initRossMods() { } - - if (event.ctrlKey && /^[1-9]$/.test(event.key)) { // This will eventually be to trigger quick replies // event.preventDefault(); diff --git a/public/scripts/autocomplete/AutoComplete.js b/public/scripts/autocomplete/AutoComplete.js index 268cad09e..b641f56e1 100644 --- a/public/scripts/autocomplete/AutoComplete.js +++ b/public/scripts/autocomplete/AutoComplete.js @@ -80,8 +80,6 @@ export class AutoComplete { } - - /** * @param {HTMLTextAreaElement|HTMLInputElement} textarea The textarea to receive autocomplete. * @param {() => boolean} checkIfActivate Function should return true only if under the current conditions, autocomplete should display (e.g., for slash commands: autoComplete.text[0] == '/') @@ -414,7 +412,6 @@ export class AutoComplete { }); - if (this.isForceHidden) { // hidden with escape return this.hide(); @@ -465,7 +462,6 @@ export class AutoComplete { } - /** * Create updated DOM. */ @@ -514,7 +510,6 @@ export class AutoComplete { } - /** * Update position of DOM. */ diff --git a/public/scripts/autocomplete/AutoCompleteFuzzyScore.js b/public/scripts/autocomplete/AutoCompleteFuzzyScore.js index 550fbe6a2..0ecb54266 100644 --- a/public/scripts/autocomplete/AutoCompleteFuzzyScore.js +++ b/public/scripts/autocomplete/AutoCompleteFuzzyScore.js @@ -1,6 +1,3 @@ - - - export class AutoCompleteFuzzyScore { /**@type {number}*/ start; /**@type {number}*/ longestConsecutive; diff --git a/public/scripts/autocomplete/AutoCompleteNameResult.js b/public/scripts/autocomplete/AutoCompleteNameResult.js index f048d6383..f146dc825 100644 --- a/public/scripts/autocomplete/AutoCompleteNameResult.js +++ b/public/scripts/autocomplete/AutoCompleteNameResult.js @@ -2,7 +2,6 @@ import { AutoCompleteNameResultBase } from './AutoCompleteNameResultBase.js'; import { AutoCompleteSecondaryNameResult } from './AutoCompleteSecondaryNameResult.js'; - export class AutoCompleteNameResult extends AutoCompleteNameResultBase { /** * diff --git a/public/scripts/autocomplete/AutoCompleteNameResultBase.js b/public/scripts/autocomplete/AutoCompleteNameResultBase.js index 4cd491468..6e8408dc2 100644 --- a/public/scripts/autocomplete/AutoCompleteNameResultBase.js +++ b/public/scripts/autocomplete/AutoCompleteNameResultBase.js @@ -1,14 +1,13 @@ import { AutoCompleteOption } from './AutoCompleteOption.js'; - export class AutoCompleteNameResultBase { /**@type {string} */ name; /**@type {number} */ start; /**@type {AutoCompleteOption[]} */ optionList = []; /**@type {boolean} */ canBeQuoted = false; - /**@type {()=>string} */ makeNoMatchText = ()=>`No matches found for "${this.name}"`; - /**@type {()=>string} */ makeNoOptionsText = ()=>'No options'; + /**@type {()=>string} */ makeNoMatchText = () => `No matches found for "${this.name}"`; + /**@type {()=>string} */ makeNoOptionsText = () => 'No options'; /** diff --git a/public/scripts/autocomplete/AutoCompleteOption.js b/public/scripts/autocomplete/AutoCompleteOption.js index 74f8665a6..2ca3d44dd 100644 --- a/public/scripts/autocomplete/AutoCompleteOption.js +++ b/public/scripts/autocomplete/AutoCompleteOption.js @@ -1,7 +1,6 @@ import { AutoCompleteFuzzyScore } from './AutoCompleteFuzzyScore.js'; - export class AutoCompleteOption { /** @type {string} */ name; /** @type {string} */ typeIcon; @@ -72,7 +71,7 @@ export class AutoCompleteOption { name.classList.add('name'); name.classList.add('monospace'); name.textContent = noSlash ? '' : '/'; - key.split('').forEach(char=>{ + key.split('').forEach(char => { const span = document.createElement('span'); { span.textContent = char; name.append(span); diff --git a/public/scripts/bulk-edit.js b/public/scripts/bulk-edit.js index 404e07a01..bb09551cc 100644 --- a/public/scripts/bulk-edit.js +++ b/public/scripts/bulk-edit.js @@ -55,7 +55,7 @@ function onSelectAllButtonClick() { if (!atLeastOneSelected) { // If none was selected, trigger click on all to deselect all of them - for(const character of characters) { + for (const character of characters) { const checked = $(character).find('.bulk_select_checkbox:checked') ?? false; if (checked && character instanceof HTMLElement) { characterGroupOverlay.toggleSingleCharacter(character); diff --git a/public/scripts/cfg-scale.js b/public/scripts/cfg-scale.js index 801e78af7..56b5995e8 100644 --- a/public/scripts/cfg-scale.js +++ b/public/scripts/cfg-scale.js @@ -150,7 +150,6 @@ function onCfgMenuItemClick() { setTimeout(function () { $('#cfgConfig').hide(); }, animation_duration); - } //duplicate options menu close handler from script.js //because this listener takes priority diff --git a/public/scripts/chat-backups.js b/public/scripts/chat-backups.js index 437b87873..966bd78fe 100644 --- a/public/scripts/chat-backups.js +++ b/public/scripts/chat-backups.js @@ -199,7 +199,7 @@ class BackupsBrowser { const deleteButton = document.createElement('div'); deleteButton.classList.add('right_menu_button', 'fa-solid', 'fa-trash'); deleteButton.title = t`Delete backup`; - deleteButton.addEventListener('click',async () => { + deleteButton.addEventListener('click', async () => { const isDeleted = await this.deleteBackup(backup.file_name); if (isDeleted) { listItem.remove(); diff --git a/public/scripts/data-maid.js b/public/scripts/data-maid.js index 144d3ca05..7d706eabd 100644 --- a/public/scripts/data-maid.js +++ b/public/scripts/data-maid.js @@ -251,7 +251,6 @@ class DataMaidDialog { categoryElement.remove(); this.displayEmptyPlaceholder(); }); - }); categoryElement.querySelectorAll('.dataMaidItemDelete').forEach(button => { button.addEventListener('click', async () => { diff --git a/public/scripts/extensions/assets/index.js b/public/scripts/extensions/assets/index.js index 9458c8298..4dad9ac15 100644 --- a/public/scripts/extensions/assets/index.js +++ b/public/scripts/extensions/assets/index.js @@ -94,8 +94,7 @@ async function downloadAssetsList(url) { updateCurrentAssets().then(async function () { fetch(url, { cache: 'no-cache' }) .then(response => response.json()) - .then(async function(json) { - + .then(async function (json) { availableAssets = {}; $('#assets_menu').empty(); diff --git a/public/scripts/extensions/expressions/index.js b/public/scripts/extensions/expressions/index.js index b76edc21c..a2f627882 100644 --- a/public/scripts/extensions/expressions/index.js +++ b/public/scripts/extensions/expressions/index.js @@ -1414,7 +1414,6 @@ export async function getExpressionsList({ filterAvailable = false } = {}) { }); if (apiResult.ok) { - const data = await apiResult.json(); expressionsList = data.labels; return expressionsList; @@ -1488,7 +1487,6 @@ function chooseSpriteForExpression(spriteFolderName, expression, { prevExpressio } return spriteFile; - } /** @@ -2333,7 +2331,7 @@ function migrateSettings() { name: 'expression-folder-override', aliases: ['spriteoverride', 'costume'], callback: setSpriteFolderCommand, - namedArgumentList:[ + namedArgumentList: [ SlashCommandNamedArgument.fromProps({ name: 'name', description: 'Character name to set a subfolder for. If not provided, the character who last sent a message will be used.', diff --git a/public/scripts/extensions/gallery/index.js b/public/scripts/extensions/gallery/index.js index 665cd4c7e..9abd5bc9d 100644 --- a/public/scripts/extensions/gallery/index.js +++ b/public/scripts/extensions/gallery/index.js @@ -791,7 +791,6 @@ async function listGalleryCommand(args) { const items = await getGalleryItems(url); return JSON.stringify(items.map(it => it.src)); - } catch (err) { console.error(err); } diff --git a/public/scripts/extensions/quick-reply/api/QuickReplyApi.js b/public/scripts/extensions/quick-reply/api/QuickReplyApi.js index 926003634..8755b5bf1 100644 --- a/public/scripts/extensions/quick-reply/api/QuickReplyApi.js +++ b/public/scripts/extensions/quick-reply/api/QuickReplyApi.js @@ -10,22 +10,18 @@ export class QuickReplyApi { /** @type {SettingsUi} */ settingsUi; - - constructor(/** @type {QuickReplySettings} */settings, /** @type {SettingsUi} */settingsUi) { this.settings = settings; this.settingsUi = settingsUi; } - - /** * @param {QuickReply} qr * @returns {QuickReplySet} */ getSetByQr(qr) { - return QuickReplySet.list.find(it=>it.qrList.includes(qr)); + return QuickReplySet.list.find(it => it.qrList.includes(qr)); } /** @@ -48,13 +44,11 @@ export class QuickReplyApi { getQrByLabel(setName, label) { const set = this.getSetByName(setName); if (!set) return; - if (Number.isInteger(label)) return set.qrList.find(it=>it.id == label); - return set.qrList.find(it=>it.label == label); + if (Number.isInteger(label)) return set.qrList.find(it => it.id == label); + return set.qrList.find(it => it.label == label); } - - /** * Executes a quick reply by its index and returns the result. * @@ -63,7 +57,7 @@ export class QuickReplyApi { */ async executeQuickReplyByIndex(idx) { const qr = [...this.settings.config.setList, ...(this.settings.chatConfig?.setList ?? [])] - .map(it=>it.set.qrList) + .map(it => it.set.qrList) .flat()[idx] ; if (qr) { @@ -400,7 +394,7 @@ export class QuickReplyApi { if (oldSet) { QuickReplySet.list.splice(QuickReplySet.list.indexOf(oldSet), 1, set); } else { - const idx = QuickReplySet.list.findIndex(it=>it.name.localeCompare(name) == 1); + const idx = QuickReplySet.list.findIndex(it => it.name.localeCompare(name) == 1); if (idx > -1) { QuickReplySet.list.splice(idx, 0, set); } else { @@ -460,7 +454,7 @@ export class QuickReplyApi { * @returns array with the names of all quick reply sets */ listSets() { - return QuickReplySet.list.map(it=>it.name); + return QuickReplySet.list.map(it => it.name); } /** * Gets a list of all globally active quick reply sets. @@ -468,7 +462,7 @@ export class QuickReplyApi { * @returns array with the names of all quick reply sets */ listGlobalSets() { - return this.settings.config.setList.map(it=>it.set.name); + return this.settings.config.setList.map(it => it.set.name); } /** * Gets a list of all quick reply sets activated by the current chat. @@ -476,7 +470,7 @@ export class QuickReplyApi { * @returns array with the names of all quick reply sets */ listChatSets() { - return this.settings.chatConfig?.setList?.flatMap(it=>it.set.name) ?? []; + return this.settings.chatConfig?.setList?.flatMap(it => it.set.name) ?? []; } /** @@ -490,7 +484,7 @@ export class QuickReplyApi { if (!set) { throw new Error(`No quick reply set with name "${name}" found.`); } - return set.qrList.map(it=>it.label); + return set.qrList.map(it => it.label); } /** diff --git a/public/scripts/extensions/quick-reply/index.js b/public/scripts/extensions/quick-reply/index.js index e72e6a5cd..42d5f2289 100644 --- a/public/scripts/extensions/quick-reply/index.js +++ b/public/scripts/extensions/quick-reply/index.js @@ -14,8 +14,6 @@ import { selected_group } from '../../group-chats.js'; export { debounceAsync }; - - const _VERBOSE = true; export const debug = (...msg) => _VERBOSE ? console.debug('[QR2]', ...msg) : null; export const log = (...msg) => _VERBOSE ? console.log('[QR2]', ...msg) : null; @@ -54,8 +52,6 @@ let autoExec; export let quickReplyApi; - - const loadSets = async () => { const response = await fetch('/api/settings/get', { method: 'POST', @@ -72,7 +68,7 @@ const loadSets = async () => { set.disableSend = set.quickActionEnabled ?? false; set.placeBeforeInput = set.placeBeforeInputEnabled ?? false; set.injectInput = set.AutoInputInject ?? false; - set.qrList = set.quickReplySlots.map((slot,idx)=>{ + set.qrList = set.quickReplySlots.map((slot, idx) => { const qr = {}; qr.id = idx + 1; qr.label = slot.label ?? ''; @@ -87,7 +83,7 @@ const loadSets = async () => { qr.executeOnNewChat = slot.autoExecute_newChat ?? false; qr.executeBeforeGeneration = slot.autoExecute_beforeGeneration ?? false; qr.automationId = slot.automationId ?? ''; - qr.contextList = (slot.contextMenu ?? []).map(it=>({ + qr.contextList = (slot.contextMenu ?? []).map(it => ({ set: it.preset, isChained: it.chain, })); @@ -99,8 +95,8 @@ const loadSets = async () => { } } // need to load QR lists after all sets are loaded to be able to resolve context menu entries - setList.forEach((set, idx)=>{ - QuickReplySet.list[idx].qrList = set.qrList.map(it=>QuickReply.from(it)); + setList.forEach((set, idx) => { + QuickReplySet.list[idx].qrList = set.qrList.map(it => QuickReply.from(it)); QuickReplySet.list[idx].init(); }); log('sets: ', QuickReplySet.list); @@ -140,7 +136,7 @@ const executeIfReadyElseQueue = async (functionToCall, args) => { await functionToCall(...args); } else { log('queueing', { functionToCall, args }); - executeQueue.push(async()=>await functionToCall(...args)); + executeQueue.push(async () => await functionToCall(...args)); } }; @@ -183,9 +179,9 @@ const init = async () => { buttons = new ButtonUi(settings); buttons.show(); - settings.onSave = ()=>buttons.refresh(); + settings.onSave = () => buttons.refresh(); - globalThis.executeQuickReplyByName = async(name, args = {}, options = {}) => { + globalThis.executeQuickReplyByName = async (name, args = {}, options = {}) => { let qr = [ ...settings.config.setList, ...(settings.chatConfig?.setList ?? []), @@ -193,14 +189,14 @@ const init = async () => { ] .map(it => it.set.qrList) .flat() - .find(it=>it.label == name) + .find(it => it.label == name) ; if (!qr) { let [setName, ...qrName] = name.split('.'); qrName = qrName.join('.'); let qrs = QuickReplySet.get(setName); if (qrs) { - qr = qrs.qrList.find(it=>it.label == qrName); + qr = qrs.qrList.find(it => it.label == qrName); } } if (qr && qr.onExecute) { @@ -215,7 +211,7 @@ const init = async () => { slash.init(); autoExec = new AutoExecuteHandler(settings); - eventSource.on(event_types.APP_READY, async()=>await finalizeInit()); + eventSource.on(event_types.APP_READY, async () => await finalizeInit()); globalThis.quickReplyApi = quickReplyApi; }; @@ -275,14 +271,14 @@ const onChatChanged = async (chatIdx) => { await autoExec.handleChatChanged(); }; -eventSource.on(event_types.CHAT_CHANGED, (...args)=>executeIfReadyElseQueue(onChatChanged, args)); +eventSource.on(event_types.CHAT_CHANGED, (...args) => executeIfReadyElseQueue(onChatChanged, args)); eventSource.on(event_types.CHARACTER_DELETED, purgeCharacterQuickReplySets); eventSource.on(event_types.CHARACTER_RENAMED, updateCharacterQuickReplySets); const onUserMessage = async () => { await autoExec.handleUser(); }; -eventSource.makeFirst(event_types.USER_MESSAGE_RENDERED, (...args)=>executeIfReadyElseQueue(onUserMessage, args)); +eventSource.makeFirst(event_types.USER_MESSAGE_RENDERED, (...args) => executeIfReadyElseQueue(onUserMessage, args)); const onAiMessage = async (messageId) => { if (['...'].includes(chat[messageId]?.mes)) { @@ -292,7 +288,7 @@ const onAiMessage = async (messageId) => { await autoExec.handleAi(); }; -eventSource.makeFirst(event_types.CHARACTER_MESSAGE_RENDERED, (...args)=>executeIfReadyElseQueue(onAiMessage, args)); +eventSource.makeFirst(event_types.CHARACTER_MESSAGE_RENDERED, (...args) => executeIfReadyElseQueue(onAiMessage, args)); const onGroupMemberDraft = async () => { await autoExec.handleGroupMemberDraft(); diff --git a/public/scripts/extensions/quick-reply/src/AutoExecuteHandler.js b/public/scripts/extensions/quick-reply/src/AutoExecuteHandler.js index 85cfd02ac..5318b3833 100644 --- a/public/scripts/extensions/quick-reply/src/AutoExecuteHandler.js +++ b/public/scripts/extensions/quick-reply/src/AutoExecuteHandler.js @@ -8,8 +8,6 @@ export class AutoExecuteHandler { /** @type {Boolean[]}*/ preventAutoExecuteStack = []; - - constructor(/** @type {QuickReplySettings} */settings) { this.settings = settings; } @@ -20,13 +18,11 @@ export class AutoExecuteHandler { } - - async performAutoExecute(/** @type {QuickReply[]} */qrList) { for (const qr of qrList) { this.preventAutoExecuteStack.push(qr.preventAutoExecute); try { - await qr.execute({ isAutoExecute:true }); + await qr.execute({ isAutoExecute: true }); } catch (ex) { warn(ex); } finally { diff --git a/public/scripts/extensions/quick-reply/src/QuickReply.js b/public/scripts/extensions/quick-reply/src/QuickReply.js index 2f3a87ff1..acb1eb78a 100644 --- a/public/scripts/extensions/quick-reply/src/QuickReply.js +++ b/public/scripts/extensions/quick-reply/src/QuickReply.js @@ -22,13 +22,11 @@ export class QuickReply { * @param {{ id?: number; contextList?: any; }} props */ static from(props) { - props.contextList = (props.contextList ?? []).map((/** @type {any} */ it)=>QuickReplyContextLink.from(it)); + props.contextList = (props.contextList ?? []).map((/** @type {any} */ it) => QuickReplyContextLink.from(it)); return Object.assign(new this(), props); } - - /**@type {number}*/ id; /**@type {string}*/ icon; /**@type {string}*/ label = ''; @@ -89,8 +87,6 @@ export class QuickReply { } - - unrender() { this.dom?.remove(); this.dom = null; @@ -129,7 +125,7 @@ export class QuickReply { menu.show(evt); } }); - root.addEventListener('click', (evt)=>{ + root.addEventListener('click', (evt) => { if (evt.ctrlKey) { this.showEditor(); return; @@ -169,8 +165,6 @@ export class QuickReply { } - - renderSettings(idx) { if (!this.settingsDom) { const item = document.createElement('div'); { @@ -190,7 +184,7 @@ export class QuickReply { addNew.classList.add('fa-solid'); addNew.classList.add('fa-plus'); addNew.title = 'Add quick reply'; - addNew.addEventListener('click', ()=>this.onInsertBefore()); + addNew.addEventListener('click', () => this.onInsertBefore()); actions.append(addNew); } const paste = document.createElement('div'); { @@ -201,7 +195,7 @@ export class QuickReply { paste.classList.add('fa-solid'); paste.classList.add('fa-paste'); paste.title = 'Add quick reply from clipboard'; - paste.addEventListener('click', async()=>{ + paste.addEventListener('click', async () => { const text = await navigator.clipboard.readText(); this.onInsertBefore(text); }); @@ -215,11 +209,11 @@ export class QuickReply { importFile.classList.add('fa-solid'); importFile.classList.add('fa-file-import'); importFile.title = 'Add quick reply from JSON file'; - importFile.addEventListener('click', async()=>{ + importFile.addEventListener('click', async () => { const inp = document.createElement('input'); { inp.type = 'file'; inp.accept = '.json'; - inp.addEventListener('change', async()=>{ + inp.addEventListener('change', async () => { if (inp.files.length > 0) { for (const file of inp.files) { const text = await file.text(); @@ -256,7 +250,7 @@ export class QuickReply { icon.classList.add('fa-solid'); icon.classList.add(this.icon); } - icon.addEventListener('click', async()=>{ + icon.addEventListener('click', async () => { let value = await showFontAwesomePicker(); this.updateIcon(value); }); @@ -267,7 +261,7 @@ export class QuickReply { lbl.classList.add('qr--set-itemLabel'); lbl.classList.add('text_pole'); lbl.value = this.label; - lbl.addEventListener('input', ()=>this.updateLabel(lbl.value)); + lbl.addEventListener('input', () => this.updateLabel(lbl.value)); lblContainer.append(lbl); } itemContent.append(lblContainer); @@ -283,7 +277,7 @@ export class QuickReply { opt.classList.add('fa-solid'); opt.textContent = '⁝'; opt.title = 'Additional options:\n - large editor\n - context menu\n - auto-execution\n - tooltip'; - opt.addEventListener('click', ()=>this.showEditor()); + opt.addEventListener('click', () => this.showEditor()); optContainer.append(opt); } itemContent.append(optContainer); @@ -294,7 +288,7 @@ export class QuickReply { mes.classList.add('qr--set-itemMessage'); mes.value = this.message; //HACK need to use jQuery to catch the triggered event from the expanded editor - $(mes).on('input', ()=>this.updateMessage(mes.value)); + $(mes).on('input', () => this.updateMessage(mes.value)); itemContent.append(mes); } const actions = document.createElement('div'); { @@ -306,7 +300,7 @@ export class QuickReply { move.classList.add('fa-solid'); move.classList.add('fa-truck-arrow-right'); move.title = 'Move quick reply to other set'; - move.addEventListener('click', ()=>this.onTransfer(this)); + move.addEventListener('click', () => this.onTransfer(this)); actions.append(move); } const copy = document.createElement('div'); { @@ -316,7 +310,7 @@ export class QuickReply { copy.classList.add('fa-solid'); copy.classList.add('fa-copy'); copy.title = 'Copy quick reply to clipboard'; - copy.addEventListener('click', async()=>{ + copy.addEventListener('click', async () => { await navigator.clipboard.writeText(JSON.stringify(this)); copy.classList.add('qr--success'); await delay(3010); @@ -331,7 +325,7 @@ export class QuickReply { cut.classList.add('fa-solid'); cut.classList.add('fa-cut'); cut.title = 'Cut quick reply to clipboard (copy and remove)'; - cut.addEventListener('click', async()=>{ + cut.addEventListener('click', async () => { await navigator.clipboard.writeText(JSON.stringify(this)); this.delete(); }); @@ -344,8 +338,8 @@ export class QuickReply { exp.classList.add('fa-solid'); exp.classList.add('fa-file-export'); exp.title = 'Export quick reply as file'; - exp.addEventListener('click', ()=>{ - const blob = new Blob([JSON.stringify(this)], { type:'text' }); + exp.addEventListener('click', () => { + const blob = new Blob([JSON.stringify(this)], { type: 'text' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); { a.href = url; @@ -363,7 +357,7 @@ export class QuickReply { del.classList.add('fa-trash-can'); del.classList.add('redWarningBG'); del.title = 'Remove Quick Reply\n---\nShift+Click to skip confirmation'; - del.addEventListener('click', async(evt)=>{ + del.addEventListener('click', async (evt) => { if (!evt.shiftKey) { const result = await Popup.show.confirm( 'Remove Quick Reply', @@ -408,7 +402,7 @@ export class QuickReply { else { icon.textContent = '…'; } - icon.addEventListener('click', async()=>{ + icon.addEventListener('click', async () => { let value = await showFontAwesomePicker(); if (value === null) return; if (this.icon) icon.classList.remove(this.icon); @@ -425,18 +419,18 @@ export class QuickReply { /**@type {HTMLInputElement}*/ const showLabel = dom.querySelector('#qr--modal-showLabel'); showLabel.checked = this.showLabel; - showLabel.addEventListener('click', ()=>{ + showLabel.addEventListener('click', () => { this.updateShowLabel(showLabel.checked); }); /**@type {HTMLInputElement}*/ const label = dom.querySelector('#qr--modal-label'); label.value = this.label; - label.addEventListener('input', ()=>{ + label.addEventListener('input', () => { this.updateLabel(label.value); }); let switcherList; // @ts-ignore - dom.querySelector('#qr--modal-switcher').addEventListener('click', (evt)=>{ + dom.querySelector('#qr--modal-switcher').addEventListener('click', (evt) => { if (switcherList) { switcherList.remove(); switcherList = null; @@ -445,15 +439,15 @@ export class QuickReply { const list = document.createElement('ul'); { switcherList = list; list.classList.add('qr--modal-switcherList'); - const makeList = (qrs)=>{ + const makeList = (qrs) => { const setItem = document.createElement('li'); { setItem.classList.add('qr--modal-switcherItem'); - setItem.addEventListener('click', ()=>{ + setItem.addEventListener('click', () => { list.innerHTML = ''; for (const qrs of quickReplyApi.listSets()) { const item = document.createElement('li'); { item.classList.add('qr--modal-switcherItem'); - item.addEventListener('click', ()=>{ + item.addEventListener('click', () => { list.innerHTML = ''; makeList(quickReplyApi.getSetByName(qrs)); }); @@ -484,7 +478,7 @@ export class QuickReply { } const addItem = document.createElement('li'); { addItem.classList.add('qr--modal-switcherItem'); - addItem.addEventListener('click', ()=>{ + addItem.addEventListener('click', () => { const qr = quickReplyApi.getSetByQr(this).addQuickReply(); this.editorPopup.completeAffirmative(); qr.showEditor(); @@ -505,11 +499,11 @@ export class QuickReply { } list.append(addItem); } - for (const qr of qrs.qrList.toSorted((a,b)=>a.label.toLowerCase().localeCompare(b.label.toLowerCase()))) { + for (const qr of qrs.qrList.toSorted((a, b) => a.label.toLowerCase().localeCompare(b.label.toLowerCase()))) { const item = document.createElement('li'); { item.classList.add('qr--modal-switcherItem'); if (qr == this) item.classList.add('qr--current'); - else item.addEventListener('click', ()=>{ + else item.addEventListener('click', () => { this.editorPopup.completeAffirmative(); qr.showEditor(); }); @@ -588,7 +582,7 @@ export class QuickReply { }); }; const updateScrollDebounced = updateScroll; - const updateSyntaxEnabled = ()=>{ + const updateSyntaxEnabled = () => { if (syntax.checked) { dom.querySelector('#qr--modal-messageHolder').classList.remove('qr--noSyntax'); } else { @@ -623,7 +617,7 @@ export class QuickReply { // @ts-ignore if (navigator.keyboard) { // @ts-ignore - navigator.keyboard.getLayoutMap().then(it=>dom.querySelector('#qr--modal-commentKey').textContent = it.get('Backslash')); + navigator.keyboard.getLayoutMap().then(it => dom.querySelector('#qr--modal-commentKey').textContent = it.get('Backslash')); } else { dom.querySelector('#qr--modal-commentKey').closest('small').remove(); } @@ -632,12 +626,12 @@ export class QuickReply { const message = dom.querySelector('#qr--modal-message'); this.editorMessage = message; message.value = this.message; - const updateMessageDebounced = debounce((value)=>this.updateMessage(value), 10); + const updateMessageDebounced = debounce((value) => this.updateMessage(value), 10); message.addEventListener('input', () => { updateMessageDebounced(message.value); updateScrollDebounced(); - }, { passive:true }); - const getLineStart = ()=>{ + }, { passive: true }); + const getLineStart = () => { const start = message.selectionStart; let lineStart; if (start == 0 || message.value[start - 1] == '\n') { @@ -651,7 +645,7 @@ export class QuickReply { } return lineStart; }; - message.addEventListener('keydown', async(evt) => { + message.addEventListener('keydown', async (evt) => { if (this.isExecuting) return; if (evt.key == 'Tab' && !evt.shiftKey && !evt.ctrlKey && !evt.altKey) { // increase indent @@ -668,13 +662,13 @@ export class QuickReply { document.execCommand('insertText', false, `\t${affectedLines.join('\n\t')}`); message.selectionStart = start + 1; message.selectionEnd = end + affectedLines.length; - message.dispatchEvent(new Event('input', { bubbles:true })); + message.dispatchEvent(new Event('input', { bubbles: true })); } else if (!(ac.isReplaceable && ac.isActive)) { evt.stopImmediatePropagation(); evt.stopPropagation(); // document.execCommand is deprecated (and potentially buggy in some browsers) but the only way to retain undo-history document.execCommand('insertText', false, '\t'); - message.dispatchEvent(new Event('input', { bubbles:true })); + message.dispatchEvent(new Event('input', { bubbles: true })); } } else if (evt.key == 'Tab' && evt.shiftKey && !evt.ctrlKey && !evt.altKey) { // decrease indent @@ -686,7 +680,7 @@ export class QuickReply { const lineStart = getLineStart(); message.selectionStart = lineStart; const affectedLines = message.value.substring(lineStart, end).split('\n'); - const newText = affectedLines.map(it=>it.replace(/^\t/, '')).join('\n'); + const newText = affectedLines.map(it => it.replace(/^\t/, '')).join('\n'); const delta = affectedLines.join('\n').length - newText.length; // document.execCommand is deprecated (and potentially buggy in some browsers) but the only way to retain undo-history if (delta > 0) { @@ -697,7 +691,7 @@ export class QuickReply { } message.selectionStart = start - (affectedLines[0].startsWith('\t') ? 1 : 0); message.selectionEnd = end - delta; - message.dispatchEvent(new Event('input', { bubbles:true })); + message.dispatchEvent(new Event('input', { bubbles: true })); } else { message.selectionStart = start; } @@ -714,7 +708,7 @@ export class QuickReply { document.execCommand('insertText', false, `\n${indent}`); message.selectionStart = start + 1 + indent.length; message.selectionEnd = message.selectionStart; - message.dispatchEvent(new Event('input', { bubbles:true })); + message.dispatchEvent(new Event('input', { bubbles: true })); } } else if (evt.key == 'Enter' && evt.ctrlKey && !evt.shiftKey && !evt.altKey) { if (executeShortcut.checked) { @@ -751,7 +745,7 @@ export class QuickReply { parser.parse(message.value, false); const start = message.selectionStart; const end = message.selectionEnd; - const comment = parser.commandIndex.findLast(it=>it.name == '*' && (it.start <= start && it.end >= start || it.start <= end && it.end >= end)); + const comment = parser.commandIndex.findLast(it => it.name == '*' && (it.start <= start && it.end >= start || it.start <= end && it.end >= end)); if (comment) { // uncomment let content = message.value.slice(comment.start + 1, comment.end - 1); @@ -778,15 +772,15 @@ export class QuickReply { message.selectionStart = start + 3; message.selectionEnd = end + 3; } - message.dispatchEvent(new Event('input', { bubbles:true })); + message.dispatchEvent(new Event('input', { bubbles: true })); } }); const ac = await setSlashCommandAutoComplete(message, true); - message.addEventListener('wheel', (evt)=>{ + message.addEventListener('wheel', (evt) => { updateScrollDebounced(evt); }); // @ts-ignore - message.addEventListener('scroll', (evt)=>{ + message.addEventListener('scroll', (evt) => { updateScrollDebounced(); }); let preBreakPointStart; @@ -794,7 +788,7 @@ export class QuickReply { /** * @param {SlashCommandBreakPoint} bp */ - const removeBreakpoint = (bp)=>{ + const removeBreakpoint = (bp) => { // start at -1 because "/" is not included in start-end let start = bp.start - 1; // step left until forward slash "/" @@ -812,7 +806,7 @@ export class QuickReply { message.selectionEnd = end; // document.execCommand is deprecated (and potentially buggy in some browsers) but the only way to retain undo-history document.execCommand('insertText', false, ''); - message.dispatchEvent(new Event('input', { bubbles:true })); + message.dispatchEvent(new Event('input', { bubbles: true })); let postStart = preBreakPointStart; let postEnd = preBreakPointEnd; // set caret back to where it was @@ -834,12 +828,12 @@ export class QuickReply { // selection end was behind breakpoint: move back by length of removed string postEnd = preBreakPointEnd - (end - start); } - return { start:postStart, end:postEnd }; + return { start: postStart, end: postEnd }; }; /** * @param {SlashCommandExecutor} cmd */ - const addBreakpoint = (cmd)=>{ + const addBreakpoint = (cmd) => { // start at -1 because "/" is not included in start-end let start = cmd.start - 1; let indent = ''; @@ -860,16 +854,16 @@ export class QuickReply { message.selectionEnd = start; // document.execCommand is deprecated (and potentially buggy in some browsers) but the only way to retain undo-history document.execCommand('insertText', false, breakpointText); - message.dispatchEvent(new Event('input', { bubbles:true })); + message.dispatchEvent(new Event('input', { bubbles: true })); return breakpointText.length; }; - const toggleBreakpoint = ()=>{ + const toggleBreakpoint = () => { const idx = message.selectionStart; let postStart = preBreakPointStart; let postEnd = preBreakPointEnd; const parser = new SlashCommandParser(); parser.parse(message.value, false); - const cmdIdx = parser.commandIndex.findLastIndex(it=>it.start <= idx); + const cmdIdx = parser.commandIndex.findLastIndex(it => it.start <= idx); if (cmdIdx > -1) { const cmd = parser.commandIndex[cmdIdx]; if (cmd instanceof SlashCommandBreakPoint) { @@ -891,12 +885,12 @@ export class QuickReply { message.selectionEnd = postEnd; } }; - message.addEventListener('pointerdown', (evt)=>{ + message.addEventListener('pointerdown', (evt) => { if (!evt.ctrlKey || !evt.altKey) return; preBreakPointStart = message.selectionStart; preBreakPointEnd = message.selectionEnd; }); - message.addEventListener('pointerup', async(evt)=>{ + message.addEventListener('pointerup', async (evt) => { if (!evt.ctrlKey || !evt.altKey || message.selectionStart != message.selectionEnd) return; toggleBreakpoint(); }); @@ -910,11 +904,11 @@ export class QuickReply { }); window.addEventListener('resize', resizeListener); updateSyntaxEnabled(); - const updateSyntax = ()=>{ + const updateSyntax = () => { if (messageSyntaxInner && syntax.checked) { morphdom( messageSyntaxInner, - `
${hljs.highlight(`${message.value}${message.value.slice(-1) == '\n' ? ' ' : ''}`, { language:'stscript', ignoreIllegals:true })?.value}
`, + `
${hljs.highlight(`${message.value}${message.value.slice(-1) == '\n' ? ' ' : ''}`, { language: 'stscript', ignoreIllegals: true })?.value}
`, { childrenOnly: true }, ); updateScrollDebounced(); @@ -924,7 +918,7 @@ export class QuickReply { const fpsTime = 1000 / 30; let lastMessageValue = null; let wasSyntax = null; - const updateSyntaxLoop = ()=>{ + const updateSyntaxLoop = () => { const now = Date.now(); // fps limit if (now - lastSyntaxUpdate < fpsTime) return requestAnimationFrame(updateSyntaxLoop); @@ -945,7 +939,7 @@ export class QuickReply { updateSyntax(); requestAnimationFrame(updateSyntaxLoop); }; - requestAnimationFrame(()=>updateSyntaxLoop()); + requestAnimationFrame(() => updateSyntaxLoop()); message.style.setProperty('text-shadow', 'none', 'important'); updateWrap(); updateTabSize(); @@ -955,7 +949,7 @@ export class QuickReply { const tpl = dom.querySelector('#qr--ctxItem'); const linkList = dom.querySelector('#qr--ctxEditor'); const fillQrSetSelect = (/**@type {HTMLSelectElement}*/select, /**@type {QuickReplyContextLink}*/ link) => { - [{ name: 'Select a QR set' }, ...QuickReplySet.list.toSorted((a,b)=>a.name.toLowerCase().localeCompare(b.name.toLowerCase()))].forEach(qrs => { + [{ name: 'Select a QR set' }, ...QuickReplySet.list.toSorted((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()))].forEach(qrs => { const opt = document.createElement('option'); { opt.value = qrs.name; opt.textContent = qrs.name; @@ -1002,7 +996,7 @@ export class QuickReply { addCtxItem(link, this.contextList.length - 1); }); const onContextSort = () => { - this.contextList = Array.from(linkList.querySelectorAll('.qr--ctxItem')).map((it,idx) => { + this.contextList = Array.from(linkList.querySelectorAll('.qr--ctxItem')).map((it, idx) => { const link = this.contextList[Number(it.getAttribute('data-order'))]; it.setAttribute('data-order', String(idx)); return link; @@ -1019,63 +1013,63 @@ export class QuickReply { /**@type {HTMLInputElement}*/ const preventAutoExecute = dom.querySelector('#qr--preventAutoExecute'); preventAutoExecute.checked = this.preventAutoExecute; - preventAutoExecute.addEventListener('click', ()=>{ + preventAutoExecute.addEventListener('click', () => { this.preventAutoExecute = preventAutoExecute.checked; this.updateContext(); }); /**@type {HTMLInputElement}*/ const isHidden = dom.querySelector('#qr--isHidden'); isHidden.checked = this.isHidden; - isHidden.addEventListener('click', ()=>{ + isHidden.addEventListener('click', () => { this.isHidden = isHidden.checked; this.updateContext(); }); /**@type {HTMLInputElement}*/ const executeOnStartup = dom.querySelector('#qr--executeOnStartup'); executeOnStartup.checked = this.executeOnStartup; - executeOnStartup.addEventListener('click', ()=>{ + executeOnStartup.addEventListener('click', () => { this.executeOnStartup = executeOnStartup.checked; this.updateContext(); }); /**@type {HTMLInputElement}*/ const executeOnUser = dom.querySelector('#qr--executeOnUser'); executeOnUser.checked = this.executeOnUser; - executeOnUser.addEventListener('click', ()=>{ + executeOnUser.addEventListener('click', () => { this.executeOnUser = executeOnUser.checked; this.updateContext(); }); /**@type {HTMLInputElement}*/ const executeOnAi = dom.querySelector('#qr--executeOnAi'); executeOnAi.checked = this.executeOnAi; - executeOnAi.addEventListener('click', ()=>{ + executeOnAi.addEventListener('click', () => { this.executeOnAi = executeOnAi.checked; this.updateContext(); }); /**@type {HTMLInputElement}*/ const executeOnChatChange = dom.querySelector('#qr--executeOnChatChange'); executeOnChatChange.checked = this.executeOnChatChange; - executeOnChatChange.addEventListener('click', ()=>{ + executeOnChatChange.addEventListener('click', () => { this.executeOnChatChange = executeOnChatChange.checked; this.updateContext(); }); /**@type {HTMLInputElement}*/ const executeOnGroupMemberDraft = dom.querySelector('#qr--executeOnGroupMemberDraft'); executeOnGroupMemberDraft.checked = this.executeOnGroupMemberDraft; - executeOnGroupMemberDraft.addEventListener('click', ()=>{ + executeOnGroupMemberDraft.addEventListener('click', () => { this.executeOnGroupMemberDraft = executeOnGroupMemberDraft.checked; this.updateContext(); }); /**@type {HTMLInputElement}*/ const executeBeforeGeneration = dom.querySelector('#qr--executeBeforeGeneration'); executeBeforeGeneration.checked = this.executeBeforeGeneration; - executeBeforeGeneration.addEventListener('click', ()=>{ + executeBeforeGeneration.addEventListener('click', () => { this.executeBeforeGeneration = executeBeforeGeneration.checked; this.updateContext(); }); /**@type {HTMLInputElement}*/ const executeOnNewChat = dom.querySelector('#qr--executeOnNewChat'); executeOnNewChat.checked = this.executeOnNewChat; - executeOnNewChat.addEventListener('click', ()=>{ + executeOnNewChat.addEventListener('click', () => { this.executeOnNewChat = executeOnNewChat.checked; this.updateContext(); }); @@ -1102,13 +1096,13 @@ export class QuickReply { /**@type {HTMLElement}*/ const executeBtn = dom.querySelector('#qr--modal-execute'); this.editorExecuteBtn = executeBtn; - executeBtn.addEventListener('click', async()=>{ + executeBtn.addEventListener('click', async () => { await this.executeFromEditor(); }); /**@type {HTMLElement}*/ const executeBtnPause = dom.querySelector('#qr--modal-pause'); this.editorExecuteBtnPause = executeBtnPause; - executeBtnPause.addEventListener('click', async()=>{ + executeBtnPause.addEventListener('click', async () => { if (this.abortController) { if (this.abortController.signal.paused) { this.abortController.continue('Continue button clicked'); @@ -1122,7 +1116,7 @@ export class QuickReply { /**@type {HTMLElement}*/ const executeBtnStop = dom.querySelector('#qr--modal-stop'); this.editorExecuteBtnStop = executeBtnStop; - executeBtnStop.addEventListener('click', async()=>{ + executeBtnStop.addEventListener('click', async () => { this.abortController?.abort('Stop button clicked'); }); @@ -1131,49 +1125,49 @@ export class QuickReply { const inputMirror = dom.querySelector('#qr--modal-send_textarea'); // @ts-ignore inputMirror.value = inputOg.value; - const inputOgMo = new MutationObserver(muts=>{ - if (muts.find(it=>[...it.removedNodes].includes(inputMirror) || [...it.removedNodes].find(n=>n.contains(inputMirror)))) { + const inputOgMo = new MutationObserver(muts => { + if (muts.find(it => [...it.removedNodes].includes(inputMirror) || [...it.removedNodes].find(n => n.contains(inputMirror)))) { inputOg.removeEventListener('input', inputOgListener); } }); - inputOgMo.observe(document.body, { childList:true }); - const inputOgListener = ()=>{ + inputOgMo.observe(document.body, { childList: true }); + const inputOgListener = () => { // @ts-ignore inputMirror.value = inputOg.value; }; inputOg.addEventListener('input', inputOgListener); - inputMirror.addEventListener('input', ()=>{ + inputMirror.addEventListener('input', () => { // @ts-ignore inputOg.value = inputMirror.value; }); /**@type {HTMLElement}*/ const resumeBtn = dom.querySelector('#qr--modal-resume'); - resumeBtn.addEventListener('click', ()=>{ + resumeBtn.addEventListener('click', () => { this.debugController?.resume(); }); /**@type {HTMLElement}*/ const stepBtn = dom.querySelector('#qr--modal-step'); - stepBtn.addEventListener('click', ()=>{ + stepBtn.addEventListener('click', () => { this.debugController?.step(); }); /**@type {HTMLElement}*/ const stepIntoBtn = dom.querySelector('#qr--modal-stepInto'); - stepIntoBtn.addEventListener('click', ()=>{ + stepIntoBtn.addEventListener('click', () => { this.debugController?.stepInto(); }); /**@type {HTMLElement}*/ const stepOutBtn = dom.querySelector('#qr--modal-stepOut'); - stepOutBtn.addEventListener('click', ()=>{ + stepOutBtn.addEventListener('click', () => { this.debugController?.stepOut(); }); /**@type {HTMLElement}*/ const minimizeBtn = dom.querySelector('#qr--modal-minimize'); - minimizeBtn.addEventListener('click', ()=>{ + minimizeBtn.addEventListener('click', () => { this.editorDom.classList.add('qr--minimized'); }); const maximizeBtn = dom.querySelector('#qr--modal-maximize'); - maximizeBtn.addEventListener('click', ()=>{ + maximizeBtn.addEventListener('click', () => { this.editorDom.classList.remove('qr--minimized'); }); /**@type {boolean}*/ @@ -1182,23 +1176,23 @@ export class QuickReply { let wStart; /**@type {HTMLElement}*/ const resizeHandle = dom.querySelector('#qr--resizeHandle'); - resizeHandle.addEventListener('pointerdown', (evt)=>{ + resizeHandle.addEventListener('pointerdown', (evt) => { if (isResizing) return; isResizing = true; evt.preventDefault(); resizeStart = evt.x; // @ts-ignore wStart = dom.querySelector('#qr--qrOptions').offsetWidth; - const dragListener = debounce((evt)=>{ + const dragListener = debounce((evt) => { const w = wStart + resizeStart - evt.x; // @ts-ignore dom.querySelector('#qr--qrOptions').style.setProperty('--width', `${w}px`); }, 5); - window.addEventListener('pointerup', ()=>{ + window.addEventListener('pointerup', () => { // @ts-ignore window.removeEventListener('pointermove', dragListener); isResizing = false; - }, { once:true }); + }, { once: true }); // @ts-ignore window.addEventListener('pointermove', dragListener); }); @@ -1221,13 +1215,13 @@ export class QuickReply { } this.clone.style.position = 'fixed'; this.clone.style.visibility = 'hidden'; - const mo = new MutationObserver(muts=>{ - if (muts.find(it=>[...it.removedNodes].includes(this.editorMessage) || [...it.removedNodes].find(n=>n.contains(this.editorMessage)))) { + const mo = new MutationObserver(muts => { + if (muts.find(it => [...it.removedNodes].includes(this.editorMessage) || [...it.removedNodes].find(n => n.contains(this.editorMessage)))) { this.clone?.remove(); this.clone = null; } }); - mo.observe(document.body, { childList:true }); + mo.observe(document.body, { childList: true }); } document.body.append(this.clone); this.clone.style.width = `${inputRect.width}px`; @@ -1258,7 +1252,7 @@ export class QuickReply { } async executeFromEditor() { if (this.isExecuting) return; - this.editorPopup.onClosing = ()=>false; + this.editorPopup.onClosing = () => false; const uuidCheck = /^[0-9a-z]{8}(-[0-9a-z]{4}){3}-[0-9a-z]{12}$/; const oText = this.message; this.isExecuting = true; @@ -1298,19 +1292,19 @@ export class QuickReply { }); }; const updateScrollDebounced = updateScroll; - syntax.addEventListener('wheel', (evt)=>{ + syntax.addEventListener('wheel', (evt) => { updateScrollDebounced(evt); }); // @ts-ignore - syntax.addEventListener('scroll', (evt)=>{ + syntax.addEventListener('scroll', (evt) => { updateScrollDebounced(); }); try { this.abortController = new SlashCommandAbortController(); this.debugController = new SlashCommandDebugController(); - this.debugController.onBreakPoint = async(closure, executor)=>{ + this.debugController.onBreakPoint = async (closure, executor) => { this.editorDom.classList.add('qr--isPaused'); - syntax.innerHTML = hljs.highlight(`${closure.fullText}${closure.fullText.slice(-1) == '\n' ? ' ' : ''}`, { language:'stscript', ignoreIllegals:true })?.value; + syntax.innerHTML = hljs.highlight(`${closure.fullText}${closure.fullText.slice(-1) == '\n' ? ' ' : ''}`, { language: 'stscript', ignoreIllegals: true })?.value; this.editorMessageLabel.innerHTML = ''; if (uuidCheck.test(closure.source)) { const p0 = document.createElement('span'); { @@ -1318,7 +1312,7 @@ export class QuickReply { this.editorMessageLabel.append(p0); } const p1 = document.createElement('strong'); { - p1.textContent = executor.source.slice(0,5); + p1.textContent = executor.source.slice(0, 5); this.editorMessageLabel.append(p1); } const p2 = document.createElement('span'); { @@ -1340,7 +1334,7 @@ export class QuickReply { /** * @param {SlashCommandScope} scope */ - const buildVars = (scope, isCurrent = false)=>{ + const buildVars = (scope, isCurrent = false) => { if (!isCurrent) { ci--; } @@ -1358,7 +1352,7 @@ export class QuickReply { } wrap.append(namedTitle); } - const keys = new Set([...Object.keys(this.debugController.namedArguments ?? {}), ...(executor.namedArgumentList ?? []).map(it=>it.name)]); + const keys = new Set([...Object.keys(this.debugController.namedArguments ?? {}), ...(executor.namedArgumentList ?? []).map(it => it.name)]); for (const key of keys) { if (key[0] == '_') continue; const item = document.createElement('div'); { @@ -1371,7 +1365,7 @@ export class QuickReply { const vUnresolved = document.createElement('div'); { vUnresolved.classList.add('qr--val'); vUnresolved.classList.add('qr--singleCol'); - const val = executor.namedArgumentList.find(it=>it.name == key)?.value; + const val = executor.namedArgumentList.find(it => it.name == key)?.value; if (val instanceof SlashCommandClosure) { vUnresolved.classList.add('qr--closure'); vUnresolved.title = val.rawText; @@ -1437,7 +1431,7 @@ export class QuickReply { // @ts-ignore while (unnamed.length < executor.unnamedArgumentList?.length ?? 0) unnamed.push(undefined); // @ts-ignore - unnamed = unnamed.map((it,idx)=>[executor.unnamedArgumentList?.[idx], it]); + unnamed = unnamed.map((it, idx) => [executor.unnamedArgumentList?.[idx], it]); // @ts-ignore for (const arg of unnamed) { i++; @@ -1511,7 +1505,7 @@ export class QuickReply { title.textContent = isCurrent ? 'Current Scope' : 'Parent Scope'; if (c.source == source) { let hi; - title.addEventListener('pointerenter', ()=>{ + title.addEventListener('pointerenter', () => { const loc = this.getEditorPosition(Math.max(0, c.executorList[0].start - 1), c.executorList.slice(-1)[0].end, c.fullText); const layer = syntax.getBoundingClientRect(); hi = document.createElement('div'); @@ -1522,7 +1516,7 @@ export class QuickReply { hi.style.height = `${loc.bottom - loc.top}px`; syntax.append(hi); }); - title.addEventListener('pointerleave', ()=>hi?.remove()); + title.addEventListener('pointerleave', () => hi?.remove()); } wrap.append(title); } @@ -1635,7 +1629,7 @@ export class QuickReply { } return wrap; }; - const buildStack = ()=>{ + const buildStack = () => { const wrap = document.createElement('div'); { wrap.classList.add('qr--stack'); const title = document.createElement('div'); { @@ -1651,7 +1645,7 @@ export class QuickReply { item.classList.add('qr--item'); if (executor.source == source) { let hi; - item.addEventListener('pointerenter', ()=>{ + item.addEventListener('pointerenter', () => { const loc = this.getEditorPosition(Math.max(0, executor.start - 1), executor.end, c.fullText); const layer = syntax.getBoundingClientRect(); hi = document.createElement('div'); @@ -1662,7 +1656,7 @@ export class QuickReply { hi.style.height = `${loc.bottom - loc.top}px`; syntax.append(hi); }); - item.addEventListener('pointerleave', ()=>hi?.remove()); + item.addEventListener('pointerleave', () => hi?.remove()); } const cmd = document.createElement('div'); { cmd.classList.add('qr--cmd'); @@ -1678,7 +1672,7 @@ export class QuickReply { if (uuidCheck.test(executor.source)) { const p1 = document.createElement('span'); { p1.classList.add('qr--fixed'); - p1.textContent = executor.source.slice(0,5); + p1.textContent = executor.source.slice(0, 5); src.append(p1); } const p2 = document.createElement('span'); { @@ -1756,7 +1750,7 @@ export class QuickReply { this.editorMessageLabel.innerHTML = ''; this.editorMessageLabel.textContent = 'Message / Command: '; this.editorMessage.value = oText; - this.editorMessage.dispatchEvent(new Event('input', { bubbles:true })); + this.editorMessage.dispatchEvent(new Event('input', { bubbles: true })); this.editorExecutePromise = null; this.editorExecuteBtn.classList.remove('qr--busy'); this.editorDom.classList.remove('qr--isExecuting'); @@ -1769,8 +1763,6 @@ export class QuickReply { } - - delete() { if (this.onDelete) { this.unrender(); @@ -1870,7 +1862,7 @@ export class QuickReply { this.updateContext(); } removeContextLink(setName) { - const idx = this.contextList.findIndex(it=>it.set.name == setName); + const idx = this.contextList.findIndex(it => it.set.name == setName); if (idx > -1) { this.contextList.splice(idx, 1); this.updateContext(); @@ -1908,8 +1900,6 @@ export class QuickReply { } - - toJSON() { return { id: this.id, diff --git a/public/scripts/extensions/quick-reply/src/QuickReplyConfig.js b/public/scripts/extensions/quick-reply/src/QuickReplyConfig.js index 46ef454b9..460818ca7 100644 --- a/public/scripts/extensions/quick-reply/src/QuickReplyConfig.js +++ b/public/scripts/extensions/quick-reply/src/QuickReplyConfig.js @@ -13,25 +13,21 @@ export class QuickReplyConfig { /**@type {HTMLElement}*/ setListDom; - - static from(props) { - props.setList = props.setList?.map(it=>QuickReplySetLink.from(it))?.filter(it=>it.set) ?? []; + props.setList = props.setList?.map(it => QuickReplySetLink.from(it))?.filter(it => it.set) ?? []; const instance = Object.assign(new this(), props); instance.init(); return instance; } - - init() { - this.setList.forEach(it=>this.hookQuickReplyLink(it)); + this.setList.forEach(it => this.hookQuickReplyLink(it)); } hasSet(qrs) { - return this.setList.find(it=>it.set == qrs) != null; + return this.setList.find(it => it.set == qrs) != null; } addSet(qrs, isVisible = true) { if (!this.hasSet(qrs)) { @@ -45,7 +41,7 @@ export class QuickReplyConfig { } } removeSet(qrs) { - const idx = this.setList.findIndex(it=>it.set == qrs); + const idx = this.setList.findIndex(it => it.set == qrs); if (idx > -1) { this.setList.splice(idx, 1); this.update(); @@ -54,13 +50,11 @@ export class QuickReplyConfig { } - - renderSettingsInto(/**@type {HTMLElement}*/root) { /**@type {HTMLElement}*/ this.setListDom = root.querySelector('.qr--setList'); - root.querySelector('.qr--setListAdd').addEventListener('click', ()=>{ - const newSet = QuickReplySet.list.find(qr=>!this.setList.find(qrl=>qrl.set == qr)); + root.querySelector('.qr--setListAdd').addEventListener('click', () => { + const newSet = QuickReplySet.list.find(qr => !this.setList.find(qrl => qrl.set == qr)); if (newSet) { this.addSet(newSet); } else { @@ -74,14 +68,14 @@ export class QuickReplyConfig { // @ts-ignore $(this.setListDom).sortable({ delay: getSortableDelay(), - stop: ()=>this.onSetListSort(), + stop: () => this.onSetListSort(), }); - this.setList.filter(it=>!it.set.isDeleted).forEach((qrl,idx)=>this.setListDom.append(qrl.renderSettings(idx))); + this.setList.filter(it => !it.set.isDeleted).forEach((qrl, idx) => this.setListDom.append(qrl.renderSettings(idx))); } onSetListSort() { - this.setList = Array.from(this.setListDom.children).map((it,idx)=>{ + this.setList = Array.from(this.setListDom.children).map((it, idx) => { const qrl = this.setList[Number(it.getAttribute('data-order'))]; qrl.index = idx; it.setAttribute('data-order', String(idx)); @@ -91,15 +85,13 @@ export class QuickReplyConfig { } - - /** * @param {QuickReplySetLink} qrl */ hookQuickReplyLink(qrl) { - qrl.onDelete = ()=>this.deleteQuickReplyLink(qrl); - qrl.onUpdate = ()=>this.update(); - qrl.onRequestEditSet = ()=>this.requestEditSet(qrl.set); + qrl.onDelete = () => this.deleteQuickReplyLink(qrl); + qrl.onUpdate = () => this.update(); + qrl.onRequestEditSet = () => this.requestEditSet(qrl.set); } deleteQuickReplyLink(qrl) { diff --git a/public/scripts/extensions/quick-reply/src/QuickReplyContextLink.js b/public/scripts/extensions/quick-reply/src/QuickReplyContextLink.js index a189bba8d..b7ad9af64 100644 --- a/public/scripts/extensions/quick-reply/src/QuickReplyContextLink.js +++ b/public/scripts/extensions/quick-reply/src/QuickReplyContextLink.js @@ -8,8 +8,6 @@ export class QuickReplyContextLink { } - - /**@type {QuickReplySet}*/ set; /**@type {Boolean}*/ isChained = false; diff --git a/public/scripts/extensions/quick-reply/src/QuickReplySet.js b/public/scripts/extensions/quick-reply/src/QuickReplySet.js index 72d38e427..a78e81670 100644 --- a/public/scripts/extensions/quick-reply/src/QuickReplySet.js +++ b/public/scripts/extensions/quick-reply/src/QuickReplySet.js @@ -24,7 +24,7 @@ export class QuickReplySet { * @param {string} name - name of the QuickReplySet */ static get(name) { - return this.list.find(it=>it.name == name); + return this.list.find(it => it.name == name); } /**@type {string}*/ name; @@ -42,11 +42,11 @@ export class QuickReplySet { /**@type {HTMLElement}*/ settingsDom; constructor() { - this.save = debounceAsync(()=>this.performSave(), 200); + this.save = debounceAsync(() => this.performSave(), 200); } init() { - this.qrList.forEach(qr=>this.hookQuickReply(qr)); + this.qrList.forEach(qr => this.hookQuickReply(qr)); } unrender() { @@ -60,7 +60,7 @@ export class QuickReplySet { this.dom = root; root.classList.add('qr--buttons'); this.updateColor(); - this.qrList.filter(qr=>!qr.isHidden).forEach(qr=>{ + this.qrList.filter(qr => !qr.isHidden).forEach(qr => { root.append(qr.render()); }); } @@ -70,7 +70,7 @@ export class QuickReplySet { rerender() { if (!this.dom) return; this.dom.innerHTML = ''; - this.qrList.filter(qr=>!qr.isHidden).forEach(qr=>{ + this.qrList.filter(qr => !qr.isHidden).forEach(qr => { this.dom.append(qr.render()); }); } @@ -95,7 +95,7 @@ export class QuickReplySet { if (!this.settingsDom) { this.settingsDom = document.createElement('div'); { this.settingsDom.classList.add('qr--set-qrListContents'); - this.qrList.forEach((qr,idx)=>{ + this.qrList.forEach((qr, idx) => { this.renderSettingsItem(qr, idx); }); } @@ -138,12 +138,12 @@ export class QuickReplySet { */ async executeWithOptions(qr, options = {}) { options = Object.assign({ - message:null, - isAutoExecute:false, - isEditor:false, - isRun:false, - scope:null, - executionOptions:{}, + message: null, + isAutoExecute: false, + isEditor: false, + isRun: false, + scope: null, + executionOptions: {}, }, options); const execOptions = options.executionOptions; /**@type {HTMLTextAreaElement}*/ @@ -208,9 +208,8 @@ export class QuickReplySet { } addQuickReply(data = {}) { - const id = Math.max(this.idIndex, this.qrList.reduce((max,qr)=>Math.max(max,qr.id),0)) + 1; - data.id = - this.idIndex = id + 1; + const id = Math.max(this.idIndex, this.qrList.reduce((max, qr) => Math.max(max, qr.id), 0)) + 1; + data.id = this.idIndex = id + 1; const qr = QuickReply.from(data); this.qrList.push(qr); this.hookQuickReply(qr); @@ -257,11 +256,11 @@ export class QuickReplySet { */ hookQuickReply(qr) { // @ts-ignore - qr.onDebug = ()=>this.debug(qr); - qr.onExecute = (_, options)=>this.executeWithOptions(qr, options); - qr.onDelete = ()=>this.removeQuickReply(qr); - qr.onUpdate = ()=>this.save(); - qr.onInsertBefore = (qrJson)=>{ + qr.onDebug = () => this.debug(qr); + qr.onExecute = (_, options) => this.executeWithOptions(qr, options); + qr.onDelete = () => this.removeQuickReply(qr); + qr.onUpdate = () => this.save(); + qr.onInsertBefore = (qrJson) => { this.addQuickReplyFromText(qrJson); const newQr = this.qrList.pop(); this.qrList.splice(this.qrList.indexOf(qr), 0, newQr); @@ -270,7 +269,7 @@ export class QuickReplySet { } this.save(); }; - qr.onTransfer = async()=>{ + qr.onTransfer = async () => { /**@type {HTMLSelectElement} */ let sel; let isCopy = false; @@ -301,14 +300,14 @@ export class QuickReplySet { sel.append(opt); } } - sel.addEventListener('keyup', (evt)=>{ + sel.addEventListener('keyup', (evt) => { if (evt.key == 'Shift') { // @ts-ignore (dlg.dom ?? dlg.dlg).classList.remove('qr--isCopy'); return; } }); - sel.addEventListener('keydown', (evt)=>{ + sel.addEventListener('keydown', (evt) => { if (evt.key == 'Shift') { // @ts-ignore (dlg.dom ?? dlg.dlg).classList.add('qr--isCopy'); @@ -330,12 +329,12 @@ export class QuickReplySet { dom.append(hintP); } } - const dlg = new Popup(dom, POPUP_TYPE.CONFIRM, null, { okButton:'Transfer', cancelButton:'Cancel' }); + const dlg = new Popup(dom, POPUP_TYPE.CONFIRM, null, { okButton: 'Transfer', cancelButton: 'Cancel' }); const copyBtn = document.createElement('div'); { copyBtn.classList.add('qr--copy'); copyBtn.classList.add('menu_button'); copyBtn.textContent = 'Copy'; - copyBtn.addEventListener('click', ()=>{ + copyBtn.addEventListener('click', () => { isCopy = true; dlg.completeAffirmative(); }); @@ -346,7 +345,7 @@ export class QuickReplySet { sel.focus(); await prom; if (dlg.result == POPUP_RESULT.AFFIRMATIVE) { - const qrs = QuickReplySet.list.find(it=>it.name == sel.value); + const qrs = QuickReplySet.list.find(it => it.name == sel.value); qrs.addQuickReply(qr.toJSON()); if (!isCopy) { qr.delete(); diff --git a/public/scripts/extensions/quick-reply/src/QuickReplySetLink.js b/public/scripts/extensions/quick-reply/src/QuickReplySetLink.js index a36a64d88..baa165154 100644 --- a/public/scripts/extensions/quick-reply/src/QuickReplySetLink.js +++ b/public/scripts/extensions/quick-reply/src/QuickReplySetLink.js @@ -9,8 +9,6 @@ export class QuickReplySetLink { } - - /**@type {QuickReplySet}*/ set; /**@type {Boolean}*/ isVisible = true; @@ -23,8 +21,6 @@ export class QuickReplySetLink { /**@type {HTMLElement}*/ settingsDom; - - renderSettings(idx) { this.index = idx; const item = document.createElement('div'); { @@ -40,12 +36,12 @@ export class QuickReplySetLink { const set = document.createElement('select'); { set.classList.add('qr--set'); // fix for jQuery sortable breaking childrens' touch events - set.addEventListener('touchstart', (evt)=>evt.stopPropagation()); - set.addEventListener('change', ()=>{ + set.addEventListener('touchstart', (evt) => evt.stopPropagation()); + set.addEventListener('change', () => { this.set = QuickReplySet.get(set.value); this.update(); }); - QuickReplySet.list.toSorted((a,b)=>a.name.toLowerCase().localeCompare(b.name.toLowerCase())).forEach(qrs=>{ + QuickReplySet.list.toSorted((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase())).forEach(qrs => { const opt = document.createElement('option'); { opt.value = qrs.name; opt.textContent = qrs.name; @@ -61,7 +57,7 @@ export class QuickReplySetLink { const cb = document.createElement('input'); { cb.type = 'checkbox'; cb.checked = this.isVisible; - cb.addEventListener('click', ()=>{ + cb.addEventListener('click', () => { this.isVisible = cb.checked; this.update(); }); @@ -76,7 +72,7 @@ export class QuickReplySetLink { edit.classList.add('fa-solid'); edit.classList.add('fa-pencil'); edit.title = 'Edit quick reply set'; - edit.addEventListener('click', ()=>this.requestEditSet()); + edit.addEventListener('click', () => this.requestEditSet()); item.append(edit); } const del = document.createElement('div'); { @@ -86,7 +82,7 @@ export class QuickReplySetLink { del.classList.add('fa-solid'); del.classList.add('fa-trash-can'); del.title = 'Remove quick reply set'; - del.addEventListener('click', ()=>this.delete()); + del.addEventListener('click', () => this.delete()); item.append(del); } } @@ -98,8 +94,6 @@ export class QuickReplySetLink { } - - update() { if (this.onUpdate) { this.onUpdate(this); @@ -118,8 +112,6 @@ export class QuickReplySetLink { } - - toJSON() { return { set: this.set.name, diff --git a/public/scripts/extensions/quick-reply/src/QuickReplySettings.js b/public/scripts/extensions/quick-reply/src/QuickReplySettings.js index 0b1548ae0..d0e11744f 100644 --- a/public/scripts/extensions/quick-reply/src/QuickReplySettings.js +++ b/public/scripts/extensions/quick-reply/src/QuickReplySettings.js @@ -15,8 +15,6 @@ export class QuickReplySettings { } - - /**@type {Boolean}*/ isEnabled = false; /**@type {Boolean}*/ isCombined = false; /**@type {Boolean}*/ isPopout = false; @@ -50,8 +48,6 @@ export class QuickReplySettings { /**@type {Function}*/ onRequestEditSet; - - init() { this.hookConfig(this.config); this.hookConfig(this.chatConfig); @@ -60,8 +56,8 @@ export class QuickReplySettings { hookConfig(config) { if (config) { - config.onUpdate = ()=>this.save(); - config.onRequestEditSet = (qrs)=>this.requestEditSet(qrs); + config.onUpdate = () => this.save(); + config.onRequestEditSet = (qrs) => this.requestEditSet(qrs); } } unhookConfig(config) { @@ -72,8 +68,6 @@ export class QuickReplySettings { } - - save() { extension_settings.quickReplyV2 = this.toJSON(); saveSettingsDebounced(); diff --git a/public/scripts/extensions/quick-reply/src/SlashCommandHandler.js b/public/scripts/extensions/quick-reply/src/SlashCommandHandler.js index 88ed6f578..8fac60d84 100644 --- a/public/scripts/extensions/quick-reply/src/SlashCommandHandler.js +++ b/public/scripts/extensions/quick-reply/src/SlashCommandHandler.js @@ -16,15 +16,11 @@ export class SlashCommandHandler { /** @type {QuickReplyApi} */ api; - - constructor(/** @type {QuickReplyApi} */api) { this.api = api; } - - init() { function getExecutionIcons(/** @type {QuickReply} */ qr) { let icons = ''; @@ -56,7 +52,7 @@ export class SlashCommandHandler { qrIds: (executor) => QuickReplySet.get(String(executor.namedArgumentList.find(x => x.name == 'set')?.value))?.qrList.map(qr => { const icons = getExecutionIcons(qr); const message = `${qr.automationId ? `[${qr.automationId}]` : ''}${icons ? `[auto: ${icons}]` : ''} ${qr.title || qr.message}`.trim(); - return new SlashCommandEnumValue(qr.label, message, enumTypes.enum, enumIcons.qr, null, ()=>qr.id.toString(), true); + return new SlashCommandEnumValue(qr.label, message, enumTypes.enum, enumIcons.qr, null, () => qr.id.toString(), true); }) ?? [], /** All QRs as a set.name string, to be able to execute, for example via the /run command */ @@ -352,7 +348,7 @@ export class SlashCommandHandler { return ''; }, returns: 'updated quick reply', - namedArgumentList: [...qrUpdateArgs, ...qrArgs.map(it=>{ + namedArgumentList: [...qrUpdateArgs, ...qrArgs.map(it => { if (it.name == 'label') { const clone = SlashCommandNamedArgument.fromProps(it); clone.isRequired = false; @@ -691,16 +687,16 @@ export class SlashCommandHandler { if (!args.from) throw new Error('/import requires from= to be set.'); if (!value) throw new Error('/import requires the unnamed argument to be set.'); let qr = [...this.api.listGlobalSets(), ...this.api.listChatSets()] - .map(it=>this.api.getSetByName(it)?.qrList ?? []) + .map(it => this.api.getSetByName(it)?.qrList ?? []) .flat() - .find(it=>it.label == args.from) + .find(it => it.label == args.from) ; if (!qr) { let [setName, ...qrNameParts] = args.from.split('.'); let qrName = qrNameParts.join('.'); let qrs = QuickReplySet.get(setName); if (qrs) { - qr = qrs.qrList.find(it=>it.label == qrName); + qr = qrs.qrList.find(it => it.label == qrName); } } if (qr) { @@ -709,23 +705,23 @@ export class SlashCommandHandler { if (args._debugController) { closure.source = args.from; } - const testCandidates = (executor)=>{ + const testCandidates = (executor) => { return ( - executor.namedArgumentList.find(arg=>arg.name == 'key') + executor.namedArgumentList.find(arg => arg.name == 'key') && executor.unnamedArgumentList.length > 0 && executor.unnamedArgumentList[0].value instanceof SlashCommandClosure ) || ( - !executor.namedArgumentList.find(arg=>arg.name == 'key') + !executor.namedArgumentList.find(arg => arg.name == 'key') && executor.unnamedArgumentList.length > 1 && executor.unnamedArgumentList[1].value instanceof SlashCommandClosure ); }; const candidates = closure.executorList - .filter(executor=>['let', 'var'].includes(executor.command.name)) + .filter(executor => ['let', 'var'].includes(executor.command.name)) .filter(testCandidates) - .map(executor=>({ - key: executor.namedArgumentList.find(arg=>arg.name == 'key')?.value ?? executor.unnamedArgumentList[0].value, - value: executor.unnamedArgumentList[executor.namedArgumentList.find(arg=>arg.name == 'key') ? 0 : 1].value, + .map(executor => ({ + key: executor.namedArgumentList.find(arg => arg.name == 'key')?.value ?? executor.unnamedArgumentList[0].value, + value: executor.unnamedArgumentList[executor.namedArgumentList.find(arg => arg.name == 'key') ? 0 : 1].value, })) ; for (let i = 0; i < value.length; i++) { @@ -735,7 +731,7 @@ export class SlashCommandHandler { dstName = value[i + 2]; i += 2; } - const pick = candidates.find(it=>it.key == srcName); + const pick = candidates.find(it => it.key == srcName); if (!pick) throw new Error(`No scoped closure named "${srcName}" found in "${args.from}"`); if (args._scope.existsVariableInScope(dstName)) { args._scope.setVariable(dstName, pick.value); @@ -783,8 +779,6 @@ export class SlashCommandHandler { } - - getSetByName(name) { const set = this.api.getSetByName(name); if (!set) { @@ -802,8 +796,6 @@ export class SlashCommandHandler { } - - async executeQuickReplyByIndex(idx) { try { return await this.api.executeQuickReplyByIndex(idx); diff --git a/public/scripts/extensions/quick-reply/src/ui/ButtonUi.js b/public/scripts/extensions/quick-reply/src/ui/ButtonUi.js index 8f05daf50..2cf0c9246 100644 --- a/public/scripts/extensions/quick-reply/src/ui/ButtonUi.js +++ b/public/scripts/extensions/quick-reply/src/ui/ButtonUi.js @@ -10,15 +10,11 @@ export class ButtonUi { /**@type {HTMLElement}*/ popoutDom; - - constructor(/**@type {QuickReplySettings}*/settings) { this.settings = settings; } - - render() { if (this.settings.isPopout) { return this.renderPopout(); @@ -57,8 +53,6 @@ export class ButtonUi { } - - renderBar() { if (!this.dom) { let buttonHolder; @@ -75,7 +69,7 @@ export class ButtonUi { popout.classList.add('menu_button'); popout.classList.add('fa-solid'); popout.classList.add('fa-window-restore'); - popout.addEventListener('click', ()=>{ + popout.addEventListener('click', () => { this.settings.isPopout = true; this.refresh(); this.settings.save(); @@ -91,8 +85,8 @@ export class ButtonUi { } } [...this.settings.config.setList, ...(this.settings.chatConfig?.setList ?? []), ...(this.settings.charConfig?.setList ?? [])] - .filter(link=>link.isVisible) - .forEach(link=>buttonHolder.append(link.set.render())) + .filter(link => link.isVisible) + .forEach(link => buttonHolder.append(link.set.render())) ; } } @@ -100,8 +94,6 @@ export class ButtonUi { } - - renderPopout() { if (!this.popoutDom) { let buttonHolder; @@ -130,7 +122,7 @@ export class ButtonUi { close.classList.add('fa-solid'); close.classList.add('fa-circle-xmark'); close.classList.add('hoverglow'); - close.addEventListener('click', ()=>{ + close.addEventListener('click', () => { this.settings.isPopout = false; this.refresh(); this.settings.save(); @@ -151,8 +143,8 @@ export class ButtonUi { } } [...this.settings.config.setList, ...(this.settings.chatConfig?.setList ?? []), ...(this.settings.charConfig?.setList ?? [])] - .filter(link=>link.isVisible) - .forEach(link=>buttonHolder.append(link.set.render())) + .filter(link => link.isVisible) + .forEach(link => buttonHolder.append(link.set.render())) ; root.append(body); } diff --git a/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js b/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js index 0dbc53919..79b3e64b6 100644 --- a/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js +++ b/public/scripts/extensions/quick-reply/src/ui/SettingsUi.js @@ -29,24 +29,18 @@ export class SettingsUi { /**@type {HTMLSelectElement}*/ currentSet; - - constructor(/**@type {QuickReplySettings}*/settings) { this.settings = settings; settings.onRequestEditSet = (qrs) => this.selectQrSet(qrs); } - - - - rerender() { if (!this.dom) return; const content = this.dom.querySelector('.inline-drawer-content'); content.innerHTML = ''; // @ts-ignore - Array.from(this.template.querySelector('.inline-drawer-content').cloneNode(true).children).forEach(el=>{ + Array.from(this.template.querySelector('.inline-drawer-content').cloneNode(true).children).forEach(el => { content.append(el); }); this.prepareDom(); @@ -75,15 +69,15 @@ export class SettingsUi { // general settings this.isEnabled = this.dom.querySelector('#qr--isEnabled'); this.isEnabled.checked = this.settings.isEnabled; - this.isEnabled.addEventListener('click', ()=>this.onIsEnabled()); + this.isEnabled.addEventListener('click', () => this.onIsEnabled()); this.isCombined = this.dom.querySelector('#qr--isCombined'); this.isCombined.checked = this.settings.isCombined; - this.isCombined.addEventListener('click', ()=>this.onIsCombined()); + this.isCombined.addEventListener('click', () => this.onIsCombined()); this.showPopoutButton = this.dom.querySelector('#qr--showPopoutButton'); this.showPopoutButton.checked = this.settings.showPopoutButton; - this.showPopoutButton.addEventListener('click', ()=>this.onShowPopoutButton()); + this.showPopoutButton.addEventListener('click', () => this.onShowPopoutButton()); } prepareGlobalSetList() { @@ -131,29 +125,29 @@ export class SettingsUi { prepareQrEditor() { // qr editor this.dom.querySelector('#qr--set-rename').addEventListener('click', async () => this.renameQrSet()); - this.dom.querySelector('#qr--set-new').addEventListener('click', async()=>this.addQrSet()); + this.dom.querySelector('#qr--set-new').addEventListener('click', async () => this.addQrSet()); /**@type {HTMLInputElement}*/ const importFile = this.dom.querySelector('#qr--set-importFile'); - importFile.addEventListener('change', async()=>{ + importFile.addEventListener('change', async () => { await this.importQrSet(importFile.files); importFile.value = null; }); - this.dom.querySelector('#qr--set-import').addEventListener('click', ()=>importFile.click()); + this.dom.querySelector('#qr--set-import').addEventListener('click', () => importFile.click()); this.dom.querySelector('#qr--set-export').addEventListener('click', async () => this.exportQrSet()); this.dom.querySelector('#qr--set-duplicate').addEventListener('click', async () => this.duplicateQrSet()); - this.dom.querySelector('#qr--set-delete').addEventListener('click', async()=>this.deleteQrSet()); - this.dom.querySelector('#qr--set-add').addEventListener('click', async()=>{ + this.dom.querySelector('#qr--set-delete').addEventListener('click', async () => this.deleteQrSet()); + this.dom.querySelector('#qr--set-add').addEventListener('click', async () => { this.currentQrSet.addQuickReply(); }); - this.dom.querySelector('#qr--set-paste').addEventListener('click', async()=>{ + this.dom.querySelector('#qr--set-paste').addEventListener('click', async () => { const text = await navigator.clipboard.readText(); this.currentQrSet.addQuickReplyFromText(text); }); - this.dom.querySelector('#qr--set-importQr').addEventListener('click', async()=>{ + this.dom.querySelector('#qr--set-importQr').addEventListener('click', async () => { const inp = document.createElement('input'); { inp.type = 'file'; inp.accept = '.json'; - inp.addEventListener('change', async()=>{ + inp.addEventListener('change', async () => { if (inp.files.length > 0) { for (const file of inp.files) { const text = await file.text(); @@ -166,8 +160,8 @@ export class SettingsUi { }); this.qrList = this.dom.querySelector('#qr--set-qrList'); this.currentSet = this.dom.querySelector('#qr--set'); - this.currentSet.addEventListener('change', ()=>this.onQrSetChange()); - QuickReplySet.list.toSorted((a,b)=>a.name.toLowerCase().localeCompare(b.name.toLowerCase())).forEach(qrs=>{ + this.currentSet.addEventListener('change', () => this.onQrSetChange()); + QuickReplySet.list.toSorted((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase())).forEach(qrs => { const opt = document.createElement('option'); { opt.value = qrs.name; opt.textContent = qrs.name; @@ -175,19 +169,19 @@ export class SettingsUi { } }); this.disableSend = this.dom.querySelector('#qr--disableSend'); - this.disableSend.addEventListener('click', ()=>{ + this.disableSend.addEventListener('click', () => { const qrs = this.currentQrSet; qrs.disableSend = this.disableSend.checked; qrs.save(); }); this.placeBeforeInput = this.dom.querySelector('#qr--placeBeforeInput'); - this.placeBeforeInput.addEventListener('click', ()=>{ + this.placeBeforeInput.addEventListener('click', () => { const qrs = this.currentQrSet; qrs.placeBeforeInput = this.placeBeforeInput.checked; qrs.save(); }); this.injectInput = this.dom.querySelector('#qr--injectInput'); - this.injectInput.addEventListener('click', ()=>{ + this.injectInput.addEventListener('click', () => { const qrs = this.currentQrSet; qrs.injectInput = this.injectInput.checked; qrs.save(); @@ -196,7 +190,7 @@ export class SettingsUi { this.color = this.dom.querySelector('#qr--color'); // @ts-ignore this.color.color = this.currentQrSet?.color ?? 'transparent'; - this.color.addEventListener('change', (evt)=>{ + this.color.addEventListener('change', (evt) => { if (!this.dom.closest('body')) return; const qrs = this.currentQrSet; if (initialColorChange) { @@ -211,7 +205,7 @@ export class SettingsUi { this.currentQrSet.updateColor(); }); // @ts-ignore - this.dom.querySelector('#qr--colorClear').addEventListener('click', (evt)=>{ + this.dom.querySelector('#qr--colorClear').addEventListener('click', (evt) => { const qrs = this.currentQrSet; // @ts-ignore this.color.color = 'transparent'; @@ -219,7 +213,7 @@ export class SettingsUi { this.currentQrSet.updateColor(); }); this.onlyBorderColor = this.dom.querySelector('#qr--onlyBorderColor'); - this.onlyBorderColor.addEventListener('click', ()=>{ + this.onlyBorderColor.addEventListener('click', () => { const qrs = this.currentQrSet; qrs.onlyBorderColor = this.onlyBorderColor.checked; qrs.save(); @@ -242,7 +236,7 @@ export class SettingsUi { $(qrsDom).sortable({ delay: getSortableDelay(), handle: '.drag-handle', - stop: ()=>this.onQrListSort(), + stop: () => this.onQrListSort(), }); } @@ -256,8 +250,6 @@ export class SettingsUi { } - - async onIsEnabled() { this.settings.isEnabled = this.isEnabled.checked; this.settings.save(); @@ -274,7 +266,7 @@ export class SettingsUi { } async onGlobalSetListSort() { - this.settings.config.setList = Array.from(this.globalSetList.children).map((it,idx)=>{ + this.settings.config.setList = Array.from(this.globalSetList.children).map((it, idx) => { const set = this.settings.config.setList[Number(it.getAttribute('data-order'))]; it.setAttribute('data-order', String(idx)); return set; @@ -283,7 +275,7 @@ export class SettingsUi { } async onChatSetListSort() { - this.settings.chatConfig.setList = Array.from(this.chatSetList.children).map((it,idx)=>{ + this.settings.chatConfig.setList = Array.from(this.chatSetList.children).map((it, idx) => { const set = this.settings.chatConfig.setList[Number(it.getAttribute('data-order'))]; it.setAttribute('data-order', String(idx)); return set; @@ -292,14 +284,14 @@ export class SettingsUi { } updateOrder(list) { - Array.from(list.children).forEach((it,idx)=>{ + Array.from(list.children).forEach((it, idx) => { it.setAttribute('data-order', idx); }); } async onQrListSort() { - this.currentQrSet.qrList = Array.from(this.qrList.querySelectorAll('.qr--set-item')).map((it,idx)=>{ - const qr = this.currentQrSet.qrList.find(qr=>qr.id == Number(it.getAttribute('data-id'))); + this.currentQrSet.qrList = Array.from(this.qrList.querySelectorAll('.qr--set-item')).map((it, idx) => { + const qr = this.currentQrSet.qrList.find(qr => qr.id == Number(it.getAttribute('data-id'))); it.setAttribute('data-order', String(idx)); return qr; }); @@ -408,7 +400,7 @@ export class SettingsUi { const qrs = new QuickReplySet(); qrs.name = name; qrs.addQuickReply(); - const idx = QuickReplySet.list.findIndex(it=>it.name.toLowerCase().localeCompare(name.toLowerCase()) == 1); + const idx = QuickReplySet.list.findIndex(it => it.name.toLowerCase().localeCompare(name.toLowerCase()) == 1); if (idx > -1) { QuickReplySet.list.splice(idx, 0, qrs); } else { @@ -448,7 +440,7 @@ export class SettingsUi { } else { /**@type {QuickReplySet}*/ const qrs = QuickReplySet.from(JSON.parse(JSON.stringify(props))); - qrs.qrList = props.qrList.map(it=>QuickReply.from(it)); + qrs.qrList = props.qrList.map(it => QuickReply.from(it)); qrs.init(); const oldQrs = QuickReplySet.get(props.name); if (oldQrs) { @@ -466,7 +458,7 @@ export class SettingsUi { this.prepareCharacterSetList(); } } else { - const idx = QuickReplySet.list.findIndex(it=>it.name.toLowerCase().localeCompare(qrs.name.toLowerCase()) == 1); + const idx = QuickReplySet.list.findIndex(it => it.name.toLowerCase().localeCompare(qrs.name.toLowerCase()) == 1); if (idx > -1) { QuickReplySet.list.splice(idx, 0, qrs); } else { @@ -496,7 +488,7 @@ export class SettingsUi { } exportQrSet() { - const blob = new Blob([JSON.stringify(this.currentQrSet)], { type:'application/json' }); + const blob = new Blob([JSON.stringify(this.currentQrSet)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); { a.href = url; diff --git a/public/scripts/extensions/quick-reply/src/ui/ctx/ContextMenu.js b/public/scripts/extensions/quick-reply/src/ui/ctx/ContextMenu.js index 020d5ba1e..af94f7c02 100644 --- a/public/scripts/extensions/quick-reply/src/ui/ctx/ContextMenu.js +++ b/public/scripts/extensions/quick-reply/src/ui/ctx/ContextMenu.js @@ -11,8 +11,6 @@ export class ContextMenu { /**@type {HTMLElement}*/ menu; - - constructor(/**@type {QuickReply}*/qr) { // this.itemList = items; this.itemList = this.build(qr).children; @@ -104,8 +102,6 @@ export class ContextMenu { } - - show({ clientX, clientY }) { if (this.isActive) return; this.isActive = true; diff --git a/public/scripts/extensions/quick-reply/src/ui/ctx/MenuItem.js b/public/scripts/extensions/quick-reply/src/ui/ctx/MenuItem.js index 2b33ec640..b087e5b98 100644 --- a/public/scripts/extensions/quick-reply/src/ui/ctx/MenuItem.js +++ b/public/scripts/extensions/quick-reply/src/ui/ctx/MenuItem.js @@ -15,8 +15,6 @@ export class MenuItem { /**@type {function}*/ onExpand; - - /** * * @param {?string} icon @@ -80,7 +78,6 @@ export class MenuItem { } item.addEventListener('mouseover', () => sub.show(item)); item.addEventListener('mouseleave', () => sub.hide()); - } } } diff --git a/public/scripts/extensions/quick-reply/src/ui/ctx/SubMenu.js b/public/scripts/extensions/quick-reply/src/ui/ctx/SubMenu.js index a018c60af..bb2823f40 100644 --- a/public/scripts/extensions/quick-reply/src/ui/ctx/SubMenu.js +++ b/public/scripts/extensions/quick-reply/src/ui/ctx/SubMenu.js @@ -9,8 +9,6 @@ export class SubMenu { /**@type {HTMLElement}*/ root; - - constructor(/**@type {MenuItem[]}*/items) { this.itemList = items; } @@ -29,8 +27,6 @@ export class SubMenu { } - - show(/**@type {HTMLElement}*/parent) { if (this.isActive) return; this.isActive = true; diff --git a/public/scripts/extensions/regex/index.js b/public/scripts/extensions/regex/index.js index 4a52fa178..60f8e71ba 100644 --- a/public/scripts/extensions/regex/index.js +++ b/public/scripts/extensions/regex/index.js @@ -1031,7 +1031,6 @@ function executeRegexScriptForDebugging(script, text) { const trailingText = text.substring(lastIndex); outputText += trailingText; highlightedOutput += escapeHtml(trailingText); - } catch (e) { err = (err ? err + '; ' : '') + `Replace error: ${e.message}`; outputText = text; // Fallback diff --git a/public/scripts/extensions/token-counter/index.js b/public/scripts/extensions/token-counter/index.js index 4ebe3d921..721597c98 100644 --- a/public/scripts/extensions/token-counter/index.js +++ b/public/scripts/extensions/token-counter/index.js @@ -115,5 +115,4 @@ jQuery(() => { returns: 'number of tokens', helpString: 'Counts the number of tokens in the current chat.', })); - }); diff --git a/public/scripts/extensions/tts/alltalk.js b/public/scripts/extensions/tts/alltalk.js index 50671d967..85096e3ca 100644 --- a/public/scripts/extensions/tts/alltalk.js +++ b/public/scripts/extensions/tts/alltalk.js @@ -1043,7 +1043,6 @@ class AllTalkTtsProvider { // V2: Combine the endpoint with the relative path return `${this.settings.provider_endpoint}${data.output_file_url}`; } - } catch (error) { console.error('[fetchTtsGeneration] Exception caught:', error); throw error; diff --git a/public/scripts/extensions/tts/chatterbox.js b/public/scripts/extensions/tts/chatterbox.js index 0e7b96f74..8fac4d57a 100644 --- a/public/scripts/extensions/tts/chatterbox.js +++ b/public/scripts/extensions/tts/chatterbox.js @@ -239,7 +239,6 @@ class ChatterboxTtsProvider { } this.setupEventListeners(); - } catch (error) { console.error('Error loading Chatterbox settings:', error); this.updateStatus('Offline'); @@ -518,7 +517,6 @@ class ChatterboxTtsProvider { }); await audio.play(); - } catch (error) { console.error('Error previewing voice:', error); this.updateStatus('Ready'); @@ -627,7 +625,6 @@ class ChatterboxTtsProvider { // Return the response directly - SillyTavern expects a Response object return response; - } catch (error) { console.error('Error in generateTts:', error); this.updateStatus('Ready'); diff --git a/public/scripts/extensions/tts/coqui.js b/public/scripts/extensions/tts/coqui.js index 18f20f6aa..b2186ad4b 100644 --- a/public/scripts/extensions/tts/coqui.js +++ b/public/scripts/extensions/tts/coqui.js @@ -160,7 +160,7 @@ class CoquiTtsProvider { .then(response => response.json()) .then(json => { coquiApiModels = json; - console.debug(DEBUG_PREFIX,'initialized coqui-api model list to', coquiApiModels); + console.debug(DEBUG_PREFIX, 'initialized coqui-api model list to', coquiApiModels); /* $('#coqui_api_language') .find('option') @@ -180,7 +180,7 @@ class CoquiTtsProvider { .then(response => response.json()) .then(json => { coquiApiModelsFull = json; - console.debug(DEBUG_PREFIX,'initialized coqui-api full model list to', coquiApiModelsFull); + console.debug(DEBUG_PREFIX, 'initialized coqui-api full model list to', coquiApiModelsFull); /* $('#coqui_api_full_language') .find('option') @@ -197,7 +197,7 @@ class CoquiTtsProvider { } // Perform a simple readiness check by trying to fetch voiceIds - async checkReady(){ + async checkReady() { throwIfModuleMissing(); await this.fetchTtsVoiceObjects(); } @@ -384,12 +384,12 @@ class CoquiTtsProvider { .append('') .val('none'); - for(let language in coquiApiModels) { + for (let language in coquiApiModels) { let languageLabel = language; if (language in languageLabels) languageLabel = languageLabels[language]; - $('#coqui_api_language').append(new Option(languageLabel,language)); - console.log(DEBUG_PREFIX,'added language',languageLabel,'(',language,')'); + $('#coqui_api_language').append(new Option(languageLabel, language)); + console.log(DEBUG_PREFIX, 'added language', languageLabel, '(', language, ')'); } $('#coqui_api_model_div').show(); @@ -406,12 +406,12 @@ class CoquiTtsProvider { .append('') .val('none'); - for(let language in coquiApiModelsFull) { + for (let language in coquiApiModelsFull) { let languageLabel = language; if (language in languageLabels) languageLabel = languageLabels[language]; - $('#coqui_api_language').append(new Option(languageLabel,language)); - console.log(DEBUG_PREFIX,'added language',languageLabel,'(',language,')'); + $('#coqui_api_language').append(new Option(languageLabel, language)); + console.log(DEBUG_PREFIX, 'added language', languageLabel, '(', language, ')'); } $('#coqui_api_model_div').show(); @@ -450,8 +450,8 @@ class CoquiTtsProvider { if (model_origin == 'coqui-api-full') modelDict = coquiApiModelsFull; - for(let model_dataset in modelDict[model_language]) - for(let model_name in modelDict[model_language][model_dataset]) { + for (let model_dataset in modelDict[model_language]) + for (let model_name in modelDict[model_language][model_dataset]) { const model_id = model_dataset + '/' + model_name; const model_label = model_name + ' (' + model_dataset + ' dataset)'; $('#coqui_api_model_name').append(new Option(model_label, model_id)); @@ -526,7 +526,7 @@ class CoquiTtsProvider { // Check if already installed and propose to do it otherwise const model_id = modelDict[model_language][model_dataset][model_name].id; - console.debug(DEBUG_PREFIX,'Check if model is already installed',model_id); + console.debug(DEBUG_PREFIX, 'Check if model is already installed', model_id); const result = await CoquiTtsProvider.checkmodel_state(model_id); const resultJSON = await result.json(); const model_state = resultJSON.model_state; @@ -583,7 +583,6 @@ class CoquiTtsProvider { $('#coqui_api_model_install_button').show(); return; } - } diff --git a/public/scripts/extensions/tts/cosyvoice.js b/public/scripts/extensions/tts/cosyvoice.js index d66267273..fbaf236c1 100644 --- a/public/scripts/extensions/tts/cosyvoice.js +++ b/public/scripts/extensions/tts/cosyvoice.js @@ -110,15 +110,11 @@ class CosyVoiceProvider { //#################// async getVoice(voiceName) { - - - if (this.voices.length == 0) { this.voices = await this.fetchTtsVoiceObjects(); } - const match = this.voices.filter( v => v.name == voiceName, )[0]; @@ -130,7 +126,6 @@ class CosyVoiceProvider { } - async generateTts(text, voiceId) { const response = await this.fetchTtsGeneration(text, voiceId); return response; @@ -198,7 +193,6 @@ class CosyVoiceProvider { } - // Interface not used async fetchTtsFromHistory(history_item_id) { return Promise.resolve(history_item_id); diff --git a/public/scripts/extensions/tts/elevenlabs.js b/public/scripts/extensions/tts/elevenlabs.js index bed2abc24..c151c2a44 100644 --- a/public/scripts/extensions/tts/elevenlabs.js +++ b/public/scripts/extensions/tts/elevenlabs.js @@ -132,7 +132,7 @@ class ElevenLabsTtsProvider { } if (Object.hasOwn(settings, 'apiKey')) { - if (settings.apiKey && !secret_state[SECRET_KEYS.ELEVENLABS]){ + if (settings.apiKey && !secret_state[SECRET_KEYS.ELEVENLABS]) { await writeSecret(SECRET_KEYS.ELEVENLABS, settings.apiKey); } delete settings.apiKey; diff --git a/public/scripts/extensions/tts/google-native.js b/public/scripts/extensions/tts/google-native.js index 8744b3621..9a9d2c037 100644 --- a/public/scripts/extensions/tts/google-native.js +++ b/public/scripts/extensions/tts/google-native.js @@ -124,7 +124,6 @@ export class GoogleNativeTtsProvider { console.info(`Google TTS: Loaded ${this.voices.length} voices`); return this.voices; - } catch (error) { console.error('Failed to fetch Google TTS voices:', error); throw error; @@ -151,7 +150,6 @@ export class GoogleNativeTtsProvider { this.audioElement.src = url; this.audioElement.play(); this.audioElement.onended = () => URL.revokeObjectURL(url); - } catch (error) { console.error('TTS Preview Error:', error); toastr.error(`Could not generate preview: ${error.message}`); diff --git a/public/scripts/extensions/tts/gpt-sovits-v2.js b/public/scripts/extensions/tts/gpt-sovits-v2.js index 5ef6de48a..57c3b2f80 100644 --- a/public/scripts/extensions/tts/gpt-sovits-v2.js +++ b/public/scripts/extensions/tts/gpt-sovits-v2.js @@ -115,15 +115,11 @@ class GptSovitsV2Provider { //#################// async getVoice(voiceName) { - - - if (this.voices.length == 0) { this.voices = await this.fetchTtsVoiceObjects(); } - const match = this.voices.filter( v => v.name == voiceName, )[0]; @@ -135,7 +131,6 @@ class GptSovitsV2Provider { } - async generateTts(text, voiceId) { const response = await this.fetchTtsGeneration(text, voiceId); return response; @@ -171,8 +166,6 @@ class GptSovitsV2Provider { */ - - async fetchTtsGeneration(inputText, voiceId, lang = null, forceNoStreaming = false) { console.info(`Generating new TTS for voice_id ${voiceId}`); @@ -215,7 +208,6 @@ class GptSovitsV2Provider { } - // Interface not used async fetchTtsFromHistory(history_item_id) { return Promise.resolve(history_item_id); diff --git a/public/scripts/extensions/tts/gsvi.js b/public/scripts/extensions/tts/gsvi.js index 8aee4ad20..3bd1e365a 100644 --- a/public/scripts/extensions/tts/gsvi.js +++ b/public/scripts/extensions/tts/gsvi.js @@ -1,4 +1,3 @@ - import { saveTtsProviderSettings } from './index.js'; export { GSVITtsProvider }; @@ -60,11 +59,9 @@ class GSVITtsProvider { const characterList = await response.json(); this.characterList = characterList; this.voices = Object.keys(characterList); - } - get settingsHtml() { let html = ` @@ -142,11 +139,8 @@ class GSVITtsProvider { $('#gsvi_batch_size_output').text(this.settings.batch_size); - - // Persist settings changes saveTtsProviderSettings(); - } async loadSettings(settings) { @@ -197,7 +191,6 @@ class GSVITtsProvider { } - // Perform a simple readiness check by trying to fetch voiceIds async checkReady() { await Promise.allSettled([this.fetchCharacterList()]); @@ -256,12 +249,10 @@ class GSVITtsProvider { return `${this.settings.provider_endpoint}/tts?${params.toString()}`; - } // Interface not used by GSVI TTS async fetchTtsFromHistory(history_item_id) { return Promise.resolve(history_item_id); } - } diff --git a/public/scripts/extensions/tts/index.js b/public/scripts/extensions/tts/index.js index 536b5f98a..95c03643f 100644 --- a/public/scripts/extensions/tts/index.js +++ b/public/scripts/extensions/tts/index.js @@ -611,7 +611,6 @@ async function processTtsQueue() { // Pass the full voiceMapKey (e.g., "User ("Quotes")") as well with character name await tts(segmentText, voiceId, char, voiceMapKey); - } catch (error) { toastr.error(error.toString()); console.error(error); @@ -707,7 +706,6 @@ async function processTtsQueue() { // Clear current job so the segmented jobs can be processed currentTtsJob = null; - } catch (error) { toastr.error(error.toString()); console.error(error); @@ -1286,7 +1284,6 @@ export function getCharacters(unrestricted) { } return characters; - } export function sanitizeId(input) { @@ -1314,7 +1311,6 @@ function parseVoiceMap(voiceMapString) { } - /** * Apply voiceMap based on current voiceMapEntries */ diff --git a/public/scripts/extensions/tts/kokoro-worker.js b/public/scripts/extensions/tts/kokoro-worker.js index d85e7aea0..4cc884ca9 100644 --- a/public/scripts/extensions/tts/kokoro-worker.js +++ b/public/scripts/extensions/tts/kokoro-worker.js @@ -7,7 +7,7 @@ let ready = false; let voices = []; // Handle messages from the main thread -self.onmessage = async function(e) { +self.onmessage = async function (e) { const { action, data } = e.data; switch (action) { diff --git a/public/scripts/extensions/tts/minimax.js b/public/scripts/extensions/tts/minimax.js index 4d5699adb..2e64f2367 100644 --- a/public/scripts/extensions/tts/minimax.js +++ b/public/scripts/extensions/tts/minimax.js @@ -837,7 +837,6 @@ class MiniMaxTtsProvider { // Backend handles all the complex processing and returns audio data directly console.debug('MiniMax TTS: Audio response received from backend'); return response; - } catch (error) { console.error('Error in MiniMax TTS generation:', error); throw error; @@ -954,7 +953,6 @@ class MiniMaxTtsProvider { this.audioElement.onended = null; this.audioElement.onerror = null; }; - } catch (error) { console.error('MiniMax TTS Preview Error:', error); toastr.error(`Could not generate preview: ${error.message}`); diff --git a/public/scripts/extensions/tts/openai.js b/public/scripts/extensions/tts/openai.js index 327206586..0c9d557d9 100644 --- a/public/scripts/extensions/tts/openai.js +++ b/public/scripts/extensions/tts/openai.js @@ -146,7 +146,6 @@ class OpenAITtsProvider { } populateCharacterInstructions() { - const currentCharacters = $('.tts_voicemap_block_char span').map((i, el) => $(el).text()).get(); $('#openai-character-instructions').empty(); diff --git a/public/scripts/extensions/tts/silerotts.js b/public/scripts/extensions/tts/silerotts.js index c242c67f5..022c17529 100644 --- a/public/scripts/extensions/tts/silerotts.js +++ b/public/scripts/extensions/tts/silerotts.js @@ -172,5 +172,4 @@ class SileroTtsProvider { async fetchTtsFromHistory(history_item_id) { return Promise.resolve(history_item_id); } - } diff --git a/public/scripts/extensions/tts/xtts.js b/public/scripts/extensions/tts/xtts.js index 1408cae2d..d47093c61 100644 --- a/public/scripts/extensions/tts/xtts.js +++ b/public/scripts/extensions/tts/xtts.js @@ -323,5 +323,4 @@ class XTTSTtsProvider { async fetchTtsFromHistory(history_item_id) { return Promise.resolve(history_item_id); } - } diff --git a/public/scripts/extensions/vectors/index.js b/public/scripts/extensions/vectors/index.js index c376be224..949d90bae 100644 --- a/public/scripts/extensions/vectors/index.js +++ b/public/scripts/extensions/vectors/index.js @@ -1456,7 +1456,6 @@ async function onViewStatsClick() { messageElement.addClass('vectorized'); } } - } async function onVectorizeAllFilesClick() { diff --git a/public/scripts/f-localStorage.js b/public/scripts/f-localStorage.js index 50b1fe50e..67c728372 100644 --- a/public/scripts/f-localStorage.js +++ b/public/scripts/f-localStorage.js @@ -13,7 +13,6 @@ export function SaveLocal(target, val) { export function LoadLocal(target) { console.debug('LoadLocal -- ' + target); return localStorage.getItem(target); - } /** * @deprecated THIS FUNCTION IS OBSOLETE. DO NOT USE diff --git a/public/scripts/filters.js b/public/scripts/filters.js index eb5329d8a..3a9eddaed 100644 --- a/public/scripts/filters.js +++ b/public/scripts/filters.js @@ -76,7 +76,6 @@ export const fuzzySearchCategories = Object.freeze({ * data = filterHelper.applyFilters(data); */ export class FilterHelper { - /** * Cache fuzzy search weighting scores for re-usability, sorting and stuff * diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js index c8a2bcb52..8c9f5a442 100644 --- a/public/scripts/group-chats.js +++ b/public/scripts/group-chats.js @@ -2477,7 +2477,6 @@ jQuery(() => { const value = $(this).prop('checked'); hideMutedSprites = value; onHideMutedSpritesClick(value); - }); $('#send_textarea').on('keyup', onSendTextareaInput); $('#groupCurrentMemberPopoutButton').on('click', doCurMemberListPopout); diff --git a/public/scripts/input-md-formatting.js b/public/scripts/input-md-formatting.js index 5b69fb79b..ce0389273 100644 --- a/public/scripts/input-md-formatting.js +++ b/public/scripts/input-md-formatting.js @@ -59,7 +59,8 @@ export function initInputMarkdown() { let cursorShift = charsToAdd.length; let selectedTextandPossibleFormatting = textarea.value.substring(start - possiblePreviousFormattingMargin, end + possiblePreviousFormattingMargin).trim(); - if (isTextSelected) { //if text is selected + if (isTextSelected) { + //if text is selected selectedText = textarea.value.substring(start, end); if (selectedTextandPossibleFormatting === charsToAdd + selectedText + charsToAdd) { // If the selected text is already formatted, remove the formatting @@ -90,7 +91,8 @@ export function initInputMarkdown() { textarea.focus(); document.execCommand('insertText', false, charsToAdd + selectedText + charsToAdd + possibleAddedSpace); } - } else {// No text is selected + } else { + // No text is selected //check 1 character before and after the cursor for non-space characters if (beforeCaret !== ' ' && afterCaret !== ' ' && afterCaret !== '' && beforeCaret !== '') { //look for caret in the middle of a word @@ -116,7 +118,6 @@ export function initInputMarkdown() { } if (charsToAdd + discoveredWord + charsToAdd === discoveredWordWithPossibleFormatting) { - // Replace the expanded selection with the original discovered word textarea.focus(); document.execCommand('insertText', false, discoveredWord); @@ -126,8 +127,6 @@ export function initInputMarkdown() { textarea.focus(); document.execCommand('insertText', false, charsToAdd + discoveredWord + charsToAdd); } - - } else { //caret is not inside a word, so just add the formatting textarea.focus(); textarea.setSelectionRange(start, end); diff --git a/public/scripts/instruct-mode.js b/public/scripts/instruct-mode.js index c02377dff..0b5ab1c9a 100644 --- a/public/scripts/instruct-mode.js +++ b/public/scripts/instruct-mode.js @@ -798,7 +798,6 @@ jQuery(() => { $('#instruct_system_sequence').prop('readOnly', false); $('#instruct_system_suffix').prop('readOnly', false); } - }); $('#instruct_enabled').on('change', function () { diff --git a/public/scripts/openai.js b/public/scripts/openai.js index b6e46f926..b71899a66 100644 --- a/public/scripts/openai.js +++ b/public/scripts/openai.js @@ -2279,7 +2279,6 @@ function appendElectronHubOptions(model_list, groupModels = false) { appendOption(model); }); } - } function electronHubSortBy(data, property = 'alphabetically') { @@ -3985,7 +3984,6 @@ function loadOpenAISettings(data, settings) { option.value = i; option.text = item; $('#settings_preset_openai').append(option); - }); openai_setting_names = settingNames; @@ -4896,7 +4894,6 @@ function getSiliconflowMaxContext(model, isUnlocked) { // Return context size if model found, otherwise default to 32k return Object.entries(contextMap).find(([key]) => model.includes(key))?.[1] || max_32k; - } /** @@ -5041,7 +5038,6 @@ async function onModelChange() { console.log('Claude model changed to', value); oai_settings.claude_model = value; $('#model_claude_select').val(oai_settings.claude_model); - } if ($(this).is('#model_openai_select')) { diff --git a/public/scripts/personas.js b/public/scripts/personas.js index 79c59bbcc..9f1be4c9a 100644 --- a/public/scripts/personas.js +++ b/public/scripts/personas.js @@ -1593,7 +1593,6 @@ export async function showCharConnections() { highlightPersonas: true, targetedChar: getCurrentConnectionObj(), shiftClickHandler: (element, ev) => { - const personaId = $(element).attr('data-pid'); /** @type {PersonaConnection[]} */ @@ -1845,7 +1844,6 @@ async function lockPersonaCallback(_args, value) { if (isFalseBoolean(value)) { await setPersonaLockState(false, type); return 'false'; - } return ''; diff --git a/public/scripts/popup.js b/public/scripts/popup.js index 8747fa392..69e23e145 100644 --- a/public/scripts/popup.js +++ b/public/scripts/popup.js @@ -478,7 +478,6 @@ export class Popup { break; } } - }; this.dlg.addEventListener('keydown', keyListener.bind(this)); } diff --git a/public/scripts/power-user.js b/public/scripts/power-user.js index 9fa7811a8..2dfaf08f2 100644 --- a/public/scripts/power-user.js +++ b/public/scripts/power-user.js @@ -536,7 +536,6 @@ function switchSwipeNumAllMessages() { var originalSliderValues = []; async function switchLabMode({ noReset = false } = {}) { - /* if (power_user.enableZenSliders && power_user.enableLabMode) { toastr.warning("Can't start Lab Mode while Zen Sliders are active") return @@ -571,8 +570,6 @@ async function switchLabMode({ noReset = false } = {}) { $('#amount_gen').attr('min', '1') .attr('max', '99999') .attr('step', '1'); - - } else if (!noReset) { //re apply the original sliders values to each input originalSliderValues.forEach(function (slider) { @@ -628,7 +625,6 @@ async function switchZenSliders() { }); $('div[id$="_zenslider"]').remove(); } - } async function CreateZenSliders(elmnt) { var originalSlider = elmnt; @@ -1178,7 +1174,6 @@ function applyShadowWidth() { document.documentElement.style.setProperty('--shadowWidth', String(power_user.shadow_width)); $('#shadow_width_counter').val(power_user.shadow_width); $('#shadow_width').val(power_user.shadow_width); - } function applyFontScale(type) { @@ -2954,7 +2949,6 @@ function setAvgBG() { } */ function getAverageRGB(imgEl) { - var blockSize = 5, // only visit every 5 pixels defaultRGB = { r: 0, g: 0, b: 0 }, // for non-supporting envs canvas = document.createElement('canvas'), @@ -2994,7 +2988,6 @@ function setAvgBG() { rgb.b = ~~(rgb.b / count); return rgb; - } /** @@ -4035,7 +4028,7 @@ jQuery(() => { return; } - eventSource.once(event_types.SETTINGS_UPDATED, function() { + eventSource.once(event_types.SETTINGS_UPDATED, function () { toastr.warning( t`Click here to reload.`, t`Toggling the Experimental Macro Engine requires a reload.`, diff --git a/public/scripts/preset-manager.js b/public/scripts/preset-manager.js index 1293b2e77..515d94dde 100644 --- a/public/scripts/preset-manager.js +++ b/public/scripts/preset-manager.js @@ -514,7 +514,6 @@ class PresetManager { console.error('Preset could not be renamed', error); throw new Error('Preset could not be renamed'); } - } /** diff --git a/public/scripts/reasoning.js b/public/scripts/reasoning.js index 026f640e5..e92cfd82e 100644 --- a/public/scripts/reasoning.js +++ b/public/scripts/reasoning.js @@ -865,7 +865,6 @@ function selectReasoningTemplateCallback(args, name) { UI.$select.val(foundName).trigger('change'); !quiet && toastr.success(`Reasoning template "${foundName}" selected`); return foundName; - } function registerReasoningSlashCommands() { diff --git a/public/scripts/samplerSelect.js b/public/scripts/samplerSelect.js index a6a0b2975..5ffec69dd 100644 --- a/public/scripts/samplerSelect.js +++ b/public/scripts/samplerSelect.js @@ -203,7 +203,6 @@ function setSamplerListListeners() { console.log(samplerName, relatedDOMElement.data(SELECT_SAMPLER.DATA), shouldDisplay); }); - } function isElementVisibleInDOM(element) { diff --git a/public/scripts/showdown-underscore.js b/public/scripts/showdown-underscore.js index 34c763c01..38eacbf8f 100644 --- a/public/scripts/showdown-underscore.js +++ b/public/scripts/showdown-underscore.js @@ -9,7 +9,7 @@ export const markdownUnderscoreExt = () => { return [{ type: 'output', regex: new RegExp('(]*)?>[\\s\\S]*?<\\/code>|]*)?>[\\s\\S]*?<\\/style>)|\\b(? or