@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,55 @@
1
+ import type { DocNode, EditorNode, Mark } from "../model/node.js";
2
+ import type { Point, Selection } from "./selection.js";
3
+ import type { EditorState } from "./state.js";
4
+ /**
5
+ * 삽입 좌표 정규화 — TransactionBuilder에서 분리한 순수 함수 모듈.
6
+ * DOM 셀렉션에서 오는 임의 포인트를 텍스트 삽입 가능한 형태로
7
+ * 해석하는 규칙들이다. 전부 (state, doc, point)만 받는 순수 함수라
8
+ * 빌더 외에도 재사용할 수 있다.
9
+ */
10
+ /** atom 리프가 아닌 컨테이너인가 — content가 있거나 spec이 자식을 허용 */
11
+ export declare function isContainer(state: EditorState, n: EditorNode): boolean;
12
+ /** 컨테이너가 인라인 자식을 허용하는가 — 스키마 content 표현 기준 */
13
+ export declare function acceptsInline(state: EditorState, n: EditorNode): boolean;
14
+ /**
15
+ * resolveInsert의 정규화 결과 — DOM에서 온 임의 포인트를 삽입 가능한
16
+ * 좌표로 해석한 것.
17
+ * - text : 텍스트 노드 안 포인트 — 문자 오프셋 의미
18
+ * - inside : 인라인 전용 빈 컨테이너 — 텍스트 노드를 자식으로 삽입
19
+ * - block : 블록 경계 — paragraph로 감싼 블록을 삽입
20
+ */
21
+ export type ResolvedInsert = {
22
+ kind: "text";
23
+ point: Point;
24
+ } | {
25
+ kind: "inside";
26
+ path: readonly number[];
27
+ offset: number;
28
+ } | {
29
+ kind: "block";
30
+ path: readonly number[];
31
+ offset: number;
32
+ };
33
+ /**
34
+ * DOM 셀렉션에서 오는 임의 포인트를 텍스트 삽입 가능한 형태로 정규화한다.
35
+ * 브라우저는 캐럿을 컨테이너 경계(block 엘리먼트, doc 루트)나
36
+ * contenteditable=false 노드(atom) 안쪽에도 놓는다 — 그대로 insert하면
37
+ * doc 루트에 bare text 같은 잘못된 구조가 나온다.
38
+ */
39
+ export declare function resolveInsert(state: EditorState, doc: DocNode, p: Point): ResolvedInsert;
40
+ /**
41
+ * 삽입 위치에 상속할 마크 — PM의 MarkSpec.inclusive 관례.
42
+ * 마크 run의 가장자리(앞뒤 이웃이 같은 마크를 갖지 않는 경계)에선
43
+ * `inclusive: false` 마크를 뗀다 — code 마크 끝에서 타이핑이 스팬
44
+ * 밖으로 나오도록. run 안쪽(중간 오프셋, 또는 이웃이 같은 마크인
45
+ * 분할 경계)이면 그대로 이어받는다.
46
+ */
47
+ export declare function marksForInsert(state: EditorState, doc: DocNode, p: Point): readonly Mark[] | undefined;
48
+ /**
49
+ * 삽입 후 캐럿 — 삽입된 노드의 끝. 대상이 텍스트면 마크 동일성에 따라
50
+ * merge(오프셋 이동) 또는 [head, 삽입, tail] 분할(형제 인덱스 이동)이
51
+ * 된다. 끝 삽입에서 idx+2 같은 빈 경로를 만들면 안 된다 (회귀 —
52
+ * 다음 tr이 무효 경로를 block 폴백으로 해석).
53
+ */
54
+ export declare function selectionAfterInsert(at: Point, node: EditorNode, target: EditorNode | undefined): Selection;
55
+ //# sourceMappingURL=resolve-insert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-insert.d.ts","sourceRoot":"","sources":["../../src/state/resolve-insert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAIlE,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C;;;;;GAKG;AAEH,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAEtE;AAED,8CAA8C;AAC9C,wBAAgB,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,EAAE,UAAU,GAAG,OAAO,CAExE;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,OAAO,EACZ,CAAC,EAAE,KAAK,GACP,cAAc,CAwChB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,OAAO,EACZ,CAAC,EAAE,KAAK,GACP,SAAS,IAAI,EAAE,GAAG,SAAS,CAgB7B;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,KAAK,EACT,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,UAAU,GAAG,SAAS,GAC7B,SAAS,CAgBX"}
@@ -0,0 +1,118 @@
1
+ import { firstTextPath, lastTextPath, nodeAt } from "../model/traverse.js";
2
+ import { marksEq } from "./apply.js";
3
+ import { textSelection } from "./selection.js";
4
+ /**
5
+ * 삽입 좌표 정규화 — TransactionBuilder에서 분리한 순수 함수 모듈.
6
+ * DOM 셀렉션에서 오는 임의 포인트를 텍스트 삽입 가능한 형태로
7
+ * 해석하는 규칙들이다. 전부 (state, doc, point)만 받는 순수 함수라
8
+ * 빌더 외에도 재사용할 수 있다.
9
+ */
10
+ /** atom 리프가 아닌 컨테이너인가 — content가 있거나 spec이 자식을 허용 */
11
+ export function isContainer(state, n) {
12
+ return n.content !== undefined || !!state.schema.nodeSpec(n.type)?.content;
13
+ }
14
+ /** 컨테이너가 인라인 자식을 허용하는가 — 스키마 content 표현 기준 */
15
+ export function acceptsInline(state, n) {
16
+ return /inline/.test(state.schema.nodeSpec(n.type)?.content ?? "");
17
+ }
18
+ /**
19
+ * DOM 셀렉션에서 오는 임의 포인트를 텍스트 삽입 가능한 형태로 정규화한다.
20
+ * 브라우저는 캐럿을 컨테이너 경계(block 엘리먼트, doc 루트)나
21
+ * contenteditable=false 노드(atom) 안쪽에도 놓는다 — 그대로 insert하면
22
+ * doc 루트에 bare text 같은 잘못된 구조가 나온다.
23
+ */
24
+ export function resolveInsert(state, doc, p) {
25
+ const node = nodeAt(doc, p.path);
26
+ if (!node)
27
+ return { kind: "block", path: [], offset: 0 };
28
+ if (node.type === "text")
29
+ return { kind: "text", point: p };
30
+ if (!isContainer(state, node)) {
31
+ // atom 리프 — 오프셋은 의미가 없으므로 부모 경계(노드 뒤)로 올린다
32
+ const idx = p.path[p.path.length - 1];
33
+ if (idx == null)
34
+ return { kind: "block", path: [], offset: 0 };
35
+ return resolveInsert(state, doc, {
36
+ path: p.path.slice(0, -1),
37
+ offset: idx + 1,
38
+ });
39
+ }
40
+ const children = node.content ?? [];
41
+ // 앞으로 탐색 — 경계 뒤 첫 텍스트 후손의 시작
42
+ for (let i = p.offset; i < children.length; i++) {
43
+ const ftp = firstTextPath(children[i]);
44
+ if (ftp) {
45
+ return {
46
+ kind: "text",
47
+ point: { path: [...p.path, i, ...ftp], offset: 0 },
48
+ };
49
+ }
50
+ }
51
+ // 뒤로 탐색 — 경계 앞 마지막 텍스트의 끝
52
+ for (let i = Math.min(p.offset, children.length) - 1; i >= 0; i--) {
53
+ const ltp = lastTextPath(children[i]);
54
+ if (ltp) {
55
+ const len = nodeAt(children[i], ltp)?.text?.length ?? 0;
56
+ return {
57
+ kind: "text",
58
+ point: { path: [...p.path, i, ...ltp], offset: len },
59
+ };
60
+ }
61
+ }
62
+ // 텍스트 후손이 전혀 없다 — 인라인 블록이면 안에, 아니면 새 블록으로
63
+ if (p.path.length > 0 && acceptsInline(state, node)) {
64
+ return { kind: "inside", path: p.path, offset: p.offset };
65
+ }
66
+ return { kind: "block", path: p.path, offset: p.offset };
67
+ }
68
+ /**
69
+ * 삽입 위치에 상속할 마크 — PM의 MarkSpec.inclusive 관례.
70
+ * 마크 run의 가장자리(앞뒤 이웃이 같은 마크를 갖지 않는 경계)에선
71
+ * `inclusive: false` 마크를 뗀다 — code 마크 끝에서 타이핑이 스팬
72
+ * 밖으로 나오도록. run 안쪽(중간 오프셋, 또는 이웃이 같은 마크인
73
+ * 분할 경계)이면 그대로 이어받는다.
74
+ */
75
+ export function marksForInsert(state, doc, p) {
76
+ const node = nodeAt(doc, p.path);
77
+ const marks = node?.marks;
78
+ if (!marks?.length)
79
+ return marks;
80
+ const parent = nodeAt(doc, p.path.slice(0, -1));
81
+ const kids = parent?.content ?? [];
82
+ const idx = p.path[p.path.length - 1];
83
+ const has = (n, type) => !!n?.marks?.some((m) => m.type === type);
84
+ const len = node.text?.length ?? 0;
85
+ return marks.filter((m) => {
86
+ if (state.schema.markSpec(m.type)?.inclusive !== false)
87
+ return true;
88
+ if (p.offset === 0)
89
+ return has(kids[idx - 1], m.type);
90
+ if (p.offset === len)
91
+ return has(kids[idx + 1], m.type);
92
+ return true;
93
+ });
94
+ }
95
+ /**
96
+ * 삽입 후 캐럿 — 삽입된 노드의 끝. 대상이 텍스트면 마크 동일성에 따라
97
+ * merge(오프셋 이동) 또는 [head, 삽입, tail] 분할(형제 인덱스 이동)이
98
+ * 된다. 끝 삽입에서 idx+2 같은 빈 경로를 만들면 안 된다 (회귀 —
99
+ * 다음 tr이 무효 경로를 block 폴백으로 해석).
100
+ */
101
+ export function selectionAfterInsert(at, node, target) {
102
+ const len = node.text?.length ?? 0;
103
+ if (target?.type === "text") {
104
+ if (node.type === "text" && marksEq(target.marks, node.marks)) {
105
+ return textSelection({ path: at.path, offset: at.offset + len });
106
+ }
107
+ // 마크가 달라 분할됐다 — 삽입 노드는 head가 있으면 idx+1,
108
+ // 없으면(맨 앞) idx에 놓인다. 캐럿은 삽입 노드 끝.
109
+ const parent = at.path.slice(0, -1);
110
+ const idx = at.path[at.path.length - 1] + (at.offset > 0 ? 1 : 0);
111
+ return textSelection({ path: [...parent, idx], offset: len });
112
+ }
113
+ if (node.type === "text") {
114
+ return textSelection({ path: [...at.path, at.offset], offset: len });
115
+ }
116
+ return textSelection({ path: at.path, offset: at.offset + 1 });
117
+ }
118
+ //# sourceMappingURL=resolve-insert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve-insert.js","sourceRoot":"","sources":["../../src/state/resolve-insert.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { DocNode, EditorNode } from "../model/node.js";
2
+ import type { Point, Selection } from "./selection.js";
3
+ import type { ResolvedInsert } from "./resolve-insert.js";
4
+ import type { Step } from "./transaction.js";
5
+ /**
6
+ * 붙여넣기 조각(slice) 삽입 — TransactionBuilder에서 분리한 모듈.
7
+ * insertSlice는 인라인 조각(텍스트 분할 사이 삽입)과 블록 조각(현재
8
+ * 블록을 나눠 사이에 삽입)의 규칙이 얽혀 있어 전용 모듈로 둔다
9
+ * (PM의 ReplaceAround 관례에 해당하는 최소 구현).
10
+ *
11
+ * 함수들은 SliceOpsHost(= TransactionBuilder의 구조적 뷰)에 스텝을
12
+ * 쌓는다 — list-ops.ts와 같은 패턴으로 순환 import 없이 빌더를
13
+ * 재사용한다. Step은 type-only import라 런타임 순환도 없다.
14
+ */
15
+ /**
16
+ * 슬라이스 연산이 요구하는 빌더 계약 — TransactionBuilder가 만족한다.
17
+ * 스텝 큐·셀렉션·문서 해석만 건드리는 최소 표면으로 제한한다.
18
+ */
19
+ export interface SliceOpsHost {
20
+ /** 적용 후 셀렉션 — 조각 삽입이 커서를 직접 배치할 때 쓴다 */
21
+ selection: Selection | null;
22
+ /** 이미 쌓인 스텝까지 적용된 doc — 빌더 좌표계의 현재 문서 */
23
+ docNow(): DocNode;
24
+ /** 임의 포인트를 삽입 가능한 좌표로 정규화 (transaction.ts 구현) */
25
+ resolveInsert(doc: DocNode, p: Point): ResolvedInsert;
26
+ /** 스키마 기준 인라인 노드인가 — text 또는 inline 그룹/명시 inline */
27
+ isInlineNode(n: EditorNode): boolean;
28
+ /** 인라인만 담는 텍스트블록인가 — paragraph/heading/codeBlock 등 */
29
+ isTextBlock(n: EditorNode): boolean;
30
+ /** 텍스트를 담는 새 블록 — 스키마의 기본 블록 타입 */
31
+ newTextBlock(children: readonly EditorNode[]): EditorNode;
32
+ /** 지금까지 쌓인 스텝을 doc에 적용한 결과 — 캐럿 계산용 */
33
+ simulate(): EditorNode;
34
+ /** 원시 스텝 추가 — 좌표를 이미 계산한 조각 삽입은 정규화를 거치지 않는다 */
35
+ addStep(step: Step): unknown;
36
+ }
37
+ /**
38
+ * 파싱된 노드 조각을 at에 삽입한다 — 붙여넣기 경로.
39
+ * 규칙 (PM slice 관례):
40
+ * - 문단 하나짜리/전부 인라인 → 텍스트를 나누고 인라인으로 풀어 넣는다
41
+ * - 블록이 섞이면 → 현재 블록을 나누고 사이에 블록으로 삽입한다
42
+ * - 컨테이너 경계/atom 안 포인트는 resolveInsert로 수준을 맞춘 뒤
43
+ * 블록 경계의 인라인 조각은 paragraph로 감싼다
44
+ */
45
+ export declare function insertSliceInto(host: SliceOpsHost, at: Point, nodes: readonly EditorNode[]): void;
46
+ //# sourceMappingURL=slice-ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slice-ops.d.ts","sourceRoot":"","sources":["../../src/state/slice-ops.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG5D,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C;;;;;;;;;GASG;AAEH;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,wCAAwC;IACxC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,yCAAyC;IACzC,MAAM,IAAI,OAAO,CAAC;IAClB,iDAAiD;IACjD,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,GAAG,cAAc,CAAC;IACtD,oDAAoD;IACpD,YAAY,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IACrC,sDAAsD;IACtD,WAAW,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;IACpC,mCAAmC;IACnC,YAAY,CAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,CAAC;IAC1D,uCAAuC;IACvC,QAAQ,IAAI,UAAU,CAAC;IACvB,gDAAgD;IAChD,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,YAAY,EAClB,EAAE,EAAE,KAAK,EACT,KAAK,EAAE,SAAS,UAAU,EAAE,GAC3B,IAAI,CA6CN"}
@@ -0,0 +1,150 @@
1
+ import { firstTextPath, lastTextPath, nodeAt } from "../model/traverse.js";
2
+ import { textSelection } from "./selection.js";
3
+ /**
4
+ * 파싱된 노드 조각을 at에 삽입한다 — 붙여넣기 경로.
5
+ * 규칙 (PM slice 관례):
6
+ * - 문단 하나짜리/전부 인라인 → 텍스트를 나누고 인라인으로 풀어 넣는다
7
+ * - 블록이 섞이면 → 현재 블록을 나누고 사이에 블록으로 삽입한다
8
+ * - 컨테이너 경계/atom 안 포인트는 resolveInsert로 수준을 맞춘 뒤
9
+ * 블록 경계의 인라인 조각은 paragraph로 감싼다
10
+ */
11
+ export function insertSliceInto(host, at, nodes) {
12
+ if (!nodes.length)
13
+ return;
14
+ const doc = host.docNow();
15
+ if (nodeAt(doc, at.path)?.type !== "text") {
16
+ // 컨테이너 경계/atom 안 포인트 — 텍스트 위치로 해석해 수준을 맞춘다
17
+ const r = host.resolveInsert(doc, at);
18
+ if (r.kind === "text") {
19
+ at = r.point;
20
+ }
21
+ else if (r.kind === "inside") {
22
+ at = nodes.every((n) => host.isInlineNode(n))
23
+ ? { path: r.path, offset: r.offset }
24
+ : // 블록은 인라인 컨테이너 안에 못 넣는다 — 블록 뒤 경계로 승격
25
+ {
26
+ path: r.path.slice(0, -1),
27
+ offset: r.path[r.path.length - 1] + 1,
28
+ };
29
+ }
30
+ else {
31
+ const at2 = { path: r.path, offset: r.offset };
32
+ // doc 루트 등 블록 경계 — 인라인 조각은 paragraph로 감싼다
33
+ insertBlockSlice(host, doc, at2, nodes.every((n) => host.isInlineNode(n))
34
+ ? [host.newTextBlock(nodes)]
35
+ : nodes);
36
+ return;
37
+ }
38
+ }
39
+ const target = nodeAt(doc, at.path);
40
+ // 문단 하나짜리 붙여넣기 — 인라인으로 풀어 삽입 (PM slice 관례)
41
+ if (nodes.length === 1 &&
42
+ target?.type === "text" &&
43
+ host.isTextBlock(nodes[0])) {
44
+ insertInlineSlice(host, at, nodes[0].content ?? []);
45
+ return;
46
+ }
47
+ if (nodes.every((n) => host.isInlineNode(n))) {
48
+ insertInlineSlice(host, at, nodes);
49
+ return;
50
+ }
51
+ insertBlockSlice(host, doc, at, nodes);
52
+ }
53
+ /** 인라인 조각 — 텍스트를 at.offset에서 나누고 사이에 끼운다 */
54
+ function insertInlineSlice(host, at, nodes) {
55
+ const target = nodeAt(host.docNow(), at.path);
56
+ if (target?.type === "text") {
57
+ const parent = at.path.slice(0, -1);
58
+ const i = at.path[at.path.length - 1];
59
+ const len = target.text?.length ?? 0;
60
+ let base;
61
+ let caretAfter;
62
+ if (at.offset === 0) {
63
+ base = i;
64
+ caretAfter = { path: [...parent, i + nodes.length], offset: 0 };
65
+ }
66
+ else if (at.offset >= len) {
67
+ base = i + 1;
68
+ caretAfter = { path: [...parent, i + 1 + nodes.length], offset: 0 };
69
+ }
70
+ else {
71
+ host.addStep({ op: "split", at, depth: 0 });
72
+ base = i + 1;
73
+ caretAfter = { path: [...parent, i + 1 + nodes.length], offset: 0 };
74
+ }
75
+ nodes.forEach((node, j) => {
76
+ host.addStep({
77
+ op: "insert",
78
+ at: { path: parent, offset: base + j },
79
+ node,
80
+ });
81
+ });
82
+ host.selection = textSelection(caretAfter);
83
+ return;
84
+ }
85
+ // 컨테이너 경계
86
+ nodes.forEach((node, j) => {
87
+ host.addStep({
88
+ op: "insert",
89
+ at: { path: at.path, offset: at.offset + j },
90
+ node,
91
+ });
92
+ });
93
+ host.selection = textSelection({
94
+ path: at.path,
95
+ offset: at.offset + nodes.length,
96
+ });
97
+ }
98
+ /** 블록 조각 — 현재 블록을 나누고 사이에 삽입 (doc 최상위 기준) */
99
+ function insertBlockSlice(host, doc, at, nodes) {
100
+ const target = nodeAt(doc, at.path);
101
+ if (target?.type === "text") {
102
+ const bi = at.path[0];
103
+ if (bi == null)
104
+ return;
105
+ // 텍스트 + 상위 체인을 전부 나눠 최상위 블록을 둘로 만든다
106
+ host.addStep({ op: "split", at, depth: at.path.length - 1 });
107
+ const insertAt = bi + 1;
108
+ nodes.forEach((node, j) => {
109
+ host.addStep({
110
+ op: "insert",
111
+ at: { path: [], offset: insertAt + j },
112
+ node,
113
+ });
114
+ });
115
+ // 캐럿 = 오른쪽 부분 블록(bi+1+n)의 첫 텍스트, 없으면 마지막 삽입 끝
116
+ const sim = host.simulate();
117
+ const right = nodeAt(sim, [insertAt + nodes.length]);
118
+ const ftp = right ? firstTextPath(right) : null;
119
+ if (ftp) {
120
+ host.selection = textSelection({
121
+ path: [insertAt + nodes.length, ...ftp],
122
+ offset: 0,
123
+ });
124
+ }
125
+ else {
126
+ const last = nodes[nodes.length - 1];
127
+ const ltp = last ? lastTextPath(last) : null;
128
+ host.selection = ltp
129
+ ? textSelection({
130
+ path: [insertAt + nodes.length - 1, ...ltp],
131
+ offset: (nodeAt(last, ltp)?.text ?? "").length,
132
+ })
133
+ : textSelection({ path: [insertAt], offset: 0 });
134
+ }
135
+ return;
136
+ }
137
+ // 컨테이너 경계 — 같은 부모 안에 순서대로 삽입
138
+ nodes.forEach((node, j) => {
139
+ host.addStep({
140
+ op: "insert",
141
+ at: { path: at.path, offset: at.offset + j },
142
+ node,
143
+ });
144
+ });
145
+ host.selection = textSelection({
146
+ path: at.path,
147
+ offset: at.offset + nodes.length,
148
+ });
149
+ }
150
+ //# sourceMappingURL=slice-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slice-ops.js","sourceRoot":"","sources":["../../src/state/slice-ops.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { DocNode, Mark } from "../model/node.js";
2
2
  import type { Schema } from "../model/schema.js";
