@moda-editor/core 0.1.3 → 0.2.0

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 (252) hide show
  1. package/dist/collab.d.ts +61 -0
  2. package/dist/collab.d.ts.map +1 -0
  3. package/dist/collab.js +67 -0
  4. package/dist/collab.js.map +1 -0
  5. package/dist/commands.d.ts +11 -0
  6. package/dist/commands.d.ts.map +1 -1
  7. package/dist/commands.js +48 -4
  8. package/dist/commands.js.map +1 -1
  9. package/dist/conformance/editor-base.d.ts +7 -0
  10. package/dist/conformance/editor-base.d.ts.map +1 -0
  11. package/dist/conformance/editor-base.js +304 -0
  12. package/dist/conformance/editor-base.js.map +1 -0
  13. package/dist/conformance/editor-codeblock.d.ts +8 -0
  14. package/dist/conformance/editor-codeblock.d.ts.map +1 -0
  15. package/dist/conformance/editor-codeblock.js +402 -0
  16. package/dist/conformance/editor-codeblock.js.map +1 -0
  17. package/dist/conformance/editor-ime.d.ts +7 -0
  18. package/dist/conformance/editor-ime.d.ts.map +1 -0
  19. package/dist/conformance/editor-ime.js +166 -0
  20. package/dist/conformance/editor-ime.js.map +1 -0
  21. package/dist/conformance/editor-input.d.ts +8 -0
  22. package/dist/conformance/editor-input.d.ts.map +1 -0
  23. package/dist/conformance/editor-input.js +676 -0
  24. package/dist/conformance/editor-input.js.map +1 -0
  25. package/dist/conformance/editor-nodeview.d.ts +7 -0
  26. package/dist/conformance/editor-nodeview.d.ts.map +1 -0
  27. package/dist/conformance/editor-nodeview.js +169 -0
  28. package/dist/conformance/editor-nodeview.js.map +1 -0
  29. package/dist/conformance/editor-overlay.d.ts +8 -0
  30. package/dist/conformance/editor-overlay.d.ts.map +1 -0
  31. package/dist/conformance/editor-overlay.js +345 -0
  32. package/dist/conformance/editor-overlay.js.map +1 -0
  33. package/dist/conformance/fixtures.d.ts +4 -0
  34. package/dist/conformance/fixtures.d.ts.map +1 -0
  35. package/dist/conformance/fixtures.js +15 -0
  36. package/dist/conformance/fixtures.js.map +1 -0
  37. package/dist/conformance/index.d.ts +14 -0
  38. package/dist/conformance/index.d.ts.map +1 -0
  39. package/dist/conformance/index.js +28 -0
  40. package/dist/conformance/index.js.map +1 -0
  41. package/dist/conformance/types.d.ts +51 -0
  42. package/dist/conformance/types.d.ts.map +1 -0
  43. package/dist/conformance/types.js +2 -0
  44. package/dist/conformance/types.js.map +1 -0
  45. package/dist/conformance/widget.d.ts +3 -0
  46. package/dist/conformance/widget.d.ts.map +1 -0
  47. package/dist/conformance/widget.js +49 -0
  48. package/dist/conformance/widget.js.map +1 -0
  49. package/dist/conformance.d.ts +1 -58
  50. package/dist/conformance.d.ts.map +1 -1
  51. package/dist/conformance.js +3 -1748
  52. package/dist/conformance.js.map +1 -1
  53. package/dist/editor/editor.d.ts.map +1 -1
  54. package/dist/editor/editor.js +18 -1
  55. package/dist/editor/editor.js.map +1 -1
  56. package/dist/editor/extension.d.ts +47 -3
  57. package/dist/editor/extension.d.ts.map +1 -1
  58. package/dist/features/ace.d.ts +4 -0
  59. package/dist/features/ace.d.ts.map +1 -1
  60. package/dist/features/ace.js +59 -20
  61. package/dist/features/ace.js.map +1 -1
  62. package/dist/features/block-dnd.d.ts +7 -0
  63. package/dist/features/block-dnd.d.ts.map +1 -0
  64. package/dist/features/block-dnd.js +207 -0
  65. package/dist/features/block-dnd.js.map +1 -0
  66. package/dist/features/code-block.d.ts +9 -84
  67. package/dist/features/code-block.d.ts.map +1 -1
  68. package/dist/features/code-block.js +84 -1034
  69. package/dist/features/code-block.js.map +1 -1
  70. package/dist/features/code-context.d.ts +81 -0
  71. package/dist/features/code-context.d.ts.map +1 -0
  72. package/dist/features/code-context.js +322 -0
  73. package/dist/features/code-context.js.map +1 -0
  74. package/dist/features/code-edit.d.ts +50 -0
  75. package/dist/features/code-edit.d.ts.map +1 -0
  76. package/dist/features/code-edit.js +412 -0
  77. package/dist/features/code-edit.js.map +1 -0
  78. package/dist/features/code-format.d.ts +21 -0
  79. package/dist/features/code-format.d.ts.map +1 -0
  80. package/dist/features/code-format.js +410 -0
  81. package/dist/features/code-format.js.map +1 -0
  82. package/dist/features/doc.d.ts +16 -0
  83. package/dist/features/doc.d.ts.map +1 -1
  84. package/dist/features/doc.js +154 -2
  85. package/dist/features/doc.js.map +1 -1
  86. package/dist/features/heading.d.ts.map +1 -1
  87. package/dist/features/heading.js.map +1 -1
  88. package/dist/features/image.d.ts +3 -1
  89. package/dist/features/image.d.ts.map +1 -1
  90. package/dist/features/image.js +27 -9
  91. package/dist/features/image.js.map +1 -1
  92. package/dist/features/index.d.ts +7 -0
  93. package/dist/features/index.d.ts.map +1 -1
  94. package/dist/features/index.js +16 -0
  95. package/dist/features/index.js.map +1 -1
  96. package/dist/features/inline-style.d.ts.map +1 -1
  97. package/dist/features/inline-style.js +4 -1
  98. package/dist/features/inline-style.js.map +1 -1
  99. package/dist/features/link.d.ts.map +1 -1
  100. package/dist/features/link.js +1 -1
  101. package/dist/features/link.js.map +1 -1
  102. package/dist/features/markdown.d.ts +15 -0
  103. package/dist/features/markdown.d.ts.map +1 -0
  104. package/dist/features/markdown.js +80 -0
  105. package/dist/features/markdown.js.map +1 -0
  106. package/dist/features/marks.d.ts.map +1 -1
  107. package/dist/features/marks.js +49 -4
  108. package/dist/features/marks.js.map +1 -1
  109. package/dist/features/mention.d.ts +30 -0
  110. package/dist/features/mention.d.ts.map +1 -0
  111. package/dist/features/mention.js +89 -0
  112. package/dist/features/mention.js.map +1 -0
  113. package/dist/features/script.d.ts.map +1 -1
  114. package/dist/features/script.js.map +1 -1
  115. package/dist/features/search.d.ts +76 -0
  116. package/dist/features/search.d.ts.map +1 -0
  117. package/dist/features/search.js +281 -0
  118. package/dist/features/search.js.map +1 -0
  119. package/dist/features/shared.d.ts +69 -0
  120. package/dist/features/shared.d.ts.map +1 -0
  121. package/dist/features/shared.js +272 -0
  122. package/dist/features/shared.js.map +1 -0
  123. package/dist/features/table.d.ts.map +1 -1
  124. package/dist/features/table.js +17 -3
  125. package/dist/features/table.js.map +1 -1
  126. package/dist/features/testkit.d.ts.map +1 -1
  127. package/dist/features/testkit.js +1 -1
  128. package/dist/features/testkit.js.map +1 -1
  129. package/dist/history.d.ts.map +1 -1
  130. package/dist/history.js +65 -20
  131. package/dist/history.js.map +1 -1
  132. package/dist/index.d.ts +21 -7
  133. package/dist/index.d.ts.map +1 -1
  134. package/dist/index.js +18 -6
  135. package/dist/index.js.map +1 -1
  136. package/dist/model/schema.d.ts.map +1 -1
  137. package/dist/model/schema.js +2 -1
  138. package/dist/model/schema.js.map +1 -1
  139. package/dist/parse/html.d.ts.map +1 -1
  140. package/dist/parse/html.js +38 -6
  141. package/dist/parse/html.js.map +1 -1
  142. package/dist/parse/sanitize.d.ts.map +1 -1
  143. package/dist/parse/sanitize.js +4 -1
  144. package/dist/parse/sanitize.js.map +1 -1
  145. package/dist/presets/highlight.d.ts.map +1 -1
  146. package/dist/presets/highlight.js +1 -4
  147. package/dist/presets/highlight.js.map +1 -1
  148. package/dist/presets/markdown-parse.d.ts +13 -0
  149. package/dist/presets/markdown-parse.d.ts.map +1 -0
  150. package/dist/presets/markdown-parse.js +398 -0
  151. package/dist/presets/markdown-parse.js.map +1 -0
  152. package/dist/presets/markdown.d.ts +46 -0
  153. package/dist/presets/markdown.d.ts.map +1 -0
  154. package/dist/presets/markdown.js +196 -0
  155. package/dist/presets/markdown.js.map +1 -0
  156. package/dist/state/apply.d.ts.map +1 -1
  157. package/dist/state/apply.js +25 -13
  158. package/dist/state/apply.js.map +1 -1
  159. package/dist/state/delete-ops.d.ts +34 -0
  160. package/dist/state/delete-ops.d.ts.map +1 -0
  161. package/dist/state/delete-ops.js +204 -0
  162. package/dist/state/delete-ops.js.map +1 -0
  163. package/dist/state/input-rules.d.ts +30 -0
  164. package/dist/state/input-rules.d.ts.map +1 -0
  165. package/dist/state/input-rules.js +70 -0
  166. package/dist/state/input-rules.js.map +1 -0
  167. package/dist/state/insert-ops.d.ts +54 -0
  168. package/dist/state/insert-ops.d.ts.map +1 -0
  169. package/dist/state/insert-ops.js +186 -0
  170. package/dist/state/insert-ops.js.map +1 -0
  171. package/dist/state/list-ops.d.ts +46 -0
  172. package/dist/state/list-ops.d.ts.map +1 -0
  173. package/dist/state/list-ops.js +231 -0
  174. package/dist/state/list-ops.js.map +1 -0
  175. package/dist/state/navigate.d.ts.map +1 -1
  176. package/dist/state/navigate.js +3 -1
  177. package/dist/state/navigate.js.map +1 -1
  178. package/dist/state/resolve-insert.d.ts +55 -0
  179. package/dist/state/resolve-insert.d.ts.map +1 -0
  180. package/dist/state/resolve-insert.js +118 -0
  181. package/dist/state/resolve-insert.js.map +1 -0
  182. package/dist/state/slice-ops.d.ts +46 -0
  183. package/dist/state/slice-ops.d.ts.map +1 -0
  184. package/dist/state/slice-ops.js +150 -0
  185. package/dist/state/slice-ops.js.map +1 -0
  186. package/dist/state/state.d.ts +6 -1
  187. package/dist/state/state.d.ts.map +1 -1
  188. package/dist/state/state.js +10 -0
  189. package/dist/state/state.js.map +1 -1
  190. package/dist/state/transaction.d.ts +43 -49
  191. package/dist/state/transaction.d.ts.map +1 -1
  192. package/dist/state/transaction.js +62 -858
  193. package/dist/state/transaction.js.map +1 -1
  194. package/dist/styles.css +401 -213
  195. package/dist/theme.d.ts +29 -0
  196. package/dist/theme.d.ts.map +1 -0
  197. package/dist/theme.js +347 -0
  198. package/dist/theme.js.map +1 -0
  199. package/dist/view/adapter.d.ts +84 -0
  200. package/dist/view/adapter.d.ts.map +1 -0
  201. package/dist/view/adapter.js +76 -0
  202. package/dist/view/adapter.js.map +1 -0
  203. package/dist/view/caret.d.ts +25 -0
  204. package/dist/view/caret.d.ts.map +1 -0
  205. package/dist/view/caret.js +43 -0
  206. package/dist/view/caret.js.map +1 -0
  207. package/dist/view/decoration.d.ts +9 -0
  208. package/dist/view/decoration.d.ts.map +1 -0
  209. package/dist/view/decoration.js +214 -0
  210. package/dist/view/decoration.js.map +1 -0
  211. package/dist/view/dirty-keys.d.ts +18 -0
  212. package/dist/view/dirty-keys.d.ts.map +1 -0
  213. package/dist/view/dirty-keys.js +31 -0
  214. package/dist/view/dirty-keys.js.map +1 -0
  215. package/dist/view/dom.d.ts.map +1 -1
  216. package/dist/view/dom.js +7 -5
  217. package/dist/view/dom.js.map +1 -1
  218. package/dist/view/hook-ctx.d.ts +32 -0
  219. package/dist/view/hook-ctx.d.ts.map +1 -0
  220. package/dist/view/hook-ctx.js +64 -0
  221. package/dist/view/hook-ctx.js.map +1 -0
  222. package/dist/view/ime.d.ts +72 -0
  223. package/dist/view/ime.d.ts.map +1 -0
  224. package/dist/view/ime.js +185 -0
  225. package/dist/view/ime.js.map +1 -0
  226. package/dist/view/input.d.ts +12 -12
  227. package/dist/view/input.d.ts.map +1 -1
  228. package/dist/view/input.js +156 -535
  229. package/dist/view/input.js.map +1 -1
  230. package/dist/view/keys.d.ts +25 -0
  231. package/dist/view/keys.d.ts.map +1 -0
  232. package/dist/view/keys.js +106 -0
  233. package/dist/view/keys.js.map +1 -0
  234. package/dist/view/line-nav.d.ts +13 -0
  235. package/dist/view/line-nav.d.ts.map +1 -0
  236. package/dist/view/line-nav.js +114 -0
  237. package/dist/view/line-nav.js.map +1 -0
  238. package/dist/view/mount.d.ts.map +1 -1
  239. package/dist/view/mount.js +43 -39
  240. package/dist/view/mount.js.map +1 -1
  241. package/dist/view/node-selection.d.ts +33 -0
  242. package/dist/view/node-selection.d.ts.map +1 -0
  243. package/dist/view/node-selection.js +107 -0
  244. package/dist/view/node-selection.js.map +1 -0
  245. package/dist/view/render.d.ts +4 -1
  246. package/dist/view/render.d.ts.map +1 -1
  247. package/dist/view/render.js +22 -3
  248. package/dist/view/render.js.map +1 -1
  249. package/dist/view/serialize.d.ts.map +1 -1
  250. package/dist/view/serialize.js +14 -5
  251. package/dist/view/serialize.js.map +1 -1
  252. package/package.json +1 -1
