chore: Move editor into codebase (#2930)
This commit is contained in:
65
shared/editor/lib/markInputRule.ts
Normal file
65
shared/editor/lib/markInputRule.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { InputRule } from "prosemirror-inputrules";
|
||||
import { MarkType, Mark } from "prosemirror-model";
|
||||
import { EditorState } from "prosemirror-state";
|
||||
|
||||
function getMarksBetween(start: number, end: number, state: EditorState) {
|
||||
let marks: { start: number; end: number; mark: Mark }[] = [];
|
||||
|
||||
state.doc.nodesBetween(start, end, (node, pos) => {
|
||||
marks = [
|
||||
...marks,
|
||||
...node.marks.map((mark) => ({
|
||||
start: pos,
|
||||
end: pos + node.nodeSize,
|
||||
mark,
|
||||
})),
|
||||
];
|
||||
});
|
||||
|
||||
return marks;
|
||||
}
|
||||
|
||||
export default function (
|
||||
regexp: RegExp,
|
||||
markType: MarkType,
|
||||
getAttrs?: (match: string[]) => Record<string, unknown>
|
||||
): InputRule {
|
||||
return new InputRule(
|
||||
regexp,
|
||||
(state: EditorState, match: string[], start: number, end: number) => {
|
||||
const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
|
||||
const { tr } = state;
|
||||
const m = match.length - 1;
|
||||
let markEnd = end;
|
||||
let markStart = start;
|
||||
|
||||
if (match[m]) {
|
||||
const matchStart = start + match[0].indexOf(match[m - 1]);
|
||||
const matchEnd = matchStart + match[m - 1].length - 1;
|
||||
const textStart = matchStart + match[m - 1].lastIndexOf(match[m]);
|
||||
const textEnd = textStart + match[m].length;
|
||||
|
||||
const excludedMarks = getMarksBetween(start, end, state)
|
||||
.filter((item) => item.mark.type.excludes(markType))
|
||||
.filter((item) => item.end > matchStart);
|
||||
|
||||
if (excludedMarks.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (textEnd < matchEnd) {
|
||||
tr.delete(textEnd, matchEnd);
|
||||
}
|
||||
if (textStart > matchStart) {
|
||||
tr.delete(matchStart, textStart);
|
||||
}
|
||||
markStart = matchStart;
|
||||
markEnd = markStart + match[m].length;
|
||||
}
|
||||
|
||||
tr.addMark(markStart, markEnd, markType.create(attrs));
|
||||
tr.removeStoredMark(markType);
|
||||
return tr;
|
||||
}
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user