Skip to content

Commit

Permalink
fix: Highlight matching mentions in find and replace (#8184)
Browse files Browse the repository at this point in the history
  • Loading branch information
tommoor authored Jan 3, 2025
1 parent 63d70c2 commit db30d08
Showing 1 changed file with 38 additions and 15 deletions.
53 changes: 38 additions & 15 deletions app/editor/extensions/FindAndReplace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,17 @@ export default class FindAndReplaceExtension extends Extension {
}

private get decorations() {
return this.results.map((deco, index) =>
Decoration.inline(deco.from, deco.to, {
return this.results.map((deco, index) => {
const decorationType =
deco.type === "node" ? Decoration.node : Decoration.inline;
return decorationType(deco.from, deco.to, {
class:
this.options.resultClassName +
(this.currentResultIndex === index
? ` ${this.options.resultCurrentClassName}`
: ""),
})
);
});
});
}

public replace(replace: string): Command {
Expand Down Expand Up @@ -212,22 +214,32 @@ export default class FindAndReplaceExtension extends Extension {

const { from: currentFrom, to: currentTo } = this.results[index];
const offset = currentTo - currentFrom - replace.length + lastOffset;
const { from, to } = this.results[nextIndex];
const { from, to, type } = this.results[nextIndex];

this.results[nextIndex] = {
to: to - offset,
from: from - offset,
type,
};

return offset;
}

private search(doc: Node) {
this.results = [];
const mergedTextNodes: {
text: string | undefined;
pos: number;
}[] = [];
const mergedTextNodes: (
| {
text: string | undefined;
pos: number;
type: "inline";
}
| {
text: string | undefined;
pos: number;
type: "node";
nodeSize: number;
}
)[] = [];
let index = 0;

if (!this.searchTerm) {
Expand All @@ -238,21 +250,32 @@ export default class FindAndReplaceExtension extends Extension {
if (node.isText) {
if (mergedTextNodes[index]) {
mergedTextNodes[index] = {
type: "inline",
text: mergedTextNodes[index].text + (node.text ?? ""),
pos: mergedTextNodes[index].pos,
};
} else {
mergedTextNodes[index] = {
type: "inline",
text: node.text,
pos,
};
}
} else if (node.type.name === "mention") {
mergedTextNodes[++index] = {
type: "node",
nodeSize: node.nodeSize,
text: node.attrs.label,
pos,
};
++index;
} else {
index += 1;
++index;
}
});

mergedTextNodes.forEach(({ text = "", pos }) => {
mergedTextNodes.forEach((node) => {
const { text = "", pos, type } = node;
try {
let m;
const search = this.findRegExp;
Expand All @@ -266,16 +289,16 @@ export default class FindAndReplaceExtension extends Extension {

// Reconstruct the correct match position
const i = m.index >= text.length ? m.index - text.length : m.index;
const from = pos + i;
const to = from + m[0].length;
const from = type === "inline" ? pos + i : pos;
const to = from + (type === "inline" ? m[0].length : node.nodeSize);

// Check if already exists in results, possible due to duplicated
// search string on L257
if (this.results.some((r) => r.from === from && r.to === to)) {
continue;
}

this.results.push({ from, to });
this.results.push({ from, to, type });
}
} catch (e) {
// Invalid RegExp
Expand Down Expand Up @@ -349,7 +372,7 @@ export default class FindAndReplaceExtension extends Extension {
private open = false;

@observable
private results: { from: number; to: number }[] = [];
private results: { from: number; to: number; type: "inline" | "node" }[] = [];

@observable
private currentResultIndex = 0;
Expand Down

0 comments on commit db30d08

Please sign in to comment.