Allow JS syntax in instruct activation regex

This commit is contained in:
Cohee 2024-05-17 01:14:07 +03:00
parent 59d00cca74
commit 909ec4191d
3 changed files with 31 additions and 30 deletions

View File

@ -1,5 +1,6 @@
import { substituteParams } from '../../../script.js';
import { extension_settings } from '../../extensions.js';
import { regexFromString } from '../../utils.js';
export {
regex_placement,
getRegexedString,
@ -21,29 +22,6 @@ const regex_placement = {
WORLD_INFO: 5,
};
/**
* Instantiates a regular expression from a string.
* @param {string} input The input string.
* @returns {RegExp} The regular expression instance.
* @copyright Originally from: https://github.com/IonicaBizau/regex-parser.js/blob/master/lib/index.js
*/
function regexFromString(input) {
try {
// Parse input
var m = input.match(/(\/?)(.+)\1([a-z]*)/i);
// Invalid flags
if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) {
return RegExp(input);
}
// Create the regular expression
return new RegExp(m[2], m[3]);
} catch {
return;
}
}
/**
* Parent function to fetch a regexed version of a raw string
* @param {string} rawString The raw string to be regexed

View File

@ -7,7 +7,7 @@ import {
power_user,
context_presets,
} from './power-user.js';
import { resetScrollHeight } from './utils.js';
import { regexFromString, resetScrollHeight } from './utils.js';
/**
* @type {any[]} Instruct mode presets.
@ -189,10 +189,10 @@ export function autoSelectInstructPreset(modelId) {
// If activation regex is set, check if it matches the model id
if (preset.activation_regex) {
try {
const regex = new RegExp(preset.activation_regex, 'i');
const regex = regexFromString(preset.activation_regex);
// Stop on first match so it won't cycle back and forth between presets if multiple regexes match
if (regex.test(modelId)) {
if (regex instanceof RegExp && regex.test(modelId)) {
selectInstructPreset(preset.name);
return true;

View File

@ -791,6 +791,29 @@ export function escapeRegex(string) {
return string.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&');
}
/**
* Instantiates a regular expression from a string.
* @param {string} input The input string.
* @returns {RegExp} The regular expression instance.
* @copyright Originally from: https://github.com/IonicaBizau/regex-parser.js/blob/master/lib/index.js
*/
export function regexFromString(input) {
try {
// Parse input
var m = input.match(/(\/?)(.+)\1([a-z]*)/i);
// Invalid flags
if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) {
return RegExp(input);
}
// Create the regular expression
return new RegExp(m[2], m[3]);
} catch {
return;
}
}
export class Stopwatch {
/**
* Initializes a Stopwatch class.
@ -1502,7 +1525,7 @@ export function select2ModifyOptions(element, items, { select = false, changeEve
const existingValues = [];
dataItems.forEach(item => {
// Set the value, creating a new option if necessary
if (element.find("option[value='" + item.id + "']").length) {
if (element.find('option[value=\'' + item.id + '\']').length) {
if (select) existingValues.push(item.id);
} else {
// Create a DOM Option and optionally pre-select by default
@ -1536,9 +1559,9 @@ export function dynamicSelect2DataViaAjax(dataProvider) {
});
promise.then(success);
promise.catch(failure);
};
}
const ajax = {
transport: dynamicSelect2DataTransport
transport: dynamicSelect2DataTransport,
};
return ajax;
}
@ -1599,7 +1622,7 @@ export function select2ChoiceClickSubscribe(control, action, { buttonStyle = fal
export function highlightRegex(regexStr) {
// Function to escape HTML special characters for safety
const escapeHtml = (str) => str.replace(/[&<>"']/g, match => ({
'&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;'
'&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', '\'': '&#39;',
})[match]);
// Replace special characters with their HTML-escaped forms