Merge pull request #3648 from SillyTavern/regex-info-block

Add info block for find regex flags
This commit is contained in:
Cohee
2025-03-09 23:30:38 +02:00
committed by GitHub
3 changed files with 67 additions and 2 deletions

View File

@@ -16,6 +16,13 @@
</small>
<hr />
<div id="regex_info_block_wrapper">
<div id="regex_info_block" class="info-block"></div>
<a id="regex_info_block_flags_hint" href="http://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_expressions#advanced_searching_with_flags" target="_blank" rel="noopener noreferrer">
<i class="fa-solid fa-circle-info" title="Click here to learn more about regex flags."></i>
</a>
</div>
<div id="regex_test_mode" class="flex1 flex-container displayNone">
<div class="flex1">
<label class="title_restorable" for="regex_test_input">

View File

@@ -7,7 +7,7 @@ import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '
import { enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';
import { SlashCommandEnumValue, enumTypes } from '../../slash-commands/SlashCommandEnumValue.js';
import { SlashCommandParser } from '../../slash-commands/SlashCommandParser.js';
import { download, getFileText, getSortableDelay, uuidv4 } from '../../utils.js';
import { download, getFileText, getSortableDelay, regexFromString, setInfoBlock, uuidv4 } from '../../utils.js';
import { regex_placement, runRegexScript, substitute_find_regex } from './engine.js';
import { t } from '../../i18n.js';
import { accountStorage } from '../../util/AccountStorage.js';
@@ -258,6 +258,8 @@ async function onRegexEditorOpenClick(existingId, isScoped) {
});
function updateTestResult() {
updateInfoBlock(editorHtml);
if (!editorHtml.find('#regex_test_mode').is(':visible')) {
return;
}
@@ -276,6 +278,7 @@ async function onRegexEditorOpenClick(existingId, isScoped) {
}
editorHtml.find('input, textarea, select').on('input', updateTestResult);
updateInfoBlock(editorHtml);
const popupResult = await callPopup(editorHtml, 'confirm', undefined, { okButton: t`Save` });
if (popupResult) {
@@ -305,6 +308,40 @@ async function onRegexEditorOpenClick(existingId, isScoped) {
}
}
/**
* Updates the info block in the regex editor with hints regarding the find regex.
* @param {JQuery<HTMLElement>} editorHtml The editor HTML
*/
function updateInfoBlock(editorHtml) {
const infoBlock = editorHtml.find('.info-block').get(0);
const infoBlockFlagsHint = editorHtml.find('#regex_info_block_flags_hint');
const findRegex = String(editorHtml.find('.find_regex').val());
infoBlockFlagsHint.hide();
// Clear the info block if the find regex is empty
if (!findRegex) {
setInfoBlock(infoBlock, t`Find Regex is empty`, 'info');
return;
}
try {
const regex = regexFromString(findRegex);
if (!regex) {
throw new Error(t`Invalid Find Regex`);
}
const flagInfo = [];
flagInfo.push(regex.flags.includes('g') ? t`Applies to all matches` : t`Applies to the first match`);
flagInfo.push(regex.flags.includes('i') ? t`Case insensitive` : t`Case sensitive`);
setInfoBlock(infoBlock, flagInfo.join('. '), 'hint');
infoBlockFlagsHint.show();
} catch (error) {
setInfoBlock(infoBlock, error.message, 'error');
}
}
// Common settings migration function. Some parts will eventually be removed
// TODO: Maybe migrate placement to strings?
function migrateSettings() {

View File

@@ -105,3 +105,24 @@ input.enable_scoped {
.disable_regex:not(:checked) ~ .regex-toggle-on {
display: block;
}
#regex_info_block_wrapper {
position: relative;
}
#regex_info_block {
margin: 10px 0;
padding: 5px 20px;
font-size: 0.9em;
}
#regex_info_block_wrapper:has(#regex_info_block:empty) {
display: none;
}
#regex_info_block_flags_hint {
position: absolute;
top: 50%;
right: 10px;
transform: translateY(-50%);
}