Add /regex-toggle slash command - Add /regex-toggle command, similarly to /extension-toggle - toggles the state of both global and character-bound scripts - Update jsdoc being inconsistent Closes #3613

7537192c9aff0b5756e697cf2d91b0a428312756

Wolfsblvt <wolfsblvt@gmail.com>

1 files changed, +76 -9Showing whitespace changes
public/scripts/extensions/regex/index.js+76 -9
@@ -4,22 +4,16 @@ import { selected_group } from '../../group-chats.js';
4import { callGenericPopup, POPUP_TYPE } from '../../popup.js';4import { callGenericPopup, POPUP_TYPE } from '../../popup.js';
5import { SlashCommand } from '../../slash-commands/SlashCommand.js';5import { SlashCommand } from '../../slash-commands/SlashCommand.js';
6import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';6import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '../../slash-commands/SlashCommandArgument.js';
7import { enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';7import { commonEnumProviders, enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
8import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js';8import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js';
9import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';9import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
10import { download, getFileText, getSortableDelay, regexFromString, setInfoBlock, uuidv4 } from '../../utils.js';10import { download, equalsIgnoreCaseAndAccents, getFileText, getSortableDelay, isFalseBoolean, isTrueBoolean, regexFromString, setInfoBlock, uuidv4 } from '../../utils.js';
11import { regex_placement, runRegexScript, substitute_find_regex } from './engine.js';11import { regex_placement, runRegexScript, substitute_find_regex } from './engine.js';
12import { t } from '../../i18n.js';12import { t } from '../../i18n.js';
13import { accountStorage } from '../../util/AccountStorage.js';13import { accountStorage } from '../../util/AccountStorage.js';
1414
15/**15/**
16 * @typedef {object} RegexScript16 * @typedef {import('../../char-data.js').RegexScriptData} RegexScript
17 * @property {string} scriptName - The name of the script
18 * @property {boolean} disabled - Whether the script is disabled
19 * @property {string} replaceString - The replace string
20 * @property {string[]} trimStrings - The trim strings
21 * @property {string?} findRegex - The find regex
22 * @property {number?} substituteRegex - The substitute regex
23 */17 */
2418
25/**19/**
@@ -418,6 +412,42 @@ function runRegexCallback(args, value) {
418}412}
419413
420/**414/**
415 * /regex-toggle slash command callback
416 * @param {{state: string}} args Named arguments
417 * @param {string} scriptName The name of the script to toggle
418 * @returns {Promise<string>} The regexed string
419 */
420async function toggleRegexCallback(args, scriptName) {
421 if (typeof scriptName !== 'string') throw new Error('Script name must be a string.');
422
423 const action = isTrueBoolean(args?.state) ? 'enable' :
424 isFalseBoolean(args?.state) ? 'disable' :
425 'toggle';
426
427 const scripts = getRegexScripts();
428 const script = scripts.find(s => equalsIgnoreCaseAndAccents(s.scriptName, scriptName));
429
430 if (!script) {
431 toastr.warning(t`Regex script '${scriptName}' not found.`);
432 return;
433 }
434
435 script.disabled = action === 'enable' ? false : action === 'disable' ? true : !script.disabled;
436
437 const isScoped = characters[this_chid]?.data?.extensions?.regex_scripts?.some(s => s.id === script.id);
438 const index = isScoped ? characters[this_chid]?.data?.extensions?.regex_scripts?.indexOf(script) : scripts.indexOf(script);
439
440 await saveRegexScript(script, index, isScoped);
441 if (script.disabled) {
442 toastr.success(t`Regex script '${scriptName}' has been disabled.`);
443 } else {
444 toastr.success(t`Regex script '${scriptName}' has been enabled.`);
445 }
446
447 return script.scriptName || '';
448}
449
450/**
421 * Performs the import of the regex file.451 * Performs the import of the regex file.
422 * @param {File} file Input file452 * @param {File} file Input file
423 * @param {boolean} isScoped Is the script scoped to a character?453 * @param {boolean} isScoped Is the script scoped to a character?
@@ -639,6 +669,43 @@ jQuery(async () => {
639 ],669 ],
640 helpString: 'Runs a Regex extension script by name on the provided string. The script must be enabled.',670 helpString: 'Runs a Regex extension script by name on the provided string. The script must be enabled.',
641 }));671 }));
672 SlashCommandParser.addCommandObject(SlashCommand.fromProps({
673 name: 'regex-toggle',
674 callback: toggleRegexCallback,
675 returns: 'The name of the script that was toggled',
676 namedArgumentList: [
677 SlashCommandNamedArgument.fromProps({
678 name: 'state',
679 description: 'Explicitly set the state of the script (true to enable, false to disable). If not provided, the state will be toggled to the opposite of the current state.',
680 typeList: [ARGUMENT_TYPE.BOOLEAN],
681 enumList: commonEnumProviders.boolean('trueFalse')(),
682 }),
683 ],
684 unnamedArgumentList: [
685 SlashCommandArgument.fromProps({
686 description: 'script name',
687 typeList: [ARGUMENT_TYPE.STRING],
688 isRequired: true,
689 enumProvider: localEnumProviders.regexScripts,
690 }),
691 ],
692 helpString: `
693 <div>
694 Toggles the state of a specified regex script.
695 </div>
696 <div>
697 <strong>Example:</strong>
698 <ul>
699 <li>
700 <pre><code class="language-stscript">/regex-toggle MyScript</code></pre>
701 </li>
702 <li>
703 <pre><code class="language-stscript">/regex-toggle state=off Character-specific Script</code></pre>
704 </li>
705 </ul>
706 </div>
707 `,
708 }));
642709
643 eventSource.on(event_types.CHAT_CHANGED, checkEmbeddedRegexScripts);710 eventSource.on(event_types.CHAT_CHANGED, checkEmbeddedRegexScripts);
644 eventSource.on(event_types.CHARACTER_DELETED, purgeEmbeddedRegexScripts);711 eventSource.on(event_types.CHARACTER_DELETED, purgeEmbeddedRegexScripts);