3
- import type { Plugin } from "../editor/extension.js";
3
+ import type { Decoration, Plugin } from "../editor/extension.js";
4
4
  import type { Selection } from "./selection.js";
5
5
  import type { Transaction } from "./transaction.js";
6
6
  /**
@@ -29,6 +29,11 @@ export interface EditorState {
29
29
  apply(tr: Transaction): EditorState;
30
30
  /** 이 상태에서 시작하는 새 트랜잭션 빌더 */
31
31
  tr(): Transaction;
32
+ /**
33
+ * 플러그인 뷰 데코레이션 수집 — 렌더러가 매 커밋마다 호출해
34
+ * `renderChildren`의 decos 인자로 넘긴다. 합성 순서 = plugins 순서.
35
+ */
36
+ decorations(): readonly Decoration[];
32
37
  }
33
38
  export interface CreateStateOptions extends EditorStateConfig {
34
39
  /** 플러그인 — init/apply로 pluginState를 채운다 */
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/state/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAQ,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;;;;;GAOG;AAEH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,WAAW,EAAE,SAAS,IAAI,EAAE,GAAG,IAAI,CAAC;IAC7C,+BAA+B;IAC/B,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAExD,kDAAkD;IAClD,KAAK,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CAAC;IACpC,4BAA4B;IAC5B,EAAE,IAAI,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,0CAA0C;IAC1C,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAsGD,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAsBpE"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/state/state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAGjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,OAAO,KAAK,EAAQ,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;;;;;GAOG;AAEH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,SAAS,IAAI,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,mDAAmD;IACnD,QAAQ,CAAC,WAAW,EAAE,SAAS,IAAI,EAAE,GAAG,IAAI,CAAC;IAC7C,+BAA+B;IAC/B,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAExD,kDAAkD;IAClD,KAAK,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CAAC;IACpC,4BAA4B;IAC5B,EAAE,IAAI,WAAW,CAAC;IAClB;;;OAGG;IACH,WAAW,IAAI,SAAS,UAAU,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,0CAA0C;IAC1C,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAgHD,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAsBpE"}
@@ -63,6 +63,16 @@ class EditorStateImpl {
63
63
  tr() {
64
64
  return new TransactionBuilder(this);
65
65
  }
66
+ /** 플러그인 데코레이션 합산 — 훅 순서 = extensions 등록 순서 */
67
+ decorations() {
68
+ const out = [];
69
+ for (const p of this.plugins) {
70
+ const d = p.decorations?.(this);
71
+ if (d)
72
+ out.push(...d);
73
+ }
74
+ return out;
75
+ }
66
76
  apply(tr) {
67
77
  let doc = this.doc;
68
78
  let sel = this.selection;
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state/state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state/state.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  import type { InputRule } from "../editor/extension.js";
2
- import type { EditorNode, Mark } from "../model/node.js";
3
- import type { EditorState } from "./state.js";
2
+ import type { DocNode, EditorNode, Mark } from "../model/node.js";
3
+ import type { ResolvedInsert } from "./resolve-insert.js";
4
4
  import type { Point, Range, Selection } from "./selection.js";
5
+ import type { EditorState } from "./state.js";
5
6
  /**
6
7
  * 트랜잭션 = 하나의 디스패치 단위. Step 배열 + 셀렉션 + 메타데이터.
7
8
  *
@@ -120,8 +121,23 @@ export interface Transaction {
120
121
  */
121
122
  applyInputRules(rules: readonly InputRule[]): this;
122
123
  }
124
+ /**
125
+ * 트랜잭션 빌더 — EditorState.tr()이 만든다.
126
+ *
127
+ * 복잡한 연산은 전용 모듈에 위임하고 이 클래스는 스텝 큐와
128
+ * 좌표계(docNow)만 유지한다:
129
+ * insert-ops.ts — insertText/insertNode/split + 빈 블록 삽입
130
+ * delete-ops.ts — 임의 범위의 remove/insert 분해
131
+ * list-ops.ts — splitItem/liftItem/sinkItem
132
+ * slice-ops.ts — 붙여넣기 조각 삽입
133
+ * input-rules.ts — 마크다운식 입력 변환
134
+ * resolve-insert.ts — DOM 포인트 → 삽입 좌표 정규화 (순수)
135
+ *
136
+ * 각 모듈은 호스트 인터페이스(ListOpsHost 등)로 이 빌더의 최소
137
+ * 표면만 받는다 — 순환 import 없이 빌더를 재사용한다.
138
+ */
123
139
  export declare class TransactionBuilder implements Transaction {
124
- private readonly state;
140
+ readonly state: EditorState;
125
141
  steps: Step[];
126
142
  selection: Selection | null;
127
143
  storedMarks: Mark[] | null;
@@ -134,37 +150,27 @@ export declare class TransactionBuilder implements Transaction {
134
150
  * PM 관례상 "직전 스텝까지 적용된 문서" 좌표다. tr.delete(sel) 뒤
135
151
  * insertText가 삭제된 노드를 가리키는 일이 없게 한다.
136
152
  */
137
- private docNow;
138
- private pushRemove;
139
- /** atom 리프가 아닌 컨테이너인가 — content가 있거나 spec이 자식을 허용 */
140
- private isContainer;
141
- /** 컨테이너가 인라인 자식을 허용하는가 — 스키마 content 표현 기준 */
142
- private acceptsInline;
153
+ docNow(): DocNode;
154
+ /** 임의 포인트를 삽입 가능한 좌표로 정규화 (SliceOpsHost 계약) */
155
+ resolveInsert(doc: DocNode, p: Point): ResolvedInsert;
156
+ /** 텍스트를 담는 새 블록 — 스키마에 paragraph가 없으면 inline 블록을 찾는다 (SliceOpsHost 계약) */
157
+ newTextBlock(children: readonly EditorNode[]): EditorNode;
143
158
  /**
144
- * DOM 셀렉션에서 오는 임의 포인트를 텍스트 삽입 가능한 형태로 정규화한다.
145
- * 브라우저는 캐럿을 컨테이너 경계(block 엘리먼트, doc 루트)나
146
- * contenteditable=false 노드(atom) 안쪽에도 놓는다 — 그대로 insert하면
147
- * doc 루트에 bare text 같은 잘못된 구조가 나온다.
148
- * - text : 텍스트 노드 안 포인트 — 문자 오프셋 의미
149
- * - inside : 인라인 전용 빈 컨테이너 — 텍스트 노드를 자식으로 삽입
150
- * - block : 블록 경계 — paragraph로 감싼 블록을 삽입
159
+ * 텍스트 삽입 — 구현은 insert-ops.ts. at이 없으면 현재 셀렉션
160
+ * (비축소면 먼저 삭제). 마크 우선순위와 code 블록 무시는
161
+ * insert-ops.ts의 규칙을 따른다.
151
162
  */
152
- private resolveInsert;
153
- /** 기본 텍스트블록 타입 — paragraph, 없으면 inline을 받는 첫 block */
154
- private defaultBlockType;
155
- /** 텍스트를 담는 새 블록 — 스키마에 paragraph가 없으면 inline 블록을 찾는다 */
156
- private newTextBlock;
157
- /** 블록 시작 셀렉션 — 텍스트 자식이 있으면 첫 텍스트 앞, 없으면 블록 안 */
158
- private selStartOfBlock;
159
- /** 블록 경계에 새 빈 블록을 넣고 캐럿을 그 안에 둔다 */
160
- private insertEmptyBlock;
161
163
  insertText(text: string, at?: Point): this;
162
- private selectionAfterInsert;
164
+ /**
165
+ * 노드 삽입 — at에 그대로 넣고 캐럿은 삽입물 뒤에 둔다.
166
+ * 구현은 insert-ops.ts.
167
+ */
163
168
  insertNode(at: Point, node: EditorNode): this;
164
169
  /**
165
170
  * at 위치에서 노드를 분할한다 (Enter). 생략하면 현재 셀렉션 —
166
171
  * 비어있지 않은 셀렉션이면 먼저 지운 뒤 분할한다.
167
172
  * 셀렉션은 분할된 "오른쪽" 부분의 시작으로 옮긴다.
173
+ * 구현은 insert-ops.ts — 비텍스트 포인트 환원과 splitExit 규칙을 포함한다.
168
174
  */
169
175
  split(at?: Point, depth?: number): this;
170
176
  /**
@@ -187,39 +193,27 @@ export declare class TransactionBuilder implements Transaction {
187
193
  sinkItem(itemPath: readonly number[]): this;
188
194
  replaceNode(path: readonly number[], node: EditorNode): this;
189
195
  addStep(step: Step): this;
190
- private isInlineNode;
191
- private isTextBlock;
196
+ /** SliceOpsHost 계약 — 스키마 기준 인라인 노드 판정 */
197
+ isInlineNode(n: EditorNode): boolean;
198
+ /** SliceOpsHost 계약 — 인라인만 담는 텍스트블록 판정 */
199
+ isTextBlock(n: EditorNode): boolean;
192
200
  insertSlice(at: Point, nodes: readonly EditorNode[]): this;
193
- /** 인라인 조각 — 텍스트를 o에서 나누고 사이에 끼운다 */
194
- private insertInlineSlice;
195
- /** 블록 조각 — 현재 블록을 나누고 사이에 삽입 (doc 최상위 기준) */
196
- private insertBlockSlice;
197
- /** 지금까지 쌓인 스텝을 doc에 적용한 결과 — 캐럿 계산용 */
198
- private simulate;
201
+ /** 지금까지 쌓인 스텝을 doc에 적용한 결과 — 캐럿 계산용 (SliceOpsHost 계약) */
202
+ simulate(): EditorNode;
199
203
  /**
200
- * 문서 순서 비교 — pointCmp와 다른 점: 컨테이너 경계 포인트를
201
- * "자식 offset 앞"으로 해석한다. pointCmp는 [i]/k < [i,j]/m이지만
202
- * 실제 문서 순서에선 [i]/k 는 k>j 이면 [i,j] 안쪽 "뒤"다 —
203
- * DOM 셀렉션이 만드는 (블록엘리먼트, 자식인덱스) 포인트를 정렬할 때
204
- * pointCmp를 쓰면 범위가 뒤집힌다.
204
+ * 범위 삭제 — 구현은 delete-ops.ts. anchor/focus 순서와 atom 경계를
205
+ * 정규화하고, LCA 레벨 삭제 + 양 끝 재귀 trim으로 임의 범위를
206
+ * remove/insert 스텝 열로 분해한다.
205
207
  */
206
- private docOrderCmp;
207
- /** atom 리프 안 포인트를 부모 경계로 올린다 — dir>0이면 노드 "뒤" 경계 */
208
- private resolveBoundary;
209
208
  delete(range: Range): this;
210
- /** a<f로 정렬 + atom 경계 해석이 끝난 범위 삭제 — 재귀용 내부 구현 */
211
- private deleteOrdered;
212
209
  addMark(range: Range, mark: Mark): this;
213
210
  removeMark(range: Range, markType: string): this;
214
211
  setNodeAttr(path: readonly number[], key: string, value: unknown): this;
215
212
  setSelection(selection: Selection): this;
216
213
  setStoredMarks(marks: readonly Mark[] | null): this;
217
214
  /**
218
- * 입력 규칙 — 마크다운식 변환(`# `→heading, `**x**`→bold).
219
- * 캐럿이 속한 인라인 블록의 블록 시작~커서 텍스트를 만들어 각
220
- * 규칙의 pattern에 매칭한다. 매치가 커서에서 끝나는 첫 규칙이
221
- * 이 tr 위에 변환 스텝을 쌓는다 — 위치는 docNow 좌표라 규칙
222
- * 핸들러가 쌓은 스텝도 직전 스텝 기준으로 해석된다.
215
+ * 입력 규칙 — 구현은 input-rules.ts. 캐럿이 멈춘 텍스트블록의
216
+ * 블록 시작~커서 텍스트에 규칙을 순서대로 적용한다.
223
217
  */
224
218
  applyInputRules(rules: readonly InputRule[]): this;
225
219
  setMeta(key: string, value: unknown): this;