Add info block for find regex flags #3647

eef9c3ef62255882c840765b801e45f97d5b263e

Cohee <18619528+Cohee1207@users.noreply.github.com>

3 files changed, +71 -1Showing whitespace changes
public/scripts/extensions/regex/editor.html+7 -0
@@ -16,6 +16,13 @@
16 </small>16 </small>
17 <hr />17 <hr />
1818
19 <div id="regex_info_block" class="info-block">
20 <span class="info-block-text"></span>
21 <a class="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">
22 <i class="fa-solid fa-circle-info" title="Click here to learn more about regex flags."></i>
23 </a>
24 </div>
25
19 <div id="regex_test_mode" class="flex1 flex-container displayNone">26 <div id="regex_test_mode" class="flex1 flex-container displayNone">
20 <div class="flex1">27 <div class="flex1">
21 <label class="title_restorable" for="regex_test_input">28 <label class="title_restorable" for="regex_test_input">
public/scripts/extensions/regex/index.js+46 -1
@@ -7,7 +7,7 @@ import { ARGUMENT_TYPE, SlashCommandArgument, SlashCommandNamedArgument } from '
7import { enumIcons } from '../../slash-commands/SlashCommandCommonEnumsProvider.js';7import { 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, uuidv4 } from '../../utils.js';10import { download, getFileText, getSortableDelay, regexFromString, 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';
@@ -258,6 +258,8 @@ async function onRegexEditorOpenClick(existingId, isScoped) {
258 });258 });
259259
260 function updateTestResult() {260 function updateTestResult() {
261 updateInfoBlock(editorHtml);
262
261 if (!editorHtml.find('#regex_test_mode').is(':visible')) {263 if (!editorHtml.find('#regex_test_mode').is(':visible')) {
262 return;264 return;
263 }265 }
@@ -276,6 +278,7 @@ async function onRegexEditorOpenClick(existingId, isScoped) {
276 }278 }
277279
278 editorHtml.find('input, textarea, select').on('input', updateTestResult);280 editorHtml.find('input, textarea, select').on('input', updateTestResult);
281 updateInfoBlock(editorHtml);
279282
280 const popupResult = await callPopup(editorHtml, 'confirm', undefined, { okButton: t`Save` });283 const popupResult = await callPopup(editorHtml, 'confirm', undefined, { okButton: t`Save` });
281 if (popupResult) {284 if (popupResult) {
@@ -305,6 +308,48 @@ async function onRegexEditorOpenClick(existingId, isScoped) {
305 }308 }
306}309}
307310
311/**
312 * Updates the info block in the regex editor with hints regarding the find regex.
313 * @param {JQuery<HTMLElement>} editorHtml The editor HTML
314 */
315function updateInfoBlock(editorHtml) {
316 const infoBlock = editorHtml.find('.info-block');
317 const infoBlockTextSpan = infoBlock.find('.info-block-text');
318 const infoBlockFlagsHint = infoBlock.find('.info-block-flags-hint');
319 const findRegex = String(editorHtml.find('.find_regex').val());
320
321 infoBlock.removeClass('error hint info warning');
322 infoBlockFlagsHint.hide();
323
324 // Clear the info block if the find regex is empty
325 if (!findRegex) {
326 infoBlock.addClass('info');
327 infoBlockTextSpan.text(t`Find Regex is empty`);
328 return;
329 }
330
331 try {
332 const regex = regexFromString(findRegex);
333 if (!regex) {
334 throw new Error(t`Invalid Find Regex`);
335 }
336
337 const flagInfo = [];
338 // Check flags
339
340 flagInfo.push(regex.flags.includes('g') ? t`Applies to all matches` : t`Applies to the first match`);
341 flagInfo.push(regex.flags.includes('i') ? t`Case insensitive` : t`Case sensitive`);
342
343 infoBlock.addClass('hint');
344 infoBlockTextSpan.text(flagInfo.join('. '));
345 infoBlockFlagsHint.show();
346 } catch (error) {
347 infoBlock.addClass('error');
348 infoBlockTextSpan.text(error.message);
349 return;
350 }
351}
352
308// Common settings migration function. Some parts will eventually be removed353// Common settings migration function. Some parts will eventually be removed
309// TODO: Maybe migrate placement to strings?354// TODO: Maybe migrate placement to strings?
310function migrateSettings() {355function migrateSettings() {
public/scripts/extensions/regex/style.css+18 -0
@@ -105,3 +105,21 @@ input.enable_scoped {
105.disable_regex:not(:checked) ~ .regex-toggle-on {105.disable_regex:not(:checked) ~ .regex-toggle-on {
106 display: block;106 display: block;
107}107}
108
109#regex_info_block {
110 position: relative;
111 margin: 10px 0;
112 padding: 5px 20px;
113 font-size: 0.9em;
114}
115
116#regex_info_block:empty {
117 display: none;
118}
119
120#regex_info_block .info-block-flags-hint {
121 position: absolute;
122 top: 50%;
123 right: 10px;
124 transform: translateY(-50%);
125}