Skip to content
This repository has been archived by the owner on Sep 26, 2024. It is now read-only.

Commit

Permalink
Add flags to replaceAll: (#167)
Browse files Browse the repository at this point in the history
i - case insensitive
   w - whole word
   p - plural
  • Loading branch information
jonathankap authored Aug 30, 2024
1 parent fc9ba5e commit 29f4a63
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 18 deletions.
7 changes: 4 additions & 3 deletions apps/mocksi-lite-next/src/pages/content/mocksi-extension.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,15 @@ chrome.runtime.onMessage.addListener((request) => {
async function findReplaceAll(
find: string,
replace: string,
flags: string,
highlight: boolean,
) {
const modification: ModificationRequest = {
description: `Change ${find} to ${replace}`,
modifications: [
{
action: "replaceAll",
content: `/${find}/${replace}/`,
content: `/${find}/${replace}/${flags}`,
selector: "body",
},
],
Expand Down Expand Up @@ -118,8 +119,8 @@ chrome.runtime.onMessage.addListener((request) => {
}
if (request.message === "NEW_EDIT") {
if (request.data) {
const { find, highlightEdits, replace } = request.data;
await findReplaceAll(find, replace, highlightEdits);
const { find, highlightEdits, replace, flags } = request.data;
await findReplaceAll(find, replace, flags, highlightEdits);
data = Array.from(reactor.getAppliedModifications()).map(
(mod) => mod.modificationRequest,
);
Expand Down
43 changes: 36 additions & 7 deletions packages/reactor/modifications/replaceAll.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,15 +159,15 @@ function replaceText(
addModifiedElement: (element: Element) => string,
addHighlightNode: (node: Node) => void,
): (node: Node) => TreeChange | null {
const { patternRegexp, replacement } = toRegExpPattern(pattern);
const { patternRegexp, replacement, flags } = toRegExpPattern(pattern);

return (node: Node) => {
let split = node.nodeValue?.split(patternRegexp) || [];
split = split.map((part, index) => {
if (index % 2 === 0) {
return part;
}
return replaceFirstLetterCaseAndPlural(replacement)(part);
return replaceFirstLetterCaseAndPlural(replacement, flags)(part);
});

const parentElement = node.parentElement;
Expand Down Expand Up @@ -213,7 +213,7 @@ function replaceText(
};
}

function replaceFirstLetterCaseAndPlural(value: string) {
function replaceFirstLetterCaseAndPlural(value: string, flags: Partial<Record<PatternFlag, boolean>> = {}) {
return (match: string) => {
let out = value;

Expand All @@ -225,26 +225,55 @@ function replaceFirstLetterCaseAndPlural(value: string) {
}

// if the match is plural, add an s
if (match.endsWith("s")) {
if ((flags[PatternFlag.Plurals] ?? false) && match.endsWith("s")) {
out = `${out}s`;
}

return out;
};
}

enum PatternFlag {
CaseInsensitive = "i",
WordBoundary = "w",
Plurals = "p",
}

// Take pattern in the form of /pattern/replacement/ and return {patternRegexp, replacement}
function toRegExpPattern(pattern: string): {
patternRegexp: RegExp;
replacement: string;
flags: Partial<Record<PatternFlag, boolean>>;
} {
const match = /\/(.+)\/(.+)\//.exec(pattern);
if (!match || match.length !== 3 || !match[1] || !match[2]) {
const match = /\/(.+)\/(.+)\/(.*)/.exec(pattern);
if (!match || match.length < 3 || !match[1] || !match[2]) {
throw new Error(`Invalid pattern: ${pattern}`);
}

let reFlags = "g";
let rePattern = match[1];
const flags = match[3];

const patternFlags: Partial<Record<PatternFlag, boolean>> = {};

if (flags?.includes('p')) {
rePattern += "s?";
patternFlags[PatternFlag.Plurals] = true;
}

if (flags?.includes('w')) {
rePattern = `\\b${rePattern}\\b`;
patternFlags[PatternFlag.WordBoundary] = true;
}

if (flags?.includes('i')) {
reFlags += "i";
patternFlags[PatternFlag.CaseInsensitive] = true;
}

return {
patternRegexp: new RegExp(`(\\b${match[1]}s?\\b)`, "gi"),
patternRegexp: new RegExp(`(${rePattern})`, reFlags),
replacement: match[2],
flags: patternFlags,
};
}
2 changes: 1 addition & 1 deletion packages/reactor/tests/main.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ describe("modifyHtml", () => {
{
xpath: "//html/body/div",
action: "replaceAll",
content: "/train/brain/",
content: "/train/brain/i",
},
],
});
Expand Down
12 changes: 6 additions & 6 deletions packages/reactor/tests/modifications.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe("Utils", () => {
it("should replace all content correctly", async () => {
const modification: Modification = {
action: "replaceAll",
content: "/old/new/",
content: "/old/new/i",
};

const element = doc.createElement("div");
Expand Down Expand Up @@ -74,7 +74,7 @@ describe("Utils", () => {
it("should preserve capitals in replacement", async () => {
const modification: Modification = {
action: "replaceAll",
content: "/old/new/",
content: "/old/new/i",
};

const element = doc.createElement("div");
Expand All @@ -88,7 +88,7 @@ describe("Utils", () => {
it("should preserve plurals in replacement", async () => {
const modification: Modification = {
action: "replaceAll",
content: "/train/brain/",
content: "/train/brain/ip",
};

const element = doc.createElement("div");
Expand All @@ -104,7 +104,7 @@ describe("Utils", () => {
it("should only replace whole words", async () => {
const modification: Modification = {
action: "replaceAll",
content: "/train/brain/",
content: "/train/brain/wip",
};

const element = doc.createElement("div");
Expand All @@ -121,7 +121,7 @@ describe("Utils", () => {
it("should handle more complicated HTML", async () => {
const modification: Modification = {
action: "replaceAll",
content: "/train/brain/",
content: "/train/brain/wip",
};

const element = doc.createElement("div");
Expand Down Expand Up @@ -156,7 +156,7 @@ describe("Utils", () => {
it("should work with multiple text nodes", async () => {
const modification: Modification = {
action: "replaceAll",
content: "/train/brain/",
content: "/train/brain/wip",
};

const element = doc.createElement("div");
Expand Down
2 changes: 1 addition & 1 deletion packages/reactor/tests/mutation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ describe("test mutation listeners", {}, () => {
{
selector: "body",
action: "replaceAll",
content: "/train/brain/",
content: "/train/brain/wip",
}
],
};
Expand Down

0 comments on commit 29f4a63

Please sign in to comment.