@@ -0,0 +1,185 @@
1
+ import { nodeAt } from "../model/traverse.js";
2
+ import { pathEq } from "../state/apply.js";
3
+ import { point, textSelection } from "../state/selection.js";
4
+ import { domEndsWith, topBlockKey } from "./caret.js";
5
+ import { PATH_ATTR } from "./dom.js";
6
+ /**
7
+ * IME 세션을 생성한다 — 한 contenteditable 바인딩당 하나.
8
+ * 모든 상태는 클로저에 갇히고 호스트가 준 인터페이스로만
9
+ * DOM·에디터에 닿는다.
10
+ */
11
+ export function createImeSession(host) {
12
+ const { editor, el, dirtyPaths, readDomSel } = host;
13
+ let composing = false;
14
+ // 조합이 시작된 리프 포인트 — 흡수가 DOM 셀렉션을 못 읽을 때의 폴백
15
+ let compStart = null;
16
+ // compositionend → flush 예약 타이머
17
+ let compTimer = null;
18
+ // compositionend가 왔고 흡수만 남은 상태 — 이 창에 도착하는 구조
19
+ // 입력(Enter/Backspace)은 커밋이 끝난 뒤의 것이라 브라우저에 맡기면
20
+ // 네이티브 split/delete가 doc 밖 DOM을 만든다
21
+ let pendingAbsorb = false;
22
+ // 실제 IME는 compositionend 뒤 같은 텍스트의 최종 커밋 beforeinput을
23
+ // 한 번 더 보낸다(Safari 확정, Chromium도 비동기 커밋 경로가 있다) —
24
+ // 타이머보다 늦게 오면 에코를 구별하기 위해 종료 시각을 기록한다
25
+ let compEndedAt = 0;
26
+ /**
27
+ * composition 중 브라우저가 직접 바꾼 DOM을 doc에 흡수한다.
28
+ * 캐럿이 위치한 텍스트 홀더의 DOM 텍스트와 doc 텍스트를 공통
29
+ * 접두/접미로 diff해 차이만큼만 트랜잭션으로 반영한다.
30
+ * (제약: 조합이 하나의 텍스트 홀더 안에 머문다고 가정 —
31
+ * 크로스-블록 조합 삭제는 compositionstart의 선처리가 막는다)
32
+ */
33
+ const absorbComposition = () => {
34
+ const focus = readDomSel()?.focus ?? compStart;
35
+ if (!focus || focus.path.length === 0)
36
+ return;
37
+ const holder = el.querySelector(`[${PATH_ATTR}="${focus.path.join(",")}"]`);
38
+ // 텍스트 홀더가 아니면(안에 me-path 자식이 있으면) 흡수 불가
39
+ if (!holder || holder.querySelector(`[${PATH_ATTR}]`))
40
+ return;
41
+ const domText = holder.textContent ?? "";
42
+ const target = nodeAt(editor.state.doc, focus.path);
43
+ const docText = target?.type === "text" ? (target.text ?? "") : "";
44
+ if (domText === docText)
45
+ return;
46
+ let lo = 0;
47
+ const max = Math.min(domText.length, docText.length);
48
+ while (lo < max && domText[lo] === docText[lo])
49
+ lo++;
50
+ let hiDom = domText.length;
51
+ let hiDoc = docText.length;
52
+ while (hiDom > lo &&
53
+ hiDoc > lo &&
54
+ domText[hiDom - 1] === docText[hiDoc - 1]) {
55
+ hiDom--;
56
+ hiDoc--;
57
+ }
58
+ const tr = editor.state.tr();
59
+ if (hiDoc > lo) {
60
+ tr.delete({
61
+ anchor: point(focus.path, lo),
62
+ focus: point(focus.path, hiDoc),
63
+ });
64
+ }
65
+ const inserted = domText.slice(lo, hiDom);
66
+ if (inserted)
67
+ tr.insertText(inserted, point(focus.path, lo));
68
+ if (!tr.docChanged)
69
+ return;
70
+ tr.setMeta("history.group", "type").setMeta("ime", true);
71
+ // 브라우저가 이 블록의 DOM을 직접 바꿨다 — 리렌더 시 프레임워크
72
+ // 리컨실이 깨지지 않게 블록 리마운트 대상으로 표시한다
73
+ const dk = topBlockKey(focus) ?? topBlockKey(compStart);
74
+ if (dk != null)
75
+ dirtyPaths.add(dk);
76
+ editor.dispatch(tr);
77
+ };
78
+ /**
79
+ * 대기 중인 흡수를 즉시 실행 — 커밋 직후의 구조 입력(Enter 등)이
80
+ * 최신 doc 기준으로 처리되게 하기 위해 게이트에서도 호출한다.
81
+ */
82
+ const flushComposition = () => {
83
+ if (compTimer !== null) {
84
+ clearTimeout(compTimer);
85
+ compTimer = null;
86
+ }
87
+ composing = false;
88
+ pendingAbsorb = false;
89
+ if (editor.editable)
90
+ absorbComposition();
91
+ compStart = null;
92
+ };
93
+ return {
94
+ get active() {
95
+ return composing;
96
+ },
97
+ start() {
98
+ // 이전 세션의 흡수 타이머가 남아있으면 취소한다 — 그대로 두면 새
99
+ // 조합 도중에 flushComposition이 composing을 해제하고 디스패치·
100
+ // 리렌더를 일으켜 브라우저가 살아있는 세션을 리셋한다
101
+ // ("안녕하세요"→"안ㄴ영ㅎ하세세요" 회귀). 커밋된 텍스트는 DOM에
102
+ // 남아 있으므로 다음 flush가 같은 홀더를 diff할 때 함께 흡수된다
103
+ if (compTimer !== null) {
104
+ clearTimeout(compTimer);
105
+ compTimer = null;
106
+ }
107
+ pendingAbsorb = false;
108
+ composing = true;
109
+ const sel = readDomSel();
110
+ compStart = sel?.focus ?? null;
111
+ // 다른 리프에 걸친 선택 위에서 시작되는 조합: 브라우저가 선택
112
+ // 범위를 네이티브로 지우며 여러 DOM 노드를 한꺼번에 바꾼다 —
113
+ // 홀더 단위 diff인 흡수가 따라가지 못한다. 조합 전에 선택을
114
+ // 트랜잭션으로 정리해 조합이 항상 한 리프 안에서 일어나게 한다.
115
+ // (같은 리프 안의 범위 선택은 기존 diff 흡수가 처리한다)
116
+ if (sel && editor.editable && !pathEq(sel.anchor.path, sel.focus.path)) {
117
+ // DOM도 같은 범위를 지워 두 문서가 어긋나지 않게 한다 — 지우지
118
+ // 않으면 조합 첫 글자가 stale DOM 위에 네이티브 삭제를 일으킨다
119
+ el.ownerDocument.getSelection()?.deleteFromDocument?.();
120
+ editor.dispatch(editor.state
121
+ .tr()
122
+ .delete({ anchor: sel.anchor, focus: sel.focus })
123
+ .setSelection(textSelection(sel.anchor))
124
+ .setMeta("history.group", "type")
125
+ .setMeta("ime", true));
126
+ // 양쪽 블록 DOM이 브라우저에 직접 바뀌었다 — 리렌더 시 리컨실이
127
+ // 아닌 리마운트로 복구되게 표시한다
128
+ for (const k of [topBlockKey(sel.anchor), topBlockKey(sel.focus)]) {
129
+ if (k != null)
130
+ dirtyPaths.add(k);
131
+ }
132
+ compStart = sel.anchor;
133
+ }
134
+ },
135
+ end() {
136
+ // composing 해제와 흡수를 다음 태스크로 미룬다 — 같은 태스크의
137
+ // 후속 beforeinput/keydown(Safari 최종 커밋, IME Enter 오커밋)을
138
+ // composing 가드가 계속 걸러내게 하기 위해서다. 단 그 창에 도착한
139
+ // 구조 입력은 flushComposition이 흡수를 앞당겨 정상 처리한다.
140
+ pendingAbsorb = true;
141
+ compEndedAt = performance.now();
142
+ compTimer = setTimeout(flushComposition, 0);
143
+ },
144
+ gate(e, domSel) {
145
+ if (!composing)
146
+ return "proceed";
147
+ // 조합 종료 직후(흡수 대기) 도착한 구조 입력만 통과 — 커밋-Enter의
148
+ // insertParagraph가 대표적이다. 텍스트 계열은 계속 브라우저에
149
+ // 맡겨 DOM이 바뀌게 두고 타이머의 흡수가 잡는다
150
+ const structural = e.inputType === "insertParagraph" ||
151
+ e.inputType === "insertLineBreak" ||
152
+ e.inputType === "insertFromPaste" ||
153
+ e.inputType === "insertFromDrop" ||
154
+ e.inputType.startsWith("delete");
155
+ if (pendingAbsorb && structural) {
156
+ flushComposition();
157
+ return "proceed";
158
+ }
159
+ // 커밋 에코 — DOM에 이미 같은 텍스트가 쓰여 있으면(조합 중 브라우저가
160
+ // 넣은 상태) 통과시키면 브라우저가 한 번 더 써서 "세세"가 된다.
161
+ // DOM에 없으면(Safari 최종 커밋) 살려둬야 글자가 사라지지 않는다
162
+ if ((e.inputType === "insertText" ||
163
+ e.inputType === "insertCompositionText") &&
164
+ e.data &&
165
+ domSel &&
166
+ domEndsWith(el, domSel.focus, e.data)) {
167
+ return "prevent";
168
+ }
169
+ return "swallow";
170
+ },
171
+ isLateEcho(data, domSel) {
172
+ // 커밋 에코가 흡수 타이머보다 늦게 도착한 경우 — DOM과 doc에
173
+ // 이미 같은 글자가 있으므로 다시 넣으면 "세세"가 된다
174
+ return (compEndedAt > 0 &&
175
+ performance.now() - compEndedAt < 300 &&
176
+ domSel != null &&
177
+ domEndsWith(el, domSel.focus, data));
178
+ },
179
+ destroy() {
180
+ if (compTimer !== null)
181
+ clearTimeout(compTimer);
182
+ },
183
+ };
184
+ }
185
+ //# sourceMappingURL=ime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ime.js","sourceRoot":"","sources":["../../src/view/ime.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,17 @@ import type { Editor } from "../editor/editor.js";
13
13
  * doc과 diff해 차이만큼 delete+insert로 흡수한다. composing 해제는
