@moda-editor/core 0.3.0 → 0.3.2

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.
Files changed (136) hide show
  1. package/dist/commands.d.ts.map +1 -1
  2. package/dist/commands.js +38 -5
  3. package/dist/commands.js.map +1 -1
  4. package/dist/conformance/editor-ime.d.ts.map +1 -1
  5. package/dist/conformance/editor-ime.js +78 -0
  6. package/dist/conformance/editor-ime.js.map +1 -1
  7. package/dist/editor/editor.d.ts.map +1 -1
  8. package/dist/editor/editor.js +3 -1
  9. package/dist/editor/editor.js.map +1 -1
  10. package/dist/features/code-block.d.ts.map +1 -1
  11. package/dist/features/code-block.js +10 -2
  12. package/dist/features/code-block.js.map +1 -1
  13. package/dist/features/code-edit.d.ts.map +1 -1
  14. package/dist/features/code-edit.js.map +1 -1
  15. package/dist/features/code-format.js.map +1 -1
  16. package/dist/features/hard-break.d.ts.map +1 -1
  17. package/dist/features/hard-break.js +2 -0
  18. package/dist/features/hard-break.js.map +1 -1
  19. package/dist/features/heading.d.ts.map +1 -1
  20. package/dist/features/heading.js +3 -1
  21. package/dist/features/heading.js.map +1 -1
  22. package/dist/features/horizontal-rule.d.ts.map +1 -1
  23. package/dist/features/horizontal-rule.js.map +1 -1
  24. package/dist/features/image.d.ts.map +1 -1
  25. package/dist/features/image.js.map +1 -1
  26. package/dist/features/link.d.ts.map +1 -1
  27. package/dist/features/link.js.map +1 -1
  28. package/dist/features/marks.d.ts.map +1 -1
  29. package/dist/features/marks.js +1 -1
  30. package/dist/features/marks.js.map +1 -1
  31. package/dist/features/search.d.ts.map +1 -1
  32. package/dist/features/search.js +1 -7
  33. package/dist/features/search.js.map +1 -1
  34. package/dist/features/table.d.ts.map +1 -1
  35. package/dist/features/table.js +30 -7
  36. package/dist/features/table.js.map +1 -1
  37. package/dist/history.d.ts.map +1 -1
  38. package/dist/history.js.map +1 -1
  39. package/dist/index.d.ts +6 -5
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +3 -3
  42. package/dist/index.js.map +1 -1
  43. package/dist/model/node.d.ts.map +1 -1
  44. package/dist/model/node.js +1 -2
  45. package/dist/model/node.js.map +1 -1
  46. package/dist/model/schema.d.ts +7 -0
  47. package/dist/model/schema.d.ts.map +1 -1
  48. package/dist/model/schema.js.map +1 -1
  49. package/dist/model/traverse.d.ts +10 -3
  50. package/dist/model/traverse.d.ts.map +1 -1
  51. package/dist/model/traverse.js +13 -5
  52. package/dist/model/traverse.js.map +1 -1
  53. package/dist/parse/html.d.ts.map +1 -1
  54. package/dist/parse/html.js +28 -1
  55. package/dist/parse/html.js.map +1 -1
  56. package/dist/presets/markdown-parse.d.ts.map +1 -1
  57. package/dist/presets/markdown-parse.js +9 -0
  58. package/dist/presets/markdown-parse.js.map +1 -1
  59. package/dist/presets/markdown.d.ts.map +1 -1
  60. package/dist/presets/markdown.js +7 -6
  61. package/dist/presets/markdown.js.map +1 -1
  62. package/dist/presets/starter.d.ts.map +1 -1
  63. package/dist/presets/starter.js.map +1 -1
  64. package/dist/state/apply.d.ts.map +1 -1
  65. package/dist/state/apply.js +1 -3
  66. package/dist/state/apply.js.map +1 -1
  67. package/dist/state/input-rules.d.ts.map +1 -1
  68. package/dist/state/input-rules.js +4 -0
  69. package/dist/state/input-rules.js.map +1 -1
  70. package/dist/state/insert-ops.d.ts.map +1 -1
  71. package/dist/state/insert-ops.js +9 -2
  72. package/dist/state/insert-ops.js.map +1 -1
  73. package/dist/state/list-ops.d.ts.map +1 -1
  74. package/dist/state/list-ops.js.map +1 -1
  75. package/dist/state/navigate.d.ts.map +1 -1
  76. package/dist/state/navigate.js +14 -4
  77. package/dist/state/navigate.js.map +1 -1
  78. package/dist/state/resolve-insert.d.ts.map +1 -1
  79. package/dist/state/resolve-insert.js +17 -3
  80. package/dist/state/resolve-insert.js.map +1 -1
  81. package/dist/state/slice-ops.js +16 -9
  82. package/dist/state/slice-ops.js.map +1 -1
  83. package/dist/styles.css +27 -12
  84. package/dist/theme.d.ts.map +1 -1
  85. package/dist/theme.js.map +1 -1
  86. package/dist/view/decoration.d.ts.map +1 -1
  87. package/dist/view/decoration.js +60 -44
  88. package/dist/view/decoration.js.map +1 -1
  89. package/dist/view/highlight-registry.d.ts.map +1 -1
  90. package/dist/view/highlight-registry.js.map +1 -1
  91. package/dist/view/ime.d.ts +1 -1
  92. package/dist/view/ime.d.ts.map +1 -1
  93. package/dist/view/ime.js +85 -12
  94. package/dist/view/ime.js.map +1 -1
  95. package/dist/view/input-beforeinput.d.ts +25 -0
  96. package/dist/view/input-beforeinput.d.ts.map +1 -0
  97. package/dist/view/input-beforeinput.js +330 -0
  98. package/dist/view/input-beforeinput.js.map +1 -0
  99. package/dist/view/input-keys.d.ts +25 -0
  100. package/dist/view/input-keys.d.ts.map +1 -0
  101. package/dist/view/input-keys.js +69 -0
  102. package/dist/view/input-keys.js.map +1 -0
  103. package/dist/view/input-pointer.d.ts +24 -0
  104. package/dist/view/input-pointer.d.ts.map +1 -0
  105. package/dist/view/input-pointer.js +96 -0
  106. package/dist/view/input-pointer.js.map +1 -0
  107. package/dist/view/input-selection.d.ts +41 -0
  108. package/dist/view/input-selection.d.ts.map +1 -0
  109. package/dist/view/input-selection.js +216 -0
  110. package/dist/view/input-selection.js.map +1 -0
  111. package/dist/view/input.d.ts +25 -30
  112. package/dist/view/input.d.ts.map +1 -1
  113. package/dist/view/input.js +36 -685
  114. package/dist/view/input.js.map +1 -1
  115. package/dist/view/mount.d.ts.map +1 -1
  116. package/dist/view/mount.js +20 -7
  117. package/dist/view/mount.js.map +1 -1
  118. package/dist/view/node-selection.d.ts.map +1 -1
  119. package/dist/view/node-selection.js +1 -3
  120. package/dist/view/node-selection.js.map +1 -1
  121. package/dist/view/render.d.ts.map +1 -1
  122. package/dist/view/render.js +10 -3
  123. package/dist/view/render.js.map +1 -1
  124. package/dist/widget/core.d.ts +37 -0
  125. package/dist/widget/core.d.ts.map +1 -0
  126. package/dist/widget/core.js +117 -0
  127. package/dist/widget/core.js.map +1 -0
  128. package/dist/widget/mount.d.ts +24 -0
  129. package/dist/widget/mount.d.ts.map +1 -0
  130. package/dist/widget/mount.js +45 -0
  131. package/dist/widget/mount.js.map +1 -0
  132. package/dist/widget/types.d.ts +44 -0
  133. package/dist/widget/types.d.ts.map +1 -0
  134. package/dist/widget/types.js +8 -0
  135. package/dist/widget/types.js.map +1 -0
  136. package/package.json +2 -6
package/dist/view/ime.js CHANGED
@@ -13,6 +13,9 @@ export function createImeSession(host) {
13
13
  let composing = false;
14
14
  // 조합이 시작된 리프 포인트 — 흡수가 DOM 셀렉션을 못 읽을 때의 폴백
15
15
  let compStart = null;
16
+ // 조합 시작 시점 리프의 doc 텍스트 — 흡수 대기 창에 외부(원격·
17
+ // 플러그인) 편집이 리프를 바꿨는지 구분하는 기준
18
+ let compStartText = null;
16
19
  // compositionend → flush 예약 타이머
17
20
  let compTimer = null;
18
21
  // compositionend가 왔고 흡수만 남은 상태 — 이 창에 도착하는 구조
@@ -23,6 +26,11 @@ export function createImeSession(host) {
23
26
  // 한 번 더 보낸다(Safari 확정, Chromium도 비동기 커밋 경로가 있다) —
24
27
  // 타이머보다 늦게 오면 에코를 구별하기 위해 종료 시각을 기록한다
25
28
  let compEndedAt = 0;
29
+ // compositionend의 커밋 페이로드 — 늦은 에코는 이 문자열을 반복한다.
30
+ // "DOM 끝자락 일치"만으로는 커밋 직후 같은 문자를 재입력한 실제
31
+ // 키입력까지 에코로 삼키므로 페이로드 일치를 함께 요구한다.
32
+ // 페이로드를 못 읽는 환경(null)은 기존 판정으로 폴백한다
33
+ let compEndData = null;
26
34
  /**
27
35
  * composition 중 브라우저가 직접 바꾼 DOM을 doc에 흡수한다.
28
36
  * 캐럿이 위치한 텍스트 홀더의 DOM 텍스트와 doc 텍스트를 공통
@@ -30,17 +38,64 @@ export function createImeSession(host) {
30
38
  * (제약: 조합이 하나의 텍스트 홀더 안에 머문다고 가정 —
31
39
  * 크로스-블록 조합 삭제는 compositionstart의 선처리가 막는다)
32
40
  */
41
+ /** 포인트가 가리키는 리프의 doc 텍스트 — 비텍스트면 ""로 본다 */
42
+ const docTextAt = (p) => {
43
+ const n = nodeAt(editor.state.doc, p.path);
44
+ return n?.type === "text" ? (n.text ?? "") : "";
45
+ };
33
46
  const absorbComposition = () => {
34
- const focus = readDomSel()?.focus ?? compStart;
47
+ const live = readDomSel()?.focus;
48
+ let focus = live ?? compStart;
49
+ // DOM 셀렉션이 조합 리프 밖으로 나갔다(흡수 대기 창의 클릭 등) —
50
+ // 커밋은 조합이 시작된 홀더에 쓰였으니 그 DOM이 doc과 어긋나면
51
+ // 조합 홀더를 diff해야 커밋이 살아남는다. compStart 쪽이 깨끗하면
52
+ // (원격 편집으로 경로가 밀린 경우 등) 라이브 셀렉션을 따른다
53
+ if (compStart && live && !pathEq(compStart.path, live.path)) {
54
+ const startHolder = compStart.path.length
55
+ ? el.querySelector(`[${PATH_ATTR}="${compStart.path.join(",")}"]`)
56
+ : null;
57
+ if ((startHolder?.textContent ?? "") !== docTextAt(compStart)) {
58
+ focus = compStart;
59
+ }
60
+ }
35
61
  if (!focus || focus.path.length === 0)
36
62
  return;
37
- const holder = el.querySelector(`[${PATH_ATTR}="${focus.path.join(",")}"]`);
38
- // 텍스트 홀더가 아니면(안에 me-path 자식이 있으면) 흡수 불가
39
- if (!holder || holder.querySelector(`[${PATH_ATTR}]`))
63
+ // 텍스트 홀더를 찾는다 — focus가 컨테이너 경계({[i],k})면 홀더가
64
+ // 아니라 블록이 걸리므로, 캐럿 기준 이웃 자식 경로로 내려간다.
65
+ // Chromium은 빈 문단(bogus br)의 조합 커밋 뒤 캐럿을 <p>의 자식
66
+ // 인덱스 경계에 놓는다 — 이 경로를 해석 못 하면 커밋이 통째로 유실된다
67
+ const holderPath = (p) => el.querySelector(`[${PATH_ATTR}="${p.join(",")}"]`);
68
+ const isTextHolder = (h) => !!h && !h.querySelector(`[${PATH_ATTR}]`);
69
+ let focusPath = focus.path;
70
+ let holder = holderPath(focusPath);
71
+ if (!isTextHolder(holder)) {
72
+ holder = null;
73
+ for (const i of [focus.offset - 1, focus.offset]) {
74
+ if (i < 0)
75
+ continue;
76
+ const p = [...focus.path, i];
77
+ const h = holderPath(p);
78
+ if (isTextHolder(h)) {
79
+ holder = h;
80
+ focusPath = p;
81
+ break;
82
+ }
83
+ }
84
+ }
85
+ if (!holder)
40
86
  return;
41
87
  const domText = holder.textContent ?? "";
42
- const target = nodeAt(editor.state.doc, focus.path);
43
- const docText = target?.type === "text" ? (target.text ?? "") : "";
88
+ const docText = docTextAt({ path: focusPath, offset: focus.offset });
89
+ // 조합 리프의 doc이 시작 스냅샷과 다르면 대기 창에 외부(원격·
90
+ // 플러그인) 편집이 들어온 것 — DOM(스냅샷+커밋 텍스트) 기준 diff가
91
+ // 그 편집을 지우므로 흡수를 건너뛴다. 커밋은 유실되지만 문서는
92
+ // 수렴 상태를 유지한다
93
+ if (compStart &&
94
+ compStartText !== null &&
95
+ pathEq(focusPath, compStart.path) &&
96
+ docText !== compStartText) {
97
+ return;
98
+ }
44
99
  if (domText === docText)
45
100
  return;
46
101
  let lo = 0;
@@ -58,13 +113,13 @@ export function createImeSession(host) {
58
113
  const tr = editor.state.tr();
59
114
  if (hiDoc > lo) {
60
115
  tr.delete({
61
- anchor: point(focus.path, lo),
62
- focus: point(focus.path, hiDoc),
116
+ anchor: point(focusPath, lo),
117
+ focus: point(focusPath, hiDoc),
63
118
  });
64
119
  }
65
120
  const inserted = domText.slice(lo, hiDom);
66
121
  if (inserted)
67
- tr.insertText(inserted, point(focus.path, lo));
122
+ tr.insertText(inserted, point(focusPath, lo));
68
123
  if (!tr.docChanged)
69
124
  return;
70
125
  tr.setMeta("history.group", "type").setMeta("ime", true);
@@ -89,6 +144,7 @@ export function createImeSession(host) {
89
144
  if (editor.editable)
90
145
  absorbComposition();
91
146
  compStart = null;
147
+ compStartText = null;
92
148
  };
93
149
  return {
94
150
  get active() {
@@ -137,14 +193,25 @@ export function createImeSession(host) {
137
193
  }
138
194
  compStart = head;
139
195
  }
196
+ // 흡수 대상 리프의 doc 텍스트 스냅샷 — 대기 창에 외부 편집이
197
+ // 들어왔는지 absorb이 판별하는 기준 (정리 tr 이후에 잡는다)
198
+ compStartText = compStart ? docTextAt(compStart) : null;
199
+ compEndData = null;
140
200
  },
141
- end() {
201
+ end(e) {
202
+ // start 없는 compositionend(일부 IME의 취소·포커스 해제 경로)나
203
+ // 같은 세션의 중복 end는 무시한다 — 없는 조합을 흡수하면 엉뚱한
204
+ // 홀더의 DOM/doc 차이를 커밋해 원격 편집 등의 정상 텍스트를
205
+ // 되돌릴 수 있다
206
+ if (!composing || pendingAbsorb)
207
+ return;
142
208
  // composing 해제와 흡수를 다음 태스크로 미룬다 — 같은 태스크의
143
209
  // 후속 beforeinput/keydown(Safari 최종 커밋, IME Enter 오커밋)을
144
210
  // composing 가드가 계속 걸러내게 하기 위해서다. 단 그 창에 도착한
145
211
  // 구조 입력은 flushComposition이 흡수를 앞당겨 정상 처리한다.
146
212
  pendingAbsorb = true;
147
213
  compEndedAt = performance.now();
214
+ compEndData = e?.data ?? null;
148
215
  compTimer = setTimeout(flushComposition, 0);
149
216
  },
150
217
  gate(e, domSel) {
@@ -164,10 +231,13 @@ export function createImeSession(host) {
164
231
  }
165
232
  // 커밋 에코 — DOM에 이미 같은 텍스트가 쓰여 있으면(조합 중 브라우저가
166
233
  // 넣은 상태) 통과시키면 브라우저가 한 번 더 써서 "세세"가 된다.
167
- // DOM에 없으면(Safari 최종 커밋) 살려둬야 글자가 사라지지 않는다
234
+ // DOM에 없으면(Safari 최종 커밋) 살려둬야 글자가 사라지지 않는다.
235
+ // 페이로드가 읽힐 때는 커밋 문자열과도 일치해야 한다 — DOM 끝자락
236
+ // 일치만으로는 커밋 직후 같은 문자의 실제 재입력까지 막는다
168
237
  if ((e.inputType === "insertText" ||
169
238
  e.inputType === "insertCompositionText") &&
170
239
  e.data &&
240
+ (compEndData == null || e.data === compEndData) &&
171
241
  domSel &&
172
242
  domEndsWith(el, domSel.focus, e.data)) {
173
243
  return "prevent";
@@ -176,9 +246,12 @@ export function createImeSession(host) {
176
246
  },
177
247
  isLateEcho(data, domSel) {
178
248
  // 커밋 에코가 흡수 타이머보다 늦게 도착한 경우 — DOM과 doc에
179
- // 이미 같은 글자가 있으므로 다시 넣으면 "세세"가 된다
249
+ // 이미 같은 글자가 있으므로 다시 넣으면 "세세"가 된다.
250
+ // 커밋 페이로드와의 일치를 요구해, 커밋 직후 같은 문자를 빠르게
251
+ // 재입력한 실제 키입력이 에코로 삼켜지는 것을 막는다
180
252
  return (compEndedAt > 0 &&
181
253
  performance.now() - compEndedAt < 300 &&
254
+ (compEndData == null || data === compEndData) &&
182
255
  domSel != null &&
183
256
  domEndsWith(el, domSel.focus, data));
184
257
  },
@@ -1 +1 @@
1
- {"version":3,"file":"ime.js","sourceRoot":"","sources":["../../src/view/ime.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ime.js","sourceRoot":"","sources":["../../src/view/ime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Editor } from "../editor/editor.js";
2
+ import type { Point } from "../state/selection.js";
3
+ import type { ImeSession } from "./ime.js";
4
+ /**
5
+ * beforeinput 핸들러 — 브라우저가 contenteditable DOM을 직접 바꾸는
6
+ * 것을 막고(preventDefault) 모든 입력을 트랜잭션으로 번역한다.
7
+ *
8
+ * bindEditorInput에서 분리된 모듈 — inputType별 디스패치(텍스트 삽입·
9
+ * 개행·삭제·붙여넣기·드롭·서식 커맨드)만 담는다. IME 게이트 판정과
10
+ * 입력 훅 소비가 먼저 돌고, 남은 입력은 tr.delete+insert로 처리한다.
11
+ */
12
+ export interface BeforeInputDeps {
13
+ editor: Editor;
14
+ el: HTMLElement;
15
+ /** DOM 셀렉션을 Point로 읽는 판독기 */
16
+ readDomSel: () => {
17
+ anchor: Point;
18
+ focus: Point;
19
+ } | null;
20
+ /** IME 세션 — gate/isLateEcho 판정에 쓴다 */
21
+ ime: ImeSession;
22
+ }
23
+ /** beforeinput 리스너를 생성한다 */
24
+ export declare function createBeforeInputHandler(deps: BeforeInputDeps): (e: InputEvent) => void;
25
+ //# sourceMappingURL=input-beforeinput.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-beforeinput.d.ts","sourceRoot":"","sources":["../../src/view/input-beforeinput.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAKlD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAInD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAK3C;;;;;;;GAOG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,WAAW,CAAC;IAChB,6BAA6B;IAC7B,UAAU,EAAE,MAAM;QAAE,MAAM,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,KAAK,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,sCAAsC;IACtC,GAAG,EAAE,UAAU,CAAC;CACjB;AAED,4BAA4B;AAC5B,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,eAAe,GACpB,CAAC,CAAC,EAAE,UAAU,KAAK,IAAI,CA6TzB"}
@@ -0,0 +1,330 @@
1
+ import { nodeAt } from "../model/traverse.js";
2
+ import { parseHTML } from "../parse/html.js";
3
+ import { pointBefore, pointAfter } from "../state/navigate.js";
4
+ import { normalizeRange, pointEq } from "../state/selection.js";
5
+ import { isLeafPoint } from "./caret.js";
6
+ import { domToPoint } from "./dom.js";
7
+ import { blockCtx, rangeCtx } from "./hook-ctx.js";
8
+ import { nodeSelectionBeforeInput } from "./node-selection.js";
9
+ import { blockHasContent, pointBlockPath } from "../commands.js";
10
+ import { dispatchFormatInput } from "./keys.js";
11
+ /** beforeinput 리스너를 생성한다 */
12
+ export function createBeforeInputHandler(deps) {
13
+ const { editor, el, readDomSel, ime } = deps;
14
+ return (e) => {
15
+ if (!editor.editable || e.isComposing)
16
+ return;
17
+ // DOM 셀렉션을 흡수 플러시 전에 읽어둔다 — 커밋 끝점 좌표라
18
+ // 흡수된 텍스트를 포함해 정확하고, 플러시의 리렌더가 DOM
19
+ // 셀렉션을 doc(조합 시작점)으로 되돌리기 전의 값이다
20
+ const domSel = readDomSel();
21
+ // 조합 세션 게이트 — swallow(조합 중 무시)/prevent(커밋 에코 차단)/
22
+ // proceed(정상 처리 — 흡수 대기 중의 구조 입력은 플러시 후 통과)
23
+ const gated = ime.gate(e, domSel);
24
+ if (gated === "swallow")
25
+ return;
26
+ if (gated === "prevent") {
27
+ e.preventDefault();
28
+ return;
29
+ }
30
+ const ds = editor.state.selection;
31
+ // 노드 셀렉션 — DOM 캐럿은 클릭 전 위치에 멈춰 있어 신뢰 불가.
32
+ // 삭제는 노드를 통째로 지우고, 텍스트/개행 입력은 노드 뒤 블록
33
+ // 경계에서 일어나는 것으로 처리한다 (노드는 유지)
34
+ if (ds.type === "node") {
35
+ e.preventDefault();
36
+ nodeSelectionBeforeInput(editor, e);
37
+ return;
38
+ }
39
+ // DOM 셀렉션이 무효하면(리렌더로 분리된 노드 위 등) doc 셀렉션으로
40
+ // 폴백 — 여기까지 왔으면 doc 셀렉션은 항상 텍스트다
41
+ const sel = domSel ?? { anchor: ds.anchor, focus: ds.focus };
42
+ const tr = editor.state.tr();
43
+ switch (e.inputType) {
44
+ case "insertText":
45
+ case "insertCompositionText": {
46
+ e.preventDefault();
47
+ const data = e.data ?? "";
48
+ if (!data)
49
+ return;
50
+ // 커밋 에코가 흡수 타이머보다 늦게 도착한 경우 — DOM과 doc에
51
+ // 이미 같은 글자가 있으므로 다시 넣으면 "세세"가 된다
52
+ if (ime.isLateEcho(data, domSel))
53
+ return;
54
+ // 범위 삭제 뒤엔 삭제 전 좌표가 무효 — 정규화한 앞점 기준으로 삽입
55
+ const r = normalizeRange(sel);
56
+ // 입력 훅 — 기능이 글자 가로채기(코드블록 자동 쌍·타입오버 등)를
57
+ // 구현한다. true 반환 = 소비 → 기본 삽입/입력 규칙을 건너뛴다
58
+ let consumed = false;
59
+ if (editor.inputHooks.length) {
60
+ const ctx = blockCtx(editor, r, tr);
61
+ if (ctx) {
62
+ for (const h of editor.inputHooks) {
63
+ if (h.insertText?.(ctx, data, e.inputType)) {
64
+ consumed = true;
65
+ break;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ if (!consumed) {
71
+ if (!pointEq(r.anchor, r.focus))
72
+ tr.delete(r);
73
+ tr.insertText(data, r.anchor).setMeta("history.group", "type");
74
+ // 마크다운 입력 규칙 — 삽입+변환이 같은 tr이라 하나의 undo 단위
75
+ tr.applyInputRules(editor.inputRules);
76
+ editor.dispatch(tr);
77
+ }
78
+ break;
79
+ }
80
+ case "insertParagraph":
81
+ case "insertLineBreak": {
82
+ e.preventDefault();
83
+ const r = normalizeRange(sel);
84
+ // 분기 판단은 삭제 전 문서의 캐럿 블록 기준 — 경계 포인트
85
+ // (빈 블록의 {path:블록,offset:0} 관례)도 안쪽 블록으로 내려
86
+ // 해석해야 빈 리스트 아이템의 Enter가 lift로 잡힌다
87
+ const blockPath = pointBlockPath(editor.state.doc, editor.state.schema, r.anchor);
88
+ const parentPath = blockPath?.slice(0, -1);
89
+ const parent = parentPath?.length
90
+ ? nodeAt(editor.state.doc, parentPath)
91
+ : undefined;
92
+ const pspec = parent
93
+ ? editor.state.schema.nodeSpec(parent.type)
94
+ : undefined;
95
+ if (!pointEq(r.anchor, r.focus)) {
96
+ tr.delete(r);
97
+ // 삭제 후에는 tr.selection(삭제 붕괴점) 기준 — 삭제 전 좌표는 무효
98
+ tr.split();
99
+ editor.dispatch(tr);
100
+ }
101
+ else {
102
+ // 입력 훅 — 기능이 개행 가로채기(코드블록 자동 들여쓰기·
103
+ // 블록 탈출 등)를 구현한다. true 반환 = 소비
104
+ let consumed = false;
105
+ if (editor.inputHooks.length) {
106
+ const ctx = blockCtx(editor, r, tr);
107
+ if (ctx) {
108
+ for (const h of editor.inputHooks) {
109
+ if (h.insertParagraph?.(ctx)) {
110
+ consumed = true;
111
+ break;
112
+ }
113
+ }
114
+ }
115
+ }
116
+ if (!consumed) {
117
+ if (parentPath && pspec?.listItem) {
118
+ // 리스트 아이템 — 빈 아이템이면 리스트 탈출, 아니면 아이템 분할.
119
+ // 텍스트 길이만 보면 멘션·hardBreak만 담은 아이템이
120
+ // "비었다"로 오판돼 Enter에 내용이 통째로 리프트된다
121
+ const kids = parent.content ?? [];
122
+ const empty = kids.length === 1 &&
123
+ !blockHasContent(editor.state.schema, kids[0]);
124
+ if (empty) {
125
+ tr.liftItem(parentPath);
126
+ }
127
+ else {
128
+ tr.splitItem(parentPath, r.anchor);
129
+ }
130
+ }
131
+ else {
132
+ tr.split(r.anchor);
133
+ }
134
+ editor.dispatch(tr);
135
+ }
136
+ }
137
+ break;
138
+ }
139
+ case "deleteContentBackward":
140
+ case "deleteContentForward": {
141
+ e.preventDefault();
142
+ if (!pointEq(sel.anchor, sel.focus)) {
143
+ tr.delete(sel);
144
+ }
145
+ else {
146
+ // 입력 훅 — collapsed Backspace 가로채기 (코드블록 쌍 삭제 등).
147
+ // true 반환 = 소비 → 아래 기본 삭제 경로를 건너뛴다
148
+ let consumed = false;
149
+ if (e.inputType === "deleteContentBackward" &&
150
+ editor.inputHooks.length) {
151
+ const ctx = blockCtx(editor, { anchor: sel.anchor, focus: sel.focus }, tr);
152
+ if (ctx) {
153
+ for (const h of editor.inputHooks) {
154
+ if (h.deleteBackward?.(ctx)) {
155
+ consumed = true;
156
+ break;
157
+ }
158
+ }
159
+ }
160
+ }
161
+ if (consumed)
162
+ break;
163
+ // 브라우저가 계산한 실제 삭제 범위 — 이모지(서로게이트
164
+ // 페어)·결합문자·ZWJ 클러스터는 코드 유닛 하나만 지우면
165
+ // 깨지므로 targetRange를 우선 쓴다. 단, 방향에 맞는 끝점이
166
+ // 캐럿이어야 신뢰한다 — Chrome은 블록 경계 Backspace에
167
+ // 캐럿 "뒤" 글자 범위를 반환하는 버그가 있어 그대로 지우면
168
+ // 머지 대신 다음 글자가 날아간다
169
+ const tr0 = e.getTargetRanges?.()[0];
170
+ const ta = tr0 && domToPoint(el, tr0.startContainer, tr0.startOffset);
171
+ const tf = tr0 && domToPoint(el, tr0.endContainer, tr0.endOffset);
172
+ const backward = e.inputType === "deleteContentBackward";
173
+ const onCaret = backward
174
+ ? tf && pointEq(tf, sel.focus)
175
+ : ta && pointEq(ta, sel.focus);
176
+ // 끝점이 요소 레벨 포인트(컨테이너 자식 경계, 블록 머지 시 Chrome이
177
+ // (P,0) 같은 위치를 줌)면 tr.delete가 해석하지 못한다 — 리프
178
+ // 포인트를 주는 pointBefore/After 폴백으로 돌린다
179
+ if (ta &&
180
+ tf &&
181
+ !pointEq(ta, tf) &&
182
+ onCaret &&
183
+ isLeafPoint(editor.state.doc, ta) &&
184
+ isLeafPoint(editor.state.doc, tf)) {
185
+ tr.delete(normalizeRange({ anchor: ta, focus: tf }));
186
+ tr.setMeta("history.group", "delete");
187
+ editor.dispatch(tr);
188
+ break;
189
+ }
190
+ const boundary = e.inputType === "deleteContentBackward"
191
+ ? pointBefore(editor.state.doc, sel.focus)
192
+ : pointAfter(editor.state.doc, sel.focus);
193
+ if (!boundary)
194
+ return;
195
+ tr.delete(e.inputType === "deleteContentBackward"
196
+ ? { anchor: boundary, focus: sel.focus }
197
+ : { anchor: sel.focus, focus: boundary });
198
+ }
199
+ tr.setMeta("history.group", "delete");
200
+ editor.dispatch(tr);
201
+ break;
202
+ }
203
+ case "insertFromPaste": {
204
+ e.preventDefault();
205
+ const html = e.dataTransfer?.getData("text/html");
206
+ const text = e.dataTransfer?.getData("text/plain") ?? "";
207
+ const r = normalizeRange(sel);
208
+ // 기능 훅 — 링크 URL 감싸기·코드블록 순수 텍스트 등.
209
+ // 하나라도 소비하면 기본 경로를 건너뛴다
210
+ const ctx = rangeCtx(editor, r, tr);
211
+ const data = { html, text };
212
+ let consumed = false;
213
+ for (const h of editor.inputHooks) {
214
+ if (h.insertFromPaste?.(ctx, data)) {
215
+ consumed = true;
216
+ break;
217
+ }
218
+ }
219
+ if (consumed)
220
+ break;
221
+ if (!pointEq(r.anchor, r.focus))
222
+ tr.delete(r);
223
+ if (html) {
224
+ const nodes = parseHTML(html, editor.state.schema);
225
+ if (nodes.length) {
226
+ tr.insertSlice(r.anchor, nodes).setMeta("paste", true);
227
+ editor.dispatch(tr);
228
+ break;
229
+ }
230
+ }
231
+ if (!text)
232
+ return;
233
+ tr.insertText(text, r.anchor).setMeta("paste", true);
234
+ editor.dispatch(tr);
235
+ break;
236
+ }
237
+ case "insertFromDrop":
238
+ case "insertReplacementText": {
239
+ // 텍스트 드롭·자동고침 — 핸들러가 없으면 브라우저가 DOM을 직접
240
+ // 바꿔 doc과 어긋난다. 이미지 파일 드롭은 onDrop이 먼저 잡는다
241
+ e.preventDefault();
242
+ const data = e.data ?? e.dataTransfer?.getData("text/plain") ?? "";
243
+ // insertReplacementText는 교체 대상 범위를 준다 (자동고침)
244
+ let r = normalizeRange(sel);
245
+ if (e.inputType === "insertReplacementText") {
246
+ const tr0 = e.getTargetRanges?.()[0];
247
+ const a = tr0 && domToPoint(el, tr0.startContainer, tr0.startOffset);
248
+ const f = tr0 && domToPoint(el, tr0.endContainer, tr0.endOffset);
249
+ if (a && f)
250
+ r = normalizeRange({ anchor: a, focus: f });
251
+ }
252
+ if (!pointEq(r.anchor, r.focus))
253
+ tr.delete(r);
254
+ if (data) {
255
+ tr.insertText(data, r.anchor).setMeta("history.group", "type");
256
+ }
257
+ editor.dispatch(tr);
258
+ break;
259
+ }
260
+ // 단어/줄 단위·드래그·잘라내기 삭제 — macOS Option-Delete는
261
+ // deleteWord*, Ctrl-K는 deleteSoftLine*, Cmd-X는 deleteByCut으로
262
+ // 온다. getTargetRanges가 브라우저가 계산한 정확한 범위를 주므로
263
+ // 그것을 쓰고, 없으면 현재 선택을 지운다. 잘라내기의 클립보드
264
+ // 쓰기는 cut 이벤트의 디폴트라 beforeinput을 막아도 채워진다
265
+ case "deleteWordBackward":
266
+ case "deleteWordForward":
267
+ case "deleteSoftLineBackward":
268
+ case "deleteSoftLineForward":
269
+ case "deleteEntireSoftLine":
270
+ case "deleteHardLineBackward":
271
+ case "deleteHardLineForward":
272
+ case "deleteByDrag":
273
+ case "deleteByCut": {
274
+ e.preventDefault();
275
+ const tr0 = e.getTargetRanges?.()[0];
276
+ const a = tr0 && domToPoint(el, tr0.startContainer, tr0.startOffset);
277
+ const f = tr0 && domToPoint(el, tr0.endContainer, tr0.endOffset);
278
+ // 캐럿 끝점이 삭제 방향과 맞을 때만 목표 범위를 신뢰한다 —
279
+ // 블록 경계에서 Chrome이 반대 방향 범위를 주는 버그가 있다.
280
+ // 방향 없는 타입(drag/cut/entire)은 항상 신뢰한다. 끝점이 요소
281
+ // 레벨 포인트면 tr.delete가 해석 못하므로 리프만 받는다
282
+ const delBack = e.inputType.endsWith("Backward");
283
+ const delFwd = e.inputType.endsWith("Forward");
284
+ const trusted = a &&
285
+ f &&
286
+ !pointEq(a, f) &&
287
+ isLeafPoint(editor.state.doc, a) &&
288
+ isLeafPoint(editor.state.doc, f) &&
289
+ (!delBack || pointEq(f, sel.focus)) &&
290
+ (!delFwd || pointEq(a, sel.focus));
291
+ const r = trusted
292
+ ? normalizeRange({ anchor: a, focus: f })
293
+ : normalizeRange(sel);
294
+ tr.delete(r).setMeta("history.group", "delete");
295
+ editor.dispatch(tr);
296
+ break;
297
+ }
298
+ // 모바일·컨텍스트 메뉴·리더의 서식 명령 — 네이티브 execCommand가
299
+ // DOM을 직접 바꾸면 어긋나므로 우리 커맨드로 매핑한다
300
+ // (매핑 테이블은 keys.ts의 dispatchFormatInput)
301
+ case "insertFromYank":
302
+ case "insertFromPasteAsQuotation": {
303
+ // macOS 킬링 붙여넣기(Ctrl-Y)·인용 붙여넣기 — 있으면 순수
304
+ // 텍스트로 삽입한다
305
+ e.preventDefault();
306
+ const data = e.data ?? e.dataTransfer?.getData("text/plain") ?? "";
307
+ if (!data)
308
+ return;
309
+ const r = normalizeRange(sel);
310
+ if (!pointEq(r.anchor, r.focus))
311
+ tr.delete(r);
312
+ tr.insertText(data, r.anchor).setMeta("history.group", "type");
313
+ editor.dispatch(tr);
314
+ break;
315
+ }
316
+ default:
317
+ // format*/history*/insert*List 등 — 커맨드 디스패치 테이블에 위임
318
+ if (dispatchFormatInput(editor, e.inputType)) {
319
+ e.preventDefault();
320
+ break;
321
+ }
322
+ // 나머지 타입(insertTranspose, formatFontColor 등)은 우리가
323
+ // 처리하지 않는다 — 그대로 두면 브라우저가 DOM만 바꿔 doc과
324
+ // 영구히 어긋나므로 기본 동작을 막아 no-op으로 둔다
325
+ e.preventDefault();
326
+ break;
327
+ }
328
+ };
329
+ }
330
+ //# sourceMappingURL=input-beforeinput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-beforeinput.js","sourceRoot":"","sources":["../../src/view/input-beforeinput.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Editor } from "../editor/editor.js";
2
+ import type { ImeSession } from "./ime.js";
3
+ /**
4
+ * keydown 핸들러 — 키맵 디스패치·Mod-A 전체 선택·노드 셀렉션 키
5
+ * 처리·줄 경계 내비게이션.
6
+ *
7
+ * bindEditorInput에서 분리된 모듈 — 키 입력을 트랜잭션 커맨드로
8
+ * 번역하는 경로만 담는다. beforeinput이 실제 편집을 처리하므로
9
+ * 여기선 "명령" 성격의 키만 다룬다.
10
+ */
11
+ export interface KeydownDeps {
12
+ editor: Editor;
13
+ el: HTMLElement;
14
+ /** IME 세션 — 조합 중 키는 모두 무시한다 */
15
+ ime: ImeSession;
16
+ /**
17
+ * DOM 셀렉션을 doc에 즉시 흡수하는 동기화 — 클릭 직후 키 입력처럼
18
+ * selectionchange가 아직 도착하지 않은 창에 doc 셀렉션이 stale하다.
19
+ * PM domObserver.flush 관례로 키 처리 전에 먼저 호출한다.
20
+ */
21
+ syncDocSelection: () => void;
22
+ }
23
+ /** keydown 리스너를 생성한다 */
24
+ export declare function createKeydownHandler(deps: KeydownDeps): (e: KeyboardEvent) => void;
25
+ //# sourceMappingURL=input-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-keys.d.ts","sourceRoot":"","sources":["../../src/view/input-keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAKlD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C;;;;;;;GAOG;AAEH,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,WAAW,CAAC;IAChB,+BAA+B;IAC/B,GAAG,EAAE,UAAU,CAAC;IAChB;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAwB;AACxB,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,WAAW,GAChB,CAAC,CAAC,EAAE,aAAa,KAAK,IAAI,CAuE5B"}