PERF: Use insertText more efficiently in `replaceText` (#28880)

Followup to e25578d702

Using execCommand to replace the entire contents of the textarea is very slow for larger posts (it seems the browser does a reflow after every 'virtual keypress'.

This commit updates the `replaceText` function to be more surgical with its `insertAt` calls. Now it only selects & replaces the characters which are actually being replaced.
This commit is contained in:
David Taylor 2024-09-12 16:11:39 +01:00 committed by GitHub
parent 600801f194
commit a7cd220704
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 18 additions and 9 deletions

View File

@ -149,16 +149,21 @@ export default Mixin.create({
});
if (opts.index && opts.regex) {
let i = -1;
const newValue = val.replace(opts.regex, (match) => {
i++;
return i === opts.index ? newVal : match;
});
if (!opts.regex.global) {
throw new Error("Regex must be global");
}
this._insertAt(0, val.length, newValue);
const regex = new RegExp(opts.regex);
let match;
for (let i = 0; i <= opts.index; i++) {
match = regex.exec(val);
}
if (match) {
this._insertAt(match.index, match.index + match[0].length, newVal);
}
} else {
const replacedValue = val.replace(oldVal, newVal);
this._insertAt(0, val.length, replacedValue);
this._insertAt(needleStart, needleStart + oldVal.length, newVal);
}
if (
@ -332,7 +337,11 @@ export default Mixin.create({
_insertAt(start, end, text) {
this._textarea.setSelectionRange(start, end);
this._textarea.focus();
document.execCommand("insertText", false, text);
if (start !== end && text === "") {
document.execCommand("delete", false);
} else {
document.execCommand("insertText", false, text);
}
},
extractTable(text) {