14
14
  * setTimeout으로 지연 — Safari는 compositionend 뒤 같은 태스크에
15
15
  * 최종 beforeinput을 보내고, Chromium은 조합 확정 Enter의 keydown을
16
- * 같은 태스크에 보내므로 둘 다 무시되어야 한다.
16
+ * 같은 태스크에 내므로 둘 다 무시되어야 한다.
17
+ *
18
+ * 이 파일은 이벤트 수신부와 수명주기(IME 상태머신, 셀렉션 동기화)만
19
+ * 담는다 — 판정/디스패치 로직은 형제 모듈로 분리됐다:
20
+ * keys.ts — 키 문자열 정규화 + format* inputType 커맨드 매핑
21
+ * caret.ts — DOM 캐럿 ↔ Point 판정 헬퍼
22
+ * line-nav.ts — 시각적 줄 경계 이동 (Home/End·Mod-Arrow)
23
+ * node-selection.ts — NodeSelection 상태의 beforeinput/keydown/클릭
24
+ * hook-ctx.ts — 입력 훅 컨텍스트 팩토리 + 파일 훅 디스패치
25
+ * dirty-keys.ts — DirtyKeyMap (어댑터 리마운트 키)
26
+ * ime.ts — IME 조합 세션 상태머신 (흡수·커밋 에코 판별)
17
27
  */
