-
Notifications
You must be signed in to change notification settings - Fork 1
Add utility for universal text replacement #53
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,90 @@ | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
class UniversalReplace { | ||||||||||||||||||||||||||||||||||||||
observer: MutationObserver | undefined; | ||||||||||||||||||||||||||||||||||||||
patterns: { pattern: RegExp, replace: string }[] = []; | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
constructor() { | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
addPattern(pattern: string | RegExp, replace: string) { | ||||||||||||||||||||||||||||||||||||||
this.patterns.push({ pattern: toRegExpPattern(pattern), replace }); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (!this.observer) { | ||||||||||||||||||||||||||||||||||||||
this.createObserver(); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
removePattern(pattern: string | RegExp) { | ||||||||||||||||||||||||||||||||||||||
const pattern_ = toRegExpPattern(pattern); | ||||||||||||||||||||||||||||||||||||||
let idx = this.patterns.findIndex(p => p.pattern.source === pattern_.source); | ||||||||||||||||||||||||||||||||||||||
if (idx >= 0) this.patterns.splice(idx, 1); | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
if (this.patterns.length === 0) { | ||||||||||||||||||||||||||||||||||||||
this.observer?.disconnect(); | ||||||||||||||||||||||||||||||||||||||
this.observer = undefined; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
createObserver() { | ||||||||||||||||||||||||||||||||||||||
const this_ = this; | ||||||||||||||||||||||||||||||||||||||
this.observer = new MutationObserver(function (mutations) { | ||||||||||||||||||||||||||||||||||||||
for (let mutation of mutations) { | ||||||||||||||||||||||||||||||||||||||
if (mutation.addedNodes != null && mutation.addedNodes.length > 0) { | ||||||||||||||||||||||||||||||||||||||
for (let node of mutation.addedNodes) { | ||||||||||||||||||||||||||||||||||||||
if (node instanceof Text && | ||||||||||||||||||||||||||||||||||||||
node.parentElement && | ||||||||||||||||||||||||||||||||||||||
!(node.parentElement instanceof HTMLScriptElement) && | ||||||||||||||||||||||||||||||||||||||
!(node.parentElement instanceof HTMLStyleElement) && | ||||||||||||||||||||||||||||||||||||||
node.textContent !== null && | ||||||||||||||||||||||||||||||||||||||
!(/^\s*$/.test(node.textContent))) | ||||||||||||||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||||||||||||||
const replace = this_.matchReplacePattern(node.textContent); | ||||||||||||||||||||||||||||||||||||||
if (replace) { | ||||||||||||||||||||||||||||||||||||||
const treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT); | ||||||||||||||||||||||||||||||||||||||
let textNode: Node | ||||||||||||||||||||||||||||||||||||||
do { | ||||||||||||||||||||||||||||||||||||||
textNode = treeWalker.currentNode; | ||||||||||||||||||||||||||||||||||||||
if (textNode.nodeValue === null) continue; | ||||||||||||||||||||||||||||||||||||||
textNode.nodeValue = textNode.nodeValue.replace(replace.pattern, replaceFirstLetterCase(replace.replace)); | ||||||||||||||||||||||||||||||||||||||
} while (treeWalker.nextNode()); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+30
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Refactor the function expression to an arrow function to enhance readability and maintain consistency with modern JavaScript practices. - this.observer = new MutationObserver(function (mutations) {
+ this.observer = new MutationObserver((mutations) => {
ToolsBiome
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, also changing that you won't need to declare There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @NicoMorenoSirius You're absolutely right! By converting the function to an arrow function, createObserver() {
this.observer = new MutationObserver((mutations) => {
for (let mutation of mutations) {
if (mutation.addedNodes != null && mutation.addedNodes.length > 0) {
for (let node of mutation.addedNodes) {
if (node instanceof Text &&
node.parentElement &&
!(node.parentElement instanceof HTMLScriptElement) &&
!(node.parentElement instanceof HTMLStyleElement) &&
node.textContent !== null &&
!(/^\s*$/.test(node.textContent)))
{
const replace = this.matchReplacePattern(node.textContent);
if (replace) {
const treeWalker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT);
let textNode;
do {
textNode = treeWalker.currentNode;
if (textNode.nodeValue === null) continue;
textNode.nodeValue = textNode.nodeValue.replace(replace.pattern, replaceFirstLetterCase(replace.replace));
} while (treeWalker.nextNode());
}
}
}
}
});
} This change simplifies the code and enhances its readability. If there's anything else you'd like to adjust or discuss, feel free to let me know! Learnings added
|
||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
this.observer.observe(document, { childList: true, subtree: true }); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
matchReplacePattern(text: string): { pattern: RegExp, replace: string } | null { | ||||||||||||||||||||||||||||||||||||||
for (let pattern of this.patterns) { | ||||||||||||||||||||||||||||||||||||||
if (pattern.pattern.test(text)) { | ||||||||||||||||||||||||||||||||||||||
return { pattern: pattern.pattern, replace: pattern.replace } | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return null | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const replaceFirstLetterCase = (value: string) => { | ||||||||||||||||||||||||||||||||||||||
return (match: string) => { | ||||||||||||||||||||||||||||||||||||||
// Check if the first letter in the match is uppercase | ||||||||||||||||||||||||||||||||||||||
if (match[0] === match[0].toUpperCase()) { | ||||||||||||||||||||||||||||||||||||||
return value.charAt(0).toUpperCase() + value.slice(1); | ||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||
return value; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
Comment on lines
+71
to
+79
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Simplify the function by removing the unnecessary else clause. - } else {
- return value;
- }
+ return value; Committable suggestion
Suggested change
ToolsBiome
|
||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
const toRegExpPattern = (pattern: string | RegExp) => { | ||||||||||||||||||||||||||||||||||||||
if (typeof pattern === "string") { | ||||||||||||||||||||||||||||||||||||||
return new RegExp('\\b' + pattern + '\\b', "ig"); | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
return pattern; | ||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||
export default new UniversalReplace(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove the unnecessary constructor to simplify the class definition.
Committable suggestion
Tools
Biome