@moda-editor/core 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +16 -0
- package/dist/commands.d.ts +78 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +299 -0
- package/dist/commands.js.map +1 -0
- package/dist/conformance.d.ts +59 -0
- package/dist/conformance.d.ts.map +1 -0
- package/dist/conformance.js +1609 -0
- package/dist/conformance.js.map +1 -0
- package/dist/core.d.ts +37 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +117 -0
- package/dist/core.js.map +1 -0
- package/dist/editor/editor.d.ts +104 -0
- package/dist/editor/editor.d.ts.map +1 -0
- package/dist/editor/editor.js +204 -0
- package/dist/editor/editor.js.map +1 -0
- package/dist/editor/extension.d.ts +170 -0
- package/dist/editor/extension.d.ts.map +1 -0
- package/dist/editor/extension.js +2 -0
- package/dist/editor/extension.js.map +1 -0
- package/dist/features/ace.d.ts +9 -0
- package/dist/features/ace.d.ts.map +1 -0
- package/dist/features/ace.js +144 -0
- package/dist/features/ace.js.map +1 -0
- package/dist/features/alignment.d.ts +9 -0
- package/dist/features/alignment.d.ts.map +1 -0
- package/dist/features/alignment.js +28 -0
- package/dist/features/alignment.js.map +1 -0
- package/dist/features/blockquote.d.ts +9 -0
- package/dist/features/blockquote.d.ts.map +1 -0
- package/dist/features/blockquote.js +65 -0
- package/dist/features/blockquote.js.map +1 -0
- package/dist/features/code-block.d.ts +77 -0
- package/dist/features/code-block.d.ts.map +1 -0
- package/dist/features/code-block.js +986 -0
- package/dist/features/code-block.js.map +1 -0
- package/dist/features/doc.d.ts +15 -0
- package/dist/features/doc.d.ts.map +1 -0
- package/dist/features/doc.js +79 -0
- package/dist/features/doc.js.map +1 -0
- package/dist/features/feature.d.ts +26 -0
- package/dist/features/feature.d.ts.map +1 -0
- package/dist/features/feature.js +8 -0
- package/dist/features/feature.js.map +1 -0
- package/dist/features/hard-break.d.ts +9 -0
- package/dist/features/hard-break.d.ts.map +1 -0
- package/dist/features/hard-break.js +48 -0
- package/dist/features/hard-break.js.map +1 -0
- package/dist/features/heading.d.ts +3 -0
- package/dist/features/heading.d.ts.map +1 -0
- package/dist/features/heading.js +31 -0
- package/dist/features/heading.js.map +1 -0
- package/dist/features/horizontal-rule.d.ts +9 -0
- package/dist/features/horizontal-rule.d.ts.map +1 -0
- package/dist/features/horizontal-rule.js +64 -0
- package/dist/features/horizontal-rule.js.map +1 -0
- package/dist/features/image.d.ts +12 -0
- package/dist/features/image.d.ts.map +1 -0
- package/dist/features/image.js +116 -0
- package/dist/features/image.js.map +1 -0
- package/dist/features/index.d.ts +31 -0
- package/dist/features/index.d.ts.map +1 -0
- package/dist/features/index.js +65 -0
- package/dist/features/index.js.map +1 -0
- package/dist/features/inline-style.d.ts +12 -0
- package/dist/features/inline-style.d.ts.map +1 -0
- package/dist/features/inline-style.js +126 -0
- package/dist/features/inline-style.js.map +1 -0
- package/dist/features/link.d.ts +29 -0
- package/dist/features/link.d.ts.map +1 -0
- package/dist/features/link.js +198 -0
- package/dist/features/link.js.map +1 -0
- package/dist/features/lists.d.ts +14 -0
- package/dist/features/lists.d.ts.map +1 -0
- package/dist/features/lists.js +178 -0
- package/dist/features/lists.js.map +1 -0
- package/dist/features/marks.d.ts +6 -0
- package/dist/features/marks.d.ts.map +1 -0
- package/dist/features/marks.js +68 -0
- package/dist/features/marks.js.map +1 -0
- package/dist/features/script.d.ts +2 -0
- package/dist/features/script.d.ts.map +1 -0
- package/dist/features/script.js +55 -0
- package/dist/features/script.js.map +1 -0
- package/dist/features/table.d.ts +20 -0
- package/dist/features/table.d.ts.map +1 -0
- package/dist/features/table.js +195 -0
- package/dist/features/table.js.map +1 -0
- package/dist/features/task-list.d.ts +10 -0
- package/dist/features/task-list.d.ts.map +1 -0
- package/dist/features/task-list.js +68 -0
- package/dist/features/task-list.js.map +1 -0
- package/dist/features/testkit.d.ts +32 -0
- package/dist/features/testkit.d.ts.map +1 -0
- package/dist/features/testkit.js +92 -0
- package/dist/features/testkit.js.map +1 -0
- package/dist/history.d.ts +40 -0
- package/dist/history.d.ts.map +1 -0
- package/dist/history.js +192 -0
- package/dist/history.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/model/node.d.ts +47 -0
- package/dist/model/node.d.ts.map +1 -0
- package/dist/model/node.js +30 -0
- package/dist/model/node.js.map +1 -0
- package/dist/model/schema.d.ts +105 -0
- package/dist/model/schema.d.ts.map +1 -0
- package/dist/model/schema.js +46 -0
- package/dist/model/schema.js.map +1 -0
- package/dist/model/traverse.d.ts +36 -0
- package/dist/model/traverse.d.ts.map +1 -0
- package/dist/model/traverse.js +123 -0
- package/dist/model/traverse.js.map +1 -0
- package/dist/mount.d.ts +24 -0
- package/dist/mount.d.ts.map +1 -0
- package/dist/mount.js +45 -0
- package/dist/mount.js.map +1 -0
- package/dist/parse/html.d.ts +8 -0
- package/dist/parse/html.d.ts.map +1 -0
- package/dist/parse/html.js +247 -0
- package/dist/parse/html.js.map +1 -0
- package/dist/parse/sanitize.d.ts +20 -0
- package/dist/parse/sanitize.d.ts.map +1 -0
- package/dist/parse/sanitize.js +116 -0
- package/dist/parse/sanitize.js.map +1 -0
- package/dist/presets/highlight.d.ts +23 -0
- package/dist/presets/highlight.d.ts.map +1 -0
- package/dist/presets/highlight.js +170 -0
- package/dist/presets/highlight.js.map +1 -0
- package/dist/presets/starter.d.ts +14 -0
- package/dist/presets/starter.d.ts.map +1 -0
- package/dist/presets/starter.js +18 -0
- package/dist/presets/starter.js.map +1 -0
- package/dist/state/apply.d.ts +64 -0
- package/dist/state/apply.d.ts.map +1 -0
- package/dist/state/apply.js +528 -0
- package/dist/state/apply.js.map +1 -0
- package/dist/state/navigate.d.ts +5 -0
- package/dist/state/navigate.d.ts.map +1 -0
- package/dist/state/navigate.js +81 -0
- package/dist/state/navigate.js.map +1 -0
- package/dist/state/selection.d.ts +44 -0
- package/dist/state/selection.d.ts.map +1 -0
- package/dist/state/selection.js +63 -0
- package/dist/state/selection.js.map +1 -0
- package/dist/state/state.d.ts +39 -0
- package/dist/state/state.d.ts.map +1 -0
- package/dist/state/state.js +123 -0
- package/dist/state/state.js.map +1 -0
- package/dist/state/transaction.d.ts +234 -0
- package/dist/state/transaction.d.ts.map +1 -0
- package/dist/state/transaction.js +988 -0
- package/dist/state/transaction.js.map +1 -0
- package/dist/styles.css +948 -0
- package/dist/types.d.ts +44 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/view/dom.d.ts +26 -0
- package/dist/view/dom.d.ts.map +1 -0
- package/dist/view/dom.js +249 -0
- package/dist/view/dom.js.map +1 -0
- package/dist/view/input.d.ts +45 -0
- package/dist/view/input.d.ts.map +1 -0
- package/dist/view/input.js +901 -0
- package/dist/view/input.js.map +1 -0
- package/dist/view/mount.d.ts +26 -0
- package/dist/view/mount.d.ts.map +1 -0
- package/dist/view/mount.js +119 -0
- package/dist/view/mount.js.map +1 -0
- package/dist/view/render.d.ts +64 -0
- package/dist/view/render.d.ts.map +1 -0
- package/dist/view/render.js +203 -0
- package/dist/view/render.js.map +1 -0
- package/dist/view/serialize.d.ts +4 -0
- package/dist/view/serialize.d.ts.map +1 -0
- package/dist/view/serialize.js +37 -0
- package/dist/view/serialize.js.map +1 -0
- package/package.json +44 -0
|
@@ -0,0 +1,528 @@
|
|
|
1
|
+
import { expandTextNodes, insertChildAt, nodeAt, removeChildAt, spliceChildren, updateNodeAt, } from "../model/traverse.js";
|
|
2
|
+
import { pointCmp, pointEq } from "./selection.js";
|
|
3
|
+
/**
|
|
4
|
+
* Step 적용 엔진 — 순수 함수 (doc, step) → doc.
|
|
5
|
+
*
|
|
6
|
+
* 위치 규약: step의 at.path가 해석되는 노드에 따라 offset 의미가 달라진다.
|
|
7
|
+
* 텍스트 노드 → offset = 문자 오프셋
|
|
8
|
+
* 비텍스트 노드 → offset = 자식 인덱스 (children 사이의 경계)
|
|
9
|
+
* Point와 같은 규약이라 셀렉션 매핑과 일관된다.
|
|
10
|
+
*/
|
|
11
|
+
export function marksEq(a, b) {
|
|
12
|
+
if (a === b)
|
|
13
|
+
return true;
|
|
14
|
+
if (!a?.length || !b?.length || a.length !== b.length)
|
|
15
|
+
return !a?.length && !b?.length;
|
|
16
|
+
return a.every((m, i) => {
|
|
17
|
+
const o = b[i];
|
|
18
|
+
return !!o && m.type === o.type && JSON.stringify(m.attrs ?? null) === JSON.stringify(o.attrs ?? null);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
export function applyStep(doc, step) {
|
|
22
|
+
switch (step.op) {
|
|
23
|
+
case "insert":
|
|
24
|
+
return applyInsert(doc, step);
|
|
25
|
+
case "remove":
|
|
26
|
+
return applyRemove(doc, step);
|
|
27
|
+
case "setAttr":
|
|
28
|
+
return applySetAttr(doc, step);
|
|
29
|
+
case "addMark":
|
|
30
|
+
return applyMark(doc, step.range, step.mark);
|
|
31
|
+
case "removeMark":
|
|
32
|
+
return applyMark(doc, step.range, null, step.markType);
|
|
33
|
+
case "split":
|
|
34
|
+
return applySplitOps(doc, computeSplitOps(doc, step));
|
|
35
|
+
case "join":
|
|
36
|
+
return applyJoin(doc, step);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// ── insert / remove ─────────────────────────────────────────
|
|
40
|
+
function applyInsert(doc, step) {
|
|
41
|
+
const target = nodeAt(doc, step.at.path);
|
|
42
|
+
const ins = step.node;
|
|
43
|
+
if (target?.type === "text") {
|
|
44
|
+
const o = step.at.offset;
|
|
45
|
+
const text = target.text ?? "";
|
|
46
|
+
if (ins.type === "text" && marksEq(target.marks, ins.marks)) {
|
|
47
|
+
// 같은 마크면 텍스트를 합친다 — 노드 수가 안 바뀌는 빠른 경로
|
|
48
|
+
return updateNodeAt(doc, step.at.path, (t) => ({
|
|
49
|
+
...t,
|
|
50
|
+
text: text.slice(0, o) + (ins.text ?? "") + text.slice(o),
|
|
51
|
+
}));
|
|
52
|
+
}
|
|
53
|
+
// 마크가 다르거나 텍스트가 아니면 대상을 [head, inserted, tail]로 분할
|
|
54
|
+
const parent = step.at.path.slice(0, -1);
|
|
55
|
+
const i = step.at.path[step.at.path.length - 1];
|
|
56
|
+
const segs = [];
|
|
57
|
+
if (o > 0)
|
|
58
|
+
segs.push({ ...target, text: text.slice(0, o) });
|
|
59
|
+
segs.push(ins);
|
|
60
|
+
if (o < text.length)
|
|
61
|
+
segs.push({ ...target, text: text.slice(o) });
|
|
62
|
+
return spliceChildren(doc, parent, i, i + 1, segs);
|
|
63
|
+
}
|
|
64
|
+
return insertChildAt(doc, step.at.path, step.at.offset, ins);
|
|
65
|
+
}
|
|
66
|
+
function applyRemove(doc, step) {
|
|
67
|
+
const target = nodeAt(doc, step.at.path);
|
|
68
|
+
if (target?.type === "text") {
|
|
69
|
+
const o = step.at.offset;
|
|
70
|
+
const len = step.node.text?.length ?? 0;
|
|
71
|
+
return updateNodeAt(doc, step.at.path, (t) => ({
|
|
72
|
+
...t,
|
|
73
|
+
text: (t.text ?? "").slice(0, o) + (t.text ?? "").slice(o + len),
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
return removeChildAt(doc, step.at.path, step.at.offset);
|
|
77
|
+
}
|
|
78
|
+
function applySetAttr(doc, step) {
|
|
79
|
+
return updateNodeAt(doc, step.path, (n) => ({
|
|
80
|
+
...n,
|
|
81
|
+
attrs: { ...n.attrs, [step.key]: step.value },
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
// ── marks ───────────────────────────────────────────────────
|
|
85
|
+
/**
|
|
86
|
+
* range 엔드포인트 ↔ 텍스트 노드 경계 비교.
|
|
87
|
+
* element-boundary 셀렉션(문단 전체 드래그, Mod-A, selectNodeContents)은
|
|
88
|
+
* DOM (el, childIndex)이 컨테이너 경계 포인트 {P,k}(=P의 자식 k 앞)로
|
|
89
|
+
* 들어온다. 그냥 pointCmp로 비교하면 조상 경로가 자식 경로보다 항상
|
|
90
|
+
* "앞"으로 정렬돼 범위가 빈 것으로 판정된다 — 컨테이너 포인트의
|
|
91
|
+
* offset은 자식 인덱스이므로 다음 경로 요소와 비교한다
|
|
92
|
+
* (transaction의 docOrderCmp와 같은 규약).
|
|
93
|
+
*/
|
|
94
|
+
function cmpBound(p, bound) {
|
|
95
|
+
const d = p.path.length;
|
|
96
|
+
if (d < bound.path.length) {
|
|
97
|
+
for (let i = 0; i < d; i++) {
|
|
98
|
+
const a = p.path[i];
|
|
99
|
+
const b = bound.path[i];
|
|
100
|
+
if (a !== b)
|
|
101
|
+
return a < b ? -1 : 1;
|
|
102
|
+
}
|
|
103
|
+
// {P,k}는 자식 k의 시작 경계 — bound가 같은 자식 안이면
|
|
104
|
+
// bound.offset으로 세부 비교 (시작이면 동일 위치, 뒤면 p가 앞)
|
|
105
|
+
const c = p.offset - bound.path[d];
|
|
106
|
+
return c === 0 ? (bound.offset === 0 ? 0 : -1) : c < 0 ? -1 : 1;
|
|
107
|
+
}
|
|
108
|
+
return pointCmp(p, bound);
|
|
109
|
+
}
|
|
110
|
+
/** 텍스트 노드가 range와 겹치는 구간 [s,e) — 겹침 없으면 null */
|
|
111
|
+
export function coveredOffsets(node, path, range) {
|
|
112
|
+
const len = node.text?.length ?? 0;
|
|
113
|
+
const a = range.anchor;
|
|
114
|
+
const f = range.focus;
|
|
115
|
+
const start = { path, offset: 0 };
|
|
116
|
+
const end = { path, offset: len };
|
|
117
|
+
if (cmpBound(a, end) >= 0 || cmpBound(f, start) <= 0)
|
|
118
|
+
return null;
|
|
119
|
+
// 노드 안쪽 엔드포인트(같은 경로)만 문자 오프셋으로 읽는다 —
|
|
120
|
+
// 컨테이너 경계 엔드포인트의 offset은 자식 인덱스다
|
|
121
|
+
const s = a.path.length === path.length && cmpBound(a, start) > 0
|
|
122
|
+
? a.offset
|
|
123
|
+
: 0;
|
|
124
|
+
const e = f.path.length === path.length && cmpBound(f, end) < 0
|
|
125
|
+
? f.offset
|
|
126
|
+
: len;
|
|
127
|
+
return s < e ? { s, e } : null;
|
|
128
|
+
}
|
|
129
|
+
function withMark(node, mark) {
|
|
130
|
+
const rest = (node.marks ?? []).filter((m) => m.type !== mark.type);
|
|
131
|
+
return { ...node, marks: [...rest, mark] };
|
|
132
|
+
}
|
|
133
|
+
function withoutMark(node, markType) {
|
|
134
|
+
const marks = (node.marks ?? []).filter((m) => m.type !== markType);
|
|
135
|
+
return marks.length ? { ...node, marks } : { ...node, marks: undefined };
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 마크 range 엔드포인트를 현재 doc 좌표로 재해석한다.
|
|
139
|
+
* 스텝이 기록된 뒤 앞선 스텝(또는 되돌리기 대상 원본)이 텍스트를
|
|
140
|
+
* 분할하면, 예컨대 [2,0]:2..3이 가리키던 "H2O"는 [H2, O]가 되어
|
|
141
|
+
* 엔드포인트가 노드 길이를 넘어선다. 오프셋 초과분을 뒤따르는 텍스트
|
|
142
|
+
* 형제로 넘겨 의미상 같은 위치를 복원한다 — 이게 없으면 removeMark 뒤
|
|
143
|
+
* addMark처럼 같은 범위의 연속 마크 스텝과 부분 범위 마크의 undo가
|
|
144
|
+
* 조용히 무동작한다.
|
|
145
|
+
*/
|
|
146
|
+
export function resolveMarkPoint(doc, p) {
|
|
147
|
+
const n = nodeAt(doc, p.path);
|
|
148
|
+
if (n?.type !== "text")
|
|
149
|
+
return p;
|
|
150
|
+
let excess = p.offset - (n.text?.length ?? 0);
|
|
151
|
+
if (excess <= 0)
|
|
152
|
+
return p;
|
|
153
|
+
const parent = p.path.slice(0, -1);
|
|
154
|
+
let i = p.path[p.path.length - 1];
|
|
155
|
+
for (let sib = nodeAt(doc, [...parent, i + 1]); sib?.type === "text"; sib = nodeAt(doc, [...parent, ++i + 1])) {
|
|
156
|
+
const len = sib.text?.length ?? 0;
|
|
157
|
+
if (excess <= len)
|
|
158
|
+
return { path: [...parent, i + 1], offset: excess };
|
|
159
|
+
excess -= len;
|
|
160
|
+
}
|
|
161
|
+
// 뒤에 텍스트가 없으면 마지막 텍스트 형제(= 원래 노드) 끝으로 클램프
|
|
162
|
+
const lastText = nodeAt(doc, [...parent, i]);
|
|
163
|
+
return { path: [...parent, i], offset: lastText?.text?.length ?? 0 };
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 컨테이너 경계 포인트를 가장 가까운 텍스트 리프 포인트로 내린다.
|
|
167
|
+
* {P,k}(자식 k 앞)는 자식 k의 첫 텍스트 시작 — k가 자식 수를 넘으면
|
|
168
|
+
* 마지막 자식의 텍스트 끝. 마크/텍스트 추출처럼 리프 좌표가 필요한
|
|
169
|
+
* 곳에서 element-boundary 셀렉션을 환원할 때 쓴다. 텍스트가 없는
|
|
170
|
+
* 빈 컨테이너나 해석 불가면 원래 포인트를 돌려준다.
|
|
171
|
+
*/
|
|
172
|
+
export function leafPoint(doc, p) {
|
|
173
|
+
const top = nodeAt(doc, p.path);
|
|
174
|
+
if (!top || top.type === "text")
|
|
175
|
+
return p;
|
|
176
|
+
const path = [...p.path];
|
|
177
|
+
let node = top;
|
|
178
|
+
let idx = p.offset;
|
|
179
|
+
let endSide = false;
|
|
180
|
+
while (node && node.type !== "text") {
|
|
181
|
+
const kids = node.content ?? [];
|
|
182
|
+
if (!kids.length)
|
|
183
|
+
return p;
|
|
184
|
+
endSide = idx >= kids.length;
|
|
185
|
+
const i = endSide ? kids.length - 1 : Math.max(0, idx);
|
|
186
|
+
path.push(i);
|
|
187
|
+
node = kids[i];
|
|
188
|
+
idx = endSide ? (node.content?.length ?? 0) : 0;
|
|
189
|
+
}
|
|
190
|
+
return node?.type === "text"
|
|
191
|
+
? { path, offset: endSide ? (node.text?.length ?? 0) : 0 }
|
|
192
|
+
: p;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* 마크 적용/제거 — range와 겹치는 텍스트 노드를 [head, covered, tail]로
|
|
196
|
+
* 분할하고 covered 구간에만 마크를 넣거나 뺀다. 단일 패스라 위치가
|
|
197
|
+
* 흔들리지 않는다.
|
|
198
|
+
*/
|
|
199
|
+
function applyMark(doc, range, mark, markType) {
|
|
200
|
+
const adjust = mark
|
|
201
|
+
? (n) => withMark(n, mark)
|
|
202
|
+
: (n) => withoutMark(n, markType);
|
|
203
|
+
const resolved = {
|
|
204
|
+
anchor: resolveMarkPoint(doc, range.anchor),
|
|
205
|
+
focus: resolveMarkPoint(doc, range.focus),
|
|
206
|
+
};
|
|
207
|
+
const [out] = expandTextNodes(doc, [], (node, path) => {
|
|
208
|
+
const cov = coveredOffsets(node, path, resolved);
|
|
209
|
+
if (!cov)
|
|
210
|
+
return [node];
|
|
211
|
+
const text = node.text ?? "";
|
|
212
|
+
if (cov.s === 0 && cov.e === text.length)
|
|
213
|
+
return [adjust(node)];
|
|
214
|
+
const segs = [];
|
|
215
|
+
if (cov.s > 0)
|
|
216
|
+
segs.push({ ...node, text: text.slice(0, cov.s) });
|
|
217
|
+
segs.push(adjust({ ...node, text: text.slice(cov.s, cov.e) }));
|
|
218
|
+
if (cov.e < text.length)
|
|
219
|
+
segs.push({ ...node, text: text.slice(cov.e) });
|
|
220
|
+
return segs;
|
|
221
|
+
});
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
export function computeSplitOps(doc, step) {
|
|
225
|
+
const ops = [];
|
|
226
|
+
let at = step.at;
|
|
227
|
+
const depth = step.depth ?? 1;
|
|
228
|
+
if (nodeAt(doc, at.path)?.type === "text") {
|
|
229
|
+
ops.push({ kind: "text", path: at.path, offset: at.offset });
|
|
230
|
+
at = {
|
|
231
|
+
path: at.path.slice(0, -1),
|
|
232
|
+
offset: at.path[at.path.length - 1] + 1,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
for (let d = 0; d < depth; d++) {
|
|
236
|
+
if (at.path.length === 0)
|
|
237
|
+
break; // doc 루트는 나눌 수 없다
|
|
238
|
+
ops.push({ kind: "node", path: at.path, index: at.offset });
|
|
239
|
+
at = {
|
|
240
|
+
path: at.path.slice(0, -1),
|
|
241
|
+
offset: at.path[at.path.length - 1] + 1,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
return ops;
|
|
245
|
+
}
|
|
246
|
+
function applySplitOps(doc, ops) {
|
|
247
|
+
let d = doc;
|
|
248
|
+
for (const op of ops) {
|
|
249
|
+
if (op.kind === "text") {
|
|
250
|
+
const t = nodeAt(d, op.path);
|
|
251
|
+
if (!t || t.type !== "text")
|
|
252
|
+
continue;
|
|
253
|
+
const text = t.text ?? "";
|
|
254
|
+
const parent = op.path.slice(0, -1);
|
|
255
|
+
const i = op.path[op.path.length - 1];
|
|
256
|
+
d = spliceChildren(d, parent, i, i + 1, [
|
|
257
|
+
{ ...t, text: text.slice(0, op.offset) },
|
|
258
|
+
{ ...t, text: text.slice(op.offset) },
|
|
259
|
+
]);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
const n = nodeAt(d, op.path);
|
|
263
|
+
if (!n?.content)
|
|
264
|
+
continue;
|
|
265
|
+
const parent = op.path.slice(0, -1);
|
|
266
|
+
const i = op.path[op.path.length - 1];
|
|
267
|
+
const left = { ...n, content: n.content.slice(0, op.index) };
|
|
268
|
+
const right = { ...n, content: n.content.slice(op.index) };
|
|
269
|
+
d = spliceChildren(d, parent, i, i + 1, [left, right]);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return d;
|
|
273
|
+
}
|
|
274
|
+
function applyJoin(doc, step) {
|
|
275
|
+
const parent = nodeAt(doc, step.at.path);
|
|
276
|
+
const i = step.at.offset;
|
|
277
|
+
const prev = parent?.content?.[i - 1];
|
|
278
|
+
const next = parent?.content?.[i];
|
|
279
|
+
if (!prev || !next)
|
|
280
|
+
return doc;
|
|
281
|
+
let merged = null;
|
|
282
|
+
if (prev.type === "text" && next.type === "text" && marksEq(prev.marks, next.marks)) {
|
|
283
|
+
merged = { ...prev, text: (prev.text ?? "") + (next.text ?? "") };
|
|
284
|
+
}
|
|
285
|
+
else if (prev.type === next.type && prev.content && next.content) {
|
|
286
|
+
merged = { ...prev, content: [...prev.content, ...next.content] };
|
|
287
|
+
}
|
|
288
|
+
if (!merged)
|
|
289
|
+
return doc;
|
|
290
|
+
return spliceChildren(doc, step.at.path, i - 1, i + 1, [merged]);
|
|
291
|
+
}
|
|
292
|
+
// ── 위치 매핑 — step 적용 후 point가 어디로 가는가 ──────────
|
|
293
|
+
/**
|
|
294
|
+
* mapPoint(p, step, docBefore) — PM의 pos mapping과 같은 역할.
|
|
295
|
+
* 셀렉션을 트랜잭션 이후로 넘기는 데 쓴다.
|
|
296
|
+
* 규약: insert는 "왼쪽 편향"(같은 위치의 포인트는 삽입물 앞에 머문다),
|
|
297
|
+
* remove는 범위 안 포인트를 제거 시작점으로 클램프한다.
|
|
298
|
+
*/
|
|
299
|
+
export function mapPoint(p, step, doc) {
|
|
300
|
+
switch (step.op) {
|
|
301
|
+
case "insert":
|
|
302
|
+
return mapInsert(p, step, doc);
|
|
303
|
+
case "remove":
|
|
304
|
+
return mapRemove(p, step, doc);
|
|
305
|
+
case "setAttr":
|
|
306
|
+
return p;
|
|
307
|
+
case "addMark":
|
|
308
|
+
case "removeMark":
|
|
309
|
+
return mapThroughMarkStep(p, step, doc);
|
|
310
|
+
case "split":
|
|
311
|
+
return computeSplitOps(doc, step).reduce((pt, op) => mapThroughSplitOp(pt, op), p);
|
|
312
|
+
case "join":
|
|
313
|
+
return mapThroughJoin(p, step, doc);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function pathEq(a, b) {
|
|
317
|
+
return a.length === b.length && a.every((v, i) => v === b[i]);
|
|
318
|
+
}
|
|
319
|
+
function last(path) {
|
|
320
|
+
return path[path.length - 1];
|
|
321
|
+
}
|
|
322
|
+
/** p가 path를 접두어로 가지는가 (path 내부의 descendant) */
|
|
323
|
+
function hasPrefix(p, path) {
|
|
324
|
+
return p.length > path.length && path.every((v, i) => v === p[i]);
|
|
325
|
+
}
|
|
326
|
+
function mapInsert(p, step, doc) {
|
|
327
|
+
const target = nodeAt(doc, step.at.path);
|
|
328
|
+
if (target?.type === "text") {
|
|
329
|
+
const o = step.at.offset;
|
|
330
|
+
const insLen = step.node.text?.length ?? 0;
|
|
331
|
+
if (pathEq(p.path, step.at.path)) {
|
|
332
|
+
if (marksEq(target.marks, step.node.marks)) {
|
|
333
|
+
return p.offset > o ? { ...p, offset: p.offset + insLen } : p;
|
|
334
|
+
}
|
|
335
|
+
// 분할 삽입: [head, ins, tail]
|
|
336
|
+
const parent = step.at.path.slice(0, -1);
|
|
337
|
+
const i = last(step.at.path);
|
|
338
|
+
if (p.offset <= o)
|
|
339
|
+
return p;
|
|
340
|
+
return { path: [...parent, i + 1 + (o > 0 ? 1 : 0)], offset: p.offset - o };
|
|
341
|
+
}
|
|
342
|
+
// 분할 삽입이면 같은 부모 안 형제가 뒤로 민린다 (merge면 변화 없음)
|
|
343
|
+
if (!marksEq(target.marks, step.node.marks)) {
|
|
344
|
+
const parent = step.at.path.slice(0, -1);
|
|
345
|
+
const i = last(step.at.path);
|
|
346
|
+
const extra = (o > 0 ? 1 : 0) + (o < (target.text?.length ?? 0) ? 1 : 0);
|
|
347
|
+
if (hasPrefix(p.path, parent) && p.path[parent.length] > i) {
|
|
348
|
+
const q = p.path.slice();
|
|
349
|
+
q[parent.length] = q[parent.length] + extra;
|
|
350
|
+
return { path: q, offset: p.offset };
|
|
351
|
+
}
|
|
352
|
+
if (pathEq(p.path, parent) && p.offset > i) {
|
|
353
|
+
return { ...p, offset: p.offset + extra };
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
return p;
|
|
357
|
+
}
|
|
358
|
+
// 자식 삽입: 경계 포인트는 >i만 밀리고, 자식 i 이하의 descendant는 +1
|
|
359
|
+
const Q = step.at.path;
|
|
360
|
+
const i = step.at.offset;
|
|
361
|
+
if (hasPrefix(p.path, Q) && p.path[Q.length] >= i) {
|
|
362
|
+
const q = p.path.slice();
|
|
363
|
+
q[Q.length] = q[Q.length] + 1;
|
|
364
|
+
return { path: q, offset: p.offset };
|
|
365
|
+
}
|
|
366
|
+
if (pathEq(p.path, Q) && p.offset > i)
|
|
367
|
+
return { ...p, offset: p.offset + 1 };
|
|
368
|
+
return p;
|
|
369
|
+
}
|
|
370
|
+
function mapRemove(p, step, doc) {
|
|
371
|
+
const target = nodeAt(doc, step.at.path);
|
|
372
|
+
if (target?.type === "text") {
|
|
373
|
+
if (!pathEq(p.path, step.at.path))
|
|
374
|
+
return p;
|
|
375
|
+
const o = step.at.offset;
|
|
376
|
+
const len = step.node.text?.length ?? 0;
|
|
377
|
+
if (p.offset <= o)
|
|
378
|
+
return p;
|
|
379
|
+
if (p.offset <= o + len)
|
|
380
|
+
return { ...p, offset: o };
|
|
381
|
+
return { ...p, offset: p.offset - len };
|
|
382
|
+
}
|
|
383
|
+
const Q = step.at.path;
|
|
384
|
+
const i = step.at.offset;
|
|
385
|
+
if (hasPrefix(p.path, Q)) {
|
|
386
|
+
const j = p.path[Q.length];
|
|
387
|
+
if (j === i)
|
|
388
|
+
return { path: Q, offset: i }; // 제거된 노드 안 → 제거 위치로
|
|
389
|
+
if (j > i) {
|
|
390
|
+
const q = p.path.slice();
|
|
391
|
+
q[Q.length] = j - 1;
|
|
392
|
+
return { path: q, offset: p.offset };
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (pathEq(p.path, Q) && p.offset > i)
|
|
396
|
+
return { ...p, offset: p.offset - 1 };
|
|
397
|
+
return p;
|
|
398
|
+
}
|
|
399
|
+
/** 마크 step으로 부분 분할되는 텍스트 노드 목록 (전체 커버는 분할 없음) */
|
|
400
|
+
function collectMarkSplits(doc, step) {
|
|
401
|
+
const out = [];
|
|
402
|
+
expandTextNodes(doc, [], (node, path) => {
|
|
403
|
+
const cov = coveredOffsets(node, path, step.range);
|
|
404
|
+
const len = node.text?.length ?? 0;
|
|
405
|
+
if (cov && (cov.s > 0 || cov.e < len)) {
|
|
406
|
+
out.push({ path, s: cov.s, e: cov.e, tail: cov.e < len });
|
|
407
|
+
}
|
|
408
|
+
return [node];
|
|
409
|
+
});
|
|
410
|
+
return out;
|
|
411
|
+
}
|
|
412
|
+
function mapThroughMarkStep(p, step, doc) {
|
|
413
|
+
let out = p;
|
|
414
|
+
for (const sp of collectMarkSplits(doc, step)) {
|
|
415
|
+
out = mapThroughTextSplit3(out, sp.path, sp.s, sp.e, sp.tail);
|
|
416
|
+
}
|
|
417
|
+
return out;
|
|
418
|
+
}
|
|
419
|
+
/** 텍스트 노드를 [0..s][s..e][e..len] 분할한 것으로 포인트를 매핑 */
|
|
420
|
+
function mapThroughTextSplit3(p, path, s, e, tail) {
|
|
421
|
+
const parent = path.slice(0, -1);
|
|
422
|
+
const i = last(path);
|
|
423
|
+
const segs = (s > 0 ? 1 : 0) + 1 + (tail ? 1 : 0);
|
|
424
|
+
if (pathEq(p.path, path)) {
|
|
425
|
+
if (p.offset <= s)
|
|
426
|
+
return p;
|
|
427
|
+
if (p.offset <= e) {
|
|
428
|
+
return { path: [...parent, i + (s > 0 ? 1 : 0)], offset: p.offset - s };
|
|
429
|
+
}
|
|
430
|
+
return {
|
|
431
|
+
path: [...parent, i + (s > 0 ? 1 : 0) + 1],
|
|
432
|
+
offset: p.offset - e,
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
if (hasPrefix(p.path, parent) && p.path[parent.length] > i) {
|
|
436
|
+
const q = p.path.slice();
|
|
437
|
+
q[parent.length] = q[parent.length] + (segs - 1);
|
|
438
|
+
return { path: q, offset: p.offset };
|
|
439
|
+
}
|
|
440
|
+
if (pathEq(p.path, parent) && p.offset > i) {
|
|
441
|
+
return { ...p, offset: p.offset + (segs - 1) };
|
|
442
|
+
}
|
|
443
|
+
return p;
|
|
444
|
+
}
|
|
445
|
+
export function mapThroughSplitOp(p, op) {
|
|
446
|
+
if (op.kind === "text") {
|
|
447
|
+
const parent = op.path.slice(0, -1);
|
|
448
|
+
const i = last(op.path);
|
|
449
|
+
if (pathEq(p.path, op.path)) {
|
|
450
|
+
return p.offset <= op.offset
|
|
451
|
+
? p
|
|
452
|
+
: { path: [...parent, i + 1], offset: p.offset - op.offset };
|
|
453
|
+
}
|
|
454
|
+
if (hasPrefix(p.path, parent) && p.path[parent.length] > i) {
|
|
455
|
+
const q = p.path.slice();
|
|
456
|
+
q[parent.length] = q[parent.length] + 1;
|
|
457
|
+
return { path: q, offset: p.offset };
|
|
458
|
+
}
|
|
459
|
+
if (pathEq(p.path, parent) && p.offset > i) {
|
|
460
|
+
return { ...p, offset: p.offset + 1 };
|
|
461
|
+
}
|
|
462
|
+
return p;
|
|
463
|
+
}
|
|
464
|
+
// node split: op.path 노드를 index에서 둘로 — 뒷부분은 parent의 i+1 형제로
|
|
465
|
+
const Q = op.path;
|
|
466
|
+
const parent = Q.slice(0, -1);
|
|
467
|
+
const qi = last(Q);
|
|
468
|
+
const c = op.index;
|
|
469
|
+
if (pathEq(p.path, Q)) {
|
|
470
|
+
return p.offset >= c
|
|
471
|
+
? { path: [...parent, qi + 1], offset: p.offset - c }
|
|
472
|
+
: p;
|
|
473
|
+
}
|
|
474
|
+
if (hasPrefix(p.path, Q)) {
|
|
475
|
+
const j = p.path[Q.length];
|
|
476
|
+
if (j >= c) {
|
|
477
|
+
return { path: [...parent, qi + 1, j - c, ...p.path.slice(Q.length + 1)], offset: p.offset };
|
|
478
|
+
}
|
|
479
|
+
return p;
|
|
480
|
+
}
|
|
481
|
+
if (hasPrefix(p.path, parent) && p.path[parent.length] > qi) {
|
|
482
|
+
const q = p.path.slice();
|
|
483
|
+
q[parent.length] = q[parent.length] + 1;
|
|
484
|
+
return { path: q, offset: p.offset };
|
|
485
|
+
}
|
|
486
|
+
if (pathEq(p.path, parent) && p.offset > qi) {
|
|
487
|
+
return { ...p, offset: p.offset + 1 };
|
|
488
|
+
}
|
|
489
|
+
return p;
|
|
490
|
+
}
|
|
491
|
+
function mapThroughJoin(p, step, doc) {
|
|
492
|
+
const Q = step.at.path;
|
|
493
|
+
const i = step.at.offset;
|
|
494
|
+
const prev = nodeAt(doc, [...Q, i - 1]);
|
|
495
|
+
if (!prev)
|
|
496
|
+
return p;
|
|
497
|
+
const mergedSize = prev.type === "text" ? (prev.text?.length ?? 0) : (prev.content?.length ?? 0);
|
|
498
|
+
if (hasPrefix(p.path, Q) && p.path[Q.length] === i) {
|
|
499
|
+
if (p.path.length === Q.length + 1) {
|
|
500
|
+
// 합쳐진 노드 안의 포인트 — seam만큼 뒤로
|
|
501
|
+
return { path: [...Q, i - 1], offset: p.offset + mergedSize };
|
|
502
|
+
}
|
|
503
|
+
return {
|
|
504
|
+
path: [
|
|
505
|
+
...Q,
|
|
506
|
+
i - 1,
|
|
507
|
+
p.path[Q.length + 1] + mergedSize,
|
|
508
|
+
...p.path.slice(Q.length + 2),
|
|
509
|
+
],
|
|
510
|
+
offset: p.offset,
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
if (hasPrefix(p.path, Q) && p.path[Q.length] > i) {
|
|
514
|
+
const q = p.path.slice();
|
|
515
|
+
q[Q.length] = q[Q.length] - 1;
|
|
516
|
+
return { path: q, offset: p.offset };
|
|
517
|
+
}
|
|
518
|
+
if (pathEq(p.path, Q)) {
|
|
519
|
+
if (p.offset === i)
|
|
520
|
+
return { path: [...Q, i - 1], offset: mergedSize };
|
|
521
|
+
if (p.offset > i)
|
|
522
|
+
return { ...p, offset: p.offset - 1 };
|
|
523
|
+
}
|
|
524
|
+
return p;
|
|
525
|
+
}
|
|
526
|
+
// 테스트/디버깅 편의 재노출
|
|
527
|
+
export { pointEq, pathEq };
|
|
528
|
+
//# sourceMappingURL=apply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/state/apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DocNode } from "../model/node.js";
|
|
2
|
+
import type { Point } from "./selection.js";
|
|
3
|
+
export declare function pointBefore(doc: DocNode, p: Point): Point | null;
|
|
4
|
+
export declare function pointAfter(doc: DocNode, p: Point): Point | null;
|
|
5
|
+
//# sourceMappingURL=navigate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../../src/state/navigate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAc,MAAM,kBAAkB,CAAC;AAE5D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AA0B5C,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,IAAI,CAchE;AAaD,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,IAAI,CAU/D"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { nodeAt } from "../model/traverse.js";
|
|
2
|
+
/**
|
|
3
|
+
* 커서 이동 네비게이션 — pointBefore/pointAfter는 Backspace/Delete가
|
|
4
|
+
* 쓰는 "한 단계 앞/뒤의 유효 포인트"를 계산한다.
|
|
5
|
+
* 규칙: 텍스트 안이면 문자 오프셋 ±1, 경계면 이전/다음 텍스트 끝으로
|
|
6
|
+
* 건너간다. 아톰 노드는 통째로 한 칸 취급한다(경계에 멈춘다).
|
|
7
|
+
*/
|
|
8
|
+
/** 노드 안의 가장 오른쪽(끝) 포인트 — 텍스트면 끝, 컨테이너면 재귀 */
|
|
9
|
+
function rightmost(node, path) {
|
|
10
|
+
if (node.type === "text")
|
|
11
|
+
return { path, offset: node.text?.length ?? 0 };
|
|
12
|
+
const kids = node.content ?? [];
|
|
13
|
+
const last = kids[kids.length - 1];
|
|
14
|
+
if (!last)
|
|
15
|
+
return { path, offset: 0 };
|
|
16
|
+
return rightmost(last, [...path, kids.length - 1]);
|
|
17
|
+
}
|
|
18
|
+
/** 노드 안의 가장 왼쪽(처음) 포인트 */
|
|
19
|
+
function leftmost(node, path) {
|
|
20
|
+
if (node.type === "text")
|
|
21
|
+
return { path, offset: 0 };
|
|
22
|
+
const first = node.content?.[0];
|
|
23
|
+
if (!first)
|
|
24
|
+
return { path, offset: 0 };
|
|
25
|
+
return leftmost(first, [...path, 0]);
|
|
26
|
+
}
|
|
27
|
+
export function pointBefore(doc, p) {
|
|
28
|
+
const node = nodeAt(doc, p.path);
|
|
29
|
+
if (node?.type === "text") {
|
|
30
|
+
if (p.offset > 0)
|
|
31
|
+
return { path: p.path, offset: p.offset - 1 };
|
|
32
|
+
// 텍스트 시작 — 앞 형제의 오른쪽 끝으로
|
|
33
|
+
return beforeNode(doc, p.path);
|
|
34
|
+
}
|
|
35
|
+
// 컨테이너 안 경계 — offset 자식의 왼쪽은 child[offset-1] 안쪽
|
|
36
|
+
const parent = node;
|
|
37
|
+
const i = p.offset;
|
|
38
|
+
const left = parent?.content?.[i - 1];
|
|
39
|
+
if (left)
|
|
40
|
+
return rightmost(left, [...p.path, i - 1]);
|
|
41
|
+
// 부모 시작 — 부모 노드 앞으로 올라간다
|
|
42
|
+
return p.path.length ? beforeNode(doc, p.path) : null;
|
|
43
|
+
}
|
|
44
|
+
/** path 노드 "바로 앞"의 포인트 — 없으면 null (문서 시작) */
|
|
45
|
+
function beforeNode(doc, path) {
|
|
46
|
+
const i = path[path.length - 1];
|
|
47
|
+
const parentPath = path.slice(0, -1);
|
|
48
|
+
const parent = nodeAt(doc, parentPath);
|
|
49
|
+
if (i == null || !parent)
|
|
50
|
+
return null;
|
|
51
|
+
const left = parent.content?.[i - 1];
|
|
52
|
+
if (left)
|
|
53
|
+
return rightmost(left, [...parentPath, i - 1]);
|
|
54
|
+
return parentPath.length ? beforeNode(doc, parentPath) : { path: parentPath, offset: 0 };
|
|
55
|
+
}
|
|
56
|
+
export function pointAfter(doc, p) {
|
|
57
|
+
const node = nodeAt(doc, p.path);
|
|
58
|
+
if (node?.type === "text") {
|
|
59
|
+
const len = node.text?.length ?? 0;
|
|
60
|
+
if (p.offset < len)
|
|
61
|
+
return { path: p.path, offset: p.offset + 1 };
|
|
62
|
+
return afterNode(doc, p.path);
|
|
63
|
+
}
|
|
64
|
+
const right = node?.content?.[p.offset];
|
|
65
|
+
if (right)
|
|
66
|
+
return leftmost(right, [...p.path, p.offset]);
|
|
67
|
+
return p.path.length ? afterNode(doc, p.path) : null;
|
|
68
|
+
}
|
|
69
|
+
/** path 노드 "바로 뒤"의 포인트 — 없으면 null (문서 끝) */
|
|
70
|
+
function afterNode(doc, path) {
|
|
71
|
+
const i = path[path.length - 1];
|
|
72
|
+
const parentPath = path.slice(0, -1);
|
|
73
|
+
const parent = nodeAt(doc, parentPath);
|
|
74
|
+
if (i == null || !parent)
|
|
75
|
+
return null;
|
|
76
|
+
const right = parent.content?.[i + 1];
|
|
77
|
+
if (right)
|
|
78
|
+
return leftmost(right, [...parentPath, i + 1]);
|
|
79
|
+
return parentPath.length ? afterNode(doc, parentPath) : null;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=navigate.js.map
|