18
28
  export interface EditorInputBinding {
19
29
  unbind(): void;
@@ -30,16 +40,6 @@ export interface EditorInputBinding {
30
40
  */
31
41
  readonly dirtyPaths: Set<string>;
32
42
  }
33
- /**
34
- * 어댑터 공용 dirty-key 헬퍼 — binding.dirtyPaths를 소비해 블록
35
- * 렌더 키를 안정적으로 버전업한다. 일반 블록은 path 그대로,
36
- * 외부 DOM 변경이 있었던 블록은 path@N으로 키가 바뀌어
37
- * 프레임워크가 내부 diff 대신 리마운트를 택한다.
38
- */
39
- export declare class DirtyKeyMap {
40
- private readonly versions;
41
- /** rn.path.join(",")와 binding.dirtyPaths를 넣으면 렌더 키를 반환 */
42
- key(pathKey: string, dirty: Set<string> | undefined): string;
43
- }
44
43
  export declare function bindEditorInput(editor: Editor, el: HTMLElement): EditorInputBinding;
44
+ export { DirtyKeyMap } from "./dirty-keys.js";
45
45
  //# sourceMappingURL=input.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/view/input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA0FlD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,IAAI,IAAI,CAAC;IACf,yCAAyC;IACzC,gBAAgB,IAAI,IAAI,CAAC;IACzB,4BAA4B;IAC5B,gBAAgB,IAAI,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClC;AAED;;;;;GAKG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;IACtD,0DAA0D;IAC1D,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM;CAO7D;AA2BD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,WAAW,GACd,kBAAkB,CAk/BpB"}
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../src/view/input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AA4BlD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,IAAI,IAAI,CAAC;IACf,yCAAyC;IACzC,gBAAgB,IAAI,IAAI,CAAC;IACzB,4BAA4B;IAC5B,gBAAgB,IAAI,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAClC;AAED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,WAAW,GACd,kBAAkB,CAwqBpB;AAGD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}