@rtif-sdk/web 1.0.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 (215) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -0
  3. package/dist/block-drag-handler.d.ts +189 -0
  4. package/dist/block-drag-handler.d.ts.map +1 -0
  5. package/dist/block-drag-handler.js +745 -0
  6. package/dist/block-drag-handler.js.map +1 -0
  7. package/dist/block-renderer.d.ts +402 -0
  8. package/dist/block-renderer.d.ts.map +1 -0
  9. package/dist/block-renderer.js +424 -0
  10. package/dist/block-renderer.js.map +1 -0
  11. package/dist/clipboard.d.ts +178 -0
  12. package/dist/clipboard.d.ts.map +1 -0
  13. package/dist/clipboard.js +432 -0
  14. package/dist/clipboard.js.map +1 -0
  15. package/dist/command-bus.d.ts +113 -0
  16. package/dist/command-bus.d.ts.map +1 -0
  17. package/dist/command-bus.js +70 -0
  18. package/dist/command-bus.js.map +1 -0
  19. package/dist/composition.d.ts +220 -0
  20. package/dist/composition.d.ts.map +1 -0
  21. package/dist/composition.js +271 -0
  22. package/dist/composition.js.map +1 -0
  23. package/dist/content-extraction.d.ts +69 -0
  24. package/dist/content-extraction.d.ts.map +1 -0
  25. package/dist/content-extraction.js +228 -0
  26. package/dist/content-extraction.js.map +1 -0
  27. package/dist/content-handler-file.d.ts +40 -0
  28. package/dist/content-handler-file.d.ts.map +1 -0
  29. package/dist/content-handler-file.js +91 -0
  30. package/dist/content-handler-file.js.map +1 -0
  31. package/dist/content-handler-image.d.ts +82 -0
  32. package/dist/content-handler-image.d.ts.map +1 -0
  33. package/dist/content-handler-image.js +120 -0
  34. package/dist/content-handler-image.js.map +1 -0
  35. package/dist/content-handler-url.d.ts +129 -0
  36. package/dist/content-handler-url.d.ts.map +1 -0
  37. package/dist/content-handler-url.js +244 -0
  38. package/dist/content-handler-url.js.map +1 -0
  39. package/dist/content-handlers.d.ts +67 -0
  40. package/dist/content-handlers.d.ts.map +1 -0
  41. package/dist/content-handlers.js +263 -0
  42. package/dist/content-handlers.js.map +1 -0
  43. package/dist/content-pipeline.d.ts +383 -0
  44. package/dist/content-pipeline.d.ts.map +1 -0
  45. package/dist/content-pipeline.js +232 -0
  46. package/dist/content-pipeline.js.map +1 -0
  47. package/dist/cursor-nav.d.ts +149 -0
  48. package/dist/cursor-nav.d.ts.map +1 -0
  49. package/dist/cursor-nav.js +230 -0
  50. package/dist/cursor-nav.js.map +1 -0
  51. package/dist/cursor-rect.d.ts +65 -0
  52. package/dist/cursor-rect.d.ts.map +1 -0
  53. package/dist/cursor-rect.js +98 -0
  54. package/dist/cursor-rect.js.map +1 -0
  55. package/dist/drop-indicator.d.ts +108 -0
  56. package/dist/drop-indicator.d.ts.map +1 -0
  57. package/dist/drop-indicator.js +236 -0
  58. package/dist/drop-indicator.js.map +1 -0
  59. package/dist/editor.d.ts +41 -0
  60. package/dist/editor.d.ts.map +1 -0
  61. package/dist/editor.js +710 -0
  62. package/dist/editor.js.map +1 -0
  63. package/dist/floating-toolbar.d.ts +93 -0
  64. package/dist/floating-toolbar.d.ts.map +1 -0
  65. package/dist/floating-toolbar.js +159 -0
  66. package/dist/floating-toolbar.js.map +1 -0
  67. package/dist/index.d.ts +62 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +119 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/input-bridge.d.ts +273 -0
  72. package/dist/input-bridge.d.ts.map +1 -0
  73. package/dist/input-bridge.js +884 -0
  74. package/dist/input-bridge.js.map +1 -0
  75. package/dist/link-popover.d.ts +38 -0
  76. package/dist/link-popover.d.ts.map +1 -0
  77. package/dist/link-popover.js +278 -0
  78. package/dist/link-popover.js.map +1 -0
  79. package/dist/mark-renderer.d.ts +275 -0
  80. package/dist/mark-renderer.d.ts.map +1 -0
  81. package/dist/mark-renderer.js +210 -0
  82. package/dist/mark-renderer.js.map +1 -0
  83. package/dist/perf.d.ts +145 -0
  84. package/dist/perf.d.ts.map +1 -0
  85. package/dist/perf.js +260 -0
  86. package/dist/perf.js.map +1 -0
  87. package/dist/plugin-kit.d.ts +265 -0
  88. package/dist/plugin-kit.d.ts.map +1 -0
  89. package/dist/plugin-kit.js +234 -0
  90. package/dist/plugin-kit.js.map +1 -0
  91. package/dist/plugins/alignment-plugin.d.ts +68 -0
  92. package/dist/plugins/alignment-plugin.d.ts.map +1 -0
  93. package/dist/plugins/alignment-plugin.js +98 -0
  94. package/dist/plugins/alignment-plugin.js.map +1 -0
  95. package/dist/plugins/block-utils.d.ts +113 -0
  96. package/dist/plugins/block-utils.d.ts.map +1 -0
  97. package/dist/plugins/block-utils.js +191 -0
  98. package/dist/plugins/block-utils.js.map +1 -0
  99. package/dist/plugins/blockquote-plugin.d.ts +39 -0
  100. package/dist/plugins/blockquote-plugin.d.ts.map +1 -0
  101. package/dist/plugins/blockquote-plugin.js +88 -0
  102. package/dist/plugins/blockquote-plugin.js.map +1 -0
  103. package/dist/plugins/bold-plugin.d.ts +37 -0
  104. package/dist/plugins/bold-plugin.d.ts.map +1 -0
  105. package/dist/plugins/bold-plugin.js +48 -0
  106. package/dist/plugins/bold-plugin.js.map +1 -0
  107. package/dist/plugins/callout-plugin.d.ts +100 -0
  108. package/dist/plugins/callout-plugin.d.ts.map +1 -0
  109. package/dist/plugins/callout-plugin.js +200 -0
  110. package/dist/plugins/callout-plugin.js.map +1 -0
  111. package/dist/plugins/code-block-plugin.d.ts +62 -0
  112. package/dist/plugins/code-block-plugin.d.ts.map +1 -0
  113. package/dist/plugins/code-block-plugin.js +176 -0
  114. package/dist/plugins/code-block-plugin.js.map +1 -0
  115. package/dist/plugins/code-plugin.d.ts +37 -0
  116. package/dist/plugins/code-plugin.d.ts.map +1 -0
  117. package/dist/plugins/code-plugin.js +48 -0
  118. package/dist/plugins/code-plugin.js.map +1 -0
  119. package/dist/plugins/embed-plugin.d.ts +90 -0
  120. package/dist/plugins/embed-plugin.d.ts.map +1 -0
  121. package/dist/plugins/embed-plugin.js +147 -0
  122. package/dist/plugins/embed-plugin.js.map +1 -0
  123. package/dist/plugins/font-family-plugin.d.ts +58 -0
  124. package/dist/plugins/font-family-plugin.d.ts.map +1 -0
  125. package/dist/plugins/font-family-plugin.js +57 -0
  126. package/dist/plugins/font-family-plugin.js.map +1 -0
  127. package/dist/plugins/font-size-plugin.d.ts +57 -0
  128. package/dist/plugins/font-size-plugin.d.ts.map +1 -0
  129. package/dist/plugins/font-size-plugin.js +56 -0
  130. package/dist/plugins/font-size-plugin.js.map +1 -0
  131. package/dist/plugins/heading-plugin.d.ts +52 -0
  132. package/dist/plugins/heading-plugin.d.ts.map +1 -0
  133. package/dist/plugins/heading-plugin.js +114 -0
  134. package/dist/plugins/heading-plugin.js.map +1 -0
  135. package/dist/plugins/hr-plugin.d.ts +33 -0
  136. package/dist/plugins/hr-plugin.d.ts.map +1 -0
  137. package/dist/plugins/hr-plugin.js +75 -0
  138. package/dist/plugins/hr-plugin.js.map +1 -0
  139. package/dist/plugins/image-plugin.d.ts +115 -0
  140. package/dist/plugins/image-plugin.d.ts.map +1 -0
  141. package/dist/plugins/image-plugin.js +199 -0
  142. package/dist/plugins/image-plugin.js.map +1 -0
  143. package/dist/plugins/indent-plugin.d.ts +62 -0
  144. package/dist/plugins/indent-plugin.d.ts.map +1 -0
  145. package/dist/plugins/indent-plugin.js +128 -0
  146. package/dist/plugins/indent-plugin.js.map +1 -0
  147. package/dist/plugins/index.d.ts +45 -0
  148. package/dist/plugins/index.d.ts.map +1 -0
  149. package/dist/plugins/index.js +42 -0
  150. package/dist/plugins/index.js.map +1 -0
  151. package/dist/plugins/italic-plugin.d.ts +37 -0
  152. package/dist/plugins/italic-plugin.d.ts.map +1 -0
  153. package/dist/plugins/italic-plugin.js +48 -0
  154. package/dist/plugins/italic-plugin.js.map +1 -0
  155. package/dist/plugins/link-plugin.d.ts +129 -0
  156. package/dist/plugins/link-plugin.d.ts.map +1 -0
  157. package/dist/plugins/link-plugin.js +212 -0
  158. package/dist/plugins/link-plugin.js.map +1 -0
  159. package/dist/plugins/list-plugin.d.ts +53 -0
  160. package/dist/plugins/list-plugin.d.ts.map +1 -0
  161. package/dist/plugins/list-plugin.js +309 -0
  162. package/dist/plugins/list-plugin.js.map +1 -0
  163. package/dist/plugins/mark-utils.d.ts +173 -0
  164. package/dist/plugins/mark-utils.d.ts.map +1 -0
  165. package/dist/plugins/mark-utils.js +425 -0
  166. package/dist/plugins/mark-utils.js.map +1 -0
  167. package/dist/plugins/mention-plugin.d.ts +191 -0
  168. package/dist/plugins/mention-plugin.d.ts.map +1 -0
  169. package/dist/plugins/mention-plugin.js +295 -0
  170. package/dist/plugins/mention-plugin.js.map +1 -0
  171. package/dist/plugins/strikethrough-plugin.d.ts +37 -0
  172. package/dist/plugins/strikethrough-plugin.d.ts.map +1 -0
  173. package/dist/plugins/strikethrough-plugin.js +48 -0
  174. package/dist/plugins/strikethrough-plugin.js.map +1 -0
  175. package/dist/plugins/text-color-plugin.d.ts +57 -0
  176. package/dist/plugins/text-color-plugin.d.ts.map +1 -0
  177. package/dist/plugins/text-color-plugin.js +56 -0
  178. package/dist/plugins/text-color-plugin.js.map +1 -0
  179. package/dist/plugins/underline-plugin.d.ts +37 -0
  180. package/dist/plugins/underline-plugin.d.ts.map +1 -0
  181. package/dist/plugins/underline-plugin.js +48 -0
  182. package/dist/plugins/underline-plugin.js.map +1 -0
  183. package/dist/presets.d.ts +95 -0
  184. package/dist/presets.d.ts.map +1 -0
  185. package/dist/presets.js +159 -0
  186. package/dist/presets.js.map +1 -0
  187. package/dist/renderer.d.ts +125 -0
  188. package/dist/renderer.d.ts.map +1 -0
  189. package/dist/renderer.js +415 -0
  190. package/dist/renderer.js.map +1 -0
  191. package/dist/scroll-to-cursor.d.ts +25 -0
  192. package/dist/scroll-to-cursor.d.ts.map +1 -0
  193. package/dist/scroll-to-cursor.js +59 -0
  194. package/dist/scroll-to-cursor.js.map +1 -0
  195. package/dist/selection-sync.d.ts +159 -0
  196. package/dist/selection-sync.d.ts.map +1 -0
  197. package/dist/selection-sync.js +527 -0
  198. package/dist/selection-sync.js.map +1 -0
  199. package/dist/shortcut-handler.d.ts +98 -0
  200. package/dist/shortcut-handler.d.ts.map +1 -0
  201. package/dist/shortcut-handler.js +155 -0
  202. package/dist/shortcut-handler.js.map +1 -0
  203. package/dist/toolbar.d.ts +103 -0
  204. package/dist/toolbar.d.ts.map +1 -0
  205. package/dist/toolbar.js +134 -0
  206. package/dist/toolbar.js.map +1 -0
  207. package/dist/trigger-manager.d.ts +205 -0
  208. package/dist/trigger-manager.d.ts.map +1 -0
  209. package/dist/trigger-manager.js +466 -0
  210. package/dist/trigger-manager.js.map +1 -0
  211. package/dist/types.d.ts +216 -0
  212. package/dist/types.d.ts.map +1 -0
  213. package/dist/types.js +2 -0
  214. package/dist/types.js.map +1 -0
  215. package/package.json +30 -0
@@ -0,0 +1,309 @@
1
+ /**
2
+ * List item block type plugin -- registers the `list-item` block type,
3
+ * `toggleBulletList` / `toggleOrderedList` toggle commands,
4
+ * `indentList` / `outdentList` depth commands, and input rules for
5
+ * `- `, `* `, and `1. ` at block start.
6
+ *
7
+ * @module
8
+ */
9
+ import { blockTextLength, resolve } from '@rtif-sdk/core';
10
+ import { getBlockAtCursor, getBlockStartOffset } from './block-utils.js';
11
+ /**
12
+ * Command name constants for the list plugin.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * engine.exec(ListCommands.TOGGLE_BULLET);
17
+ * engine.exec(ListCommands.TOGGLE_ORDERED);
18
+ * engine.exec(ListCommands.INDENT);
19
+ * engine.exec(ListCommands.OUTDENT);
20
+ * ```
21
+ */
22
+ export const ListCommands = {
23
+ TOGGLE_BULLET: 'toggleBulletList',
24
+ TOGGLE_ORDERED: 'toggleOrderedList',
25
+ INDENT: 'indentList',
26
+ OUTDENT: 'outdentList',
27
+ };
28
+ /** Maximum nesting depth for list items */
29
+ const MAX_DEPTH = 8;
30
+ /**
31
+ * Check whether a block is a list-item with an optional specific listStyle.
32
+ *
33
+ * @param block - The block to inspect
34
+ * @param listStyle - If provided, also check the listStyle attr matches
35
+ * @returns `true` if the block is a list-item with the matching style
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * isListItem(block); // true if block.type === 'list-item'
40
+ * isListItem(block, 'bullet'); // true if also listStyle === 'bullet'
41
+ * ```
42
+ */
43
+ function isListItem(block, listStyle) {
44
+ if (block.type !== 'list-item') {
45
+ return false;
46
+ }
47
+ if (listStyle === undefined) {
48
+ return true;
49
+ }
50
+ return block.attrs?.listStyle === listStyle;
51
+ }
52
+ /**
53
+ * Get the current depth of a list-item block.
54
+ *
55
+ * @param block - A list-item block
56
+ * @returns The depth value, defaulting to 0 if not set
57
+ */
58
+ function getDepth(block) {
59
+ const depth = block.attrs?.depth;
60
+ return typeof depth === 'number' ? depth : 0;
61
+ }
62
+ /**
63
+ * Build operations to revert a list-item block back to plain text.
64
+ *
65
+ * @param blockId - The block ID to revert
66
+ * @returns An array of operations that set the type to "text" and clear list attrs
67
+ */
68
+ function revertToText(blockId) {
69
+ return [
70
+ { type: 'set_block_type', blockId, blockType: 'text' },
71
+ { type: 'set_block_attrs', blockId, attrs: { listStyle: null, depth: null } },
72
+ ];
73
+ }
74
+ /**
75
+ * Build operations to set a block to a list-item with a given style.
76
+ *
77
+ * @param blockId - The block ID to convert
78
+ * @param listStyle - The list style to apply
79
+ * @returns An array of operations that set the type and attrs
80
+ */
81
+ function setListItem(blockId, listStyle) {
82
+ return [
83
+ { type: 'set_block_type', blockId, blockType: 'list-item' },
84
+ { type: 'set_block_attrs', blockId, attrs: { listStyle, depth: 0 } },
85
+ ];
86
+ }
87
+ /**
88
+ * Create the list item block type plugin.
89
+ *
90
+ * Registers:
91
+ * - Block type: `list-item` (attrs must have `listStyle` of "bullet" or "ordered", `depth` >= 0)
92
+ * - Command: `toggleBulletList` -- toggle between bullet list-item and plain text
93
+ * - Command: `toggleOrderedList` -- toggle between ordered list-item and plain text
94
+ * - Command: `indentList` -- increase list-item depth by 1 (max 8)
95
+ * - Command: `outdentList` -- decrease list-item depth by 1, or revert to text at depth 0
96
+ * - Input rules: `- ` / `* ` at block start converts to bullet list, `1. ` converts to ordered list
97
+ *
98
+ * @returns A plugin instance ready for `engine.use()`
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * const engine = createEngine(initialDoc);
103
+ * engine.use(listPlugin());
104
+ *
105
+ * // Toggle bullet list on the block at cursor
106
+ * engine.exec(ListCommands.TOGGLE_BULLET);
107
+ *
108
+ * // Indent the current list item
109
+ * engine.exec(ListCommands.INDENT);
110
+ * ```
111
+ */
112
+ export function listPlugin() {
113
+ return {
114
+ id: 'block-list-item',
115
+ init(ctx) {
116
+ // ---------------------------------------------------------------
117
+ // Block type registration
118
+ // ---------------------------------------------------------------
119
+ ctx.registerBlockType('list-item', {
120
+ defaultAttrs: { listStyle: 'bullet', depth: 0 },
121
+ validate: (attrs) => {
122
+ return ((attrs.listStyle === 'bullet' || attrs.listStyle === 'ordered') &&
123
+ typeof attrs.depth === 'number' &&
124
+ attrs.depth >= 0);
125
+ },
126
+ });
127
+ // ---------------------------------------------------------------
128
+ // toggleBulletList command
129
+ // ---------------------------------------------------------------
130
+ ctx.registerCommand(ListCommands.TOGGLE_BULLET, {
131
+ execute(engine) {
132
+ const block = getBlockAtCursor(engine);
133
+ if (isListItem(block, 'bullet')) {
134
+ engine.dispatch(revertToText(block.id));
135
+ }
136
+ else {
137
+ engine.dispatch(setListItem(block.id, 'bullet'));
138
+ }
139
+ },
140
+ canExecute(_engine) {
141
+ return true;
142
+ },
143
+ isActive(engine) {
144
+ const block = getBlockAtCursor(engine);
145
+ return isListItem(block, 'bullet');
146
+ },
147
+ });
148
+ // ---------------------------------------------------------------
149
+ // toggleOrderedList command
150
+ // ---------------------------------------------------------------
151
+ ctx.registerCommand(ListCommands.TOGGLE_ORDERED, {
152
+ execute(engine) {
153
+ const block = getBlockAtCursor(engine);
154
+ if (isListItem(block, 'ordered')) {
155
+ engine.dispatch(revertToText(block.id));
156
+ }
157
+ else {
158
+ engine.dispatch(setListItem(block.id, 'ordered'));
159
+ }
160
+ },
161
+ canExecute(_engine) {
162
+ return true;
163
+ },
164
+ isActive(engine) {
165
+ const block = getBlockAtCursor(engine);
166
+ return isListItem(block, 'ordered');
167
+ },
168
+ });
169
+ // ---------------------------------------------------------------
170
+ // indentList command
171
+ // ---------------------------------------------------------------
172
+ ctx.registerCommand(ListCommands.INDENT, {
173
+ execute(engine) {
174
+ const block = getBlockAtCursor(engine);
175
+ if (!isListItem(block))
176
+ return;
177
+ const currentDepth = getDepth(block);
178
+ if (currentDepth >= MAX_DEPTH)
179
+ return;
180
+ engine.dispatch({
181
+ type: 'set_block_attrs',
182
+ blockId: block.id,
183
+ attrs: { depth: currentDepth + 1 },
184
+ });
185
+ },
186
+ canExecute(engine) {
187
+ const block = getBlockAtCursor(engine);
188
+ return isListItem(block) && getDepth(block) < MAX_DEPTH;
189
+ },
190
+ });
191
+ // ---------------------------------------------------------------
192
+ // outdentList command
193
+ // ---------------------------------------------------------------
194
+ ctx.registerCommand(ListCommands.OUTDENT, {
195
+ execute(engine) {
196
+ const block = getBlockAtCursor(engine);
197
+ if (!isListItem(block))
198
+ return;
199
+ const currentDepth = getDepth(block);
200
+ if (currentDepth > 0) {
201
+ engine.dispatch({
202
+ type: 'set_block_attrs',
203
+ blockId: block.id,
204
+ attrs: { depth: currentDepth - 1 },
205
+ });
206
+ }
207
+ else {
208
+ // Depth is 0 -- revert to plain text
209
+ engine.dispatch(revertToText(block.id));
210
+ }
211
+ },
212
+ canExecute(engine) {
213
+ const block = getBlockAtCursor(engine);
214
+ return isListItem(block);
215
+ },
216
+ });
217
+ // ---------------------------------------------------------------
218
+ // Input rules: `- ` / `* ` -> bullet list, `1. ` -> ordered list
219
+ // ---------------------------------------------------------------
220
+ // Bullet list: `- ` or `* ` at block start
221
+ ctx.registerInputRule({
222
+ pattern: /^[-*] $/,
223
+ exclusive: true,
224
+ handler(engine, _match, blockId) {
225
+ const blockStart = getBlockStartOffset(engine.state.doc, blockId);
226
+ engine.dispatch([
227
+ { type: 'delete_text', offset: blockStart, count: 2 },
228
+ { type: 'set_block_type', blockId, blockType: 'list-item' },
229
+ { type: 'set_block_attrs', blockId, attrs: { listStyle: 'bullet', depth: 0 } },
230
+ ]);
231
+ },
232
+ });
233
+ // Ordered list: `1. ` at block start
234
+ ctx.registerInputRule({
235
+ pattern: /^1\. $/,
236
+ exclusive: true,
237
+ handler(engine, _match, blockId) {
238
+ const blockStart = getBlockStartOffset(engine.state.doc, blockId);
239
+ engine.dispatch([
240
+ { type: 'delete_text', offset: blockStart, count: 3 },
241
+ { type: 'set_block_type', blockId, blockType: 'list-item' },
242
+ { type: 'set_block_attrs', blockId, attrs: { listStyle: 'ordered', depth: 0 } },
243
+ ]);
244
+ },
245
+ });
246
+ // ---------------------------------------------------------------
247
+ // Keyboard shortcuts: Tab / Shift+Tab for indent/outdent
248
+ // ---------------------------------------------------------------
249
+ ctx.registerShortcut({ key: 'Tab' }, ListCommands.INDENT);
250
+ ctx.registerShortcut({ key: 'Tab', shift: true }, ListCommands.OUTDENT);
251
+ },
252
+ // ---------------------------------------------------------------
253
+ // beforeApply: Enter on empty list item → outdent or revert to text
254
+ // ---------------------------------------------------------------
255
+ beforeApply(ops, state) {
256
+ // Track block IDs from stripped split_block ops so we can filter
257
+ // orphan ops referencing those IDs.
258
+ const removedBlockIds = new Set();
259
+ const result = ops.flatMap((op) => {
260
+ if (op.type !== 'split_block')
261
+ return [op];
262
+ // Resolve the split offset to find which block it targets
263
+ let blockIndex;
264
+ try {
265
+ const resolved = resolve(state.doc, op.offset);
266
+ blockIndex = resolved.blockIndex;
267
+ }
268
+ catch {
269
+ return [op]; // Invalid offset — let core handle the error
270
+ }
271
+ const block = state.doc.blocks[blockIndex];
272
+ if (!block || !isListItem(block))
273
+ return [op];
274
+ // Only intercept if the block has no text content
275
+ if (blockTextLength(block) !== 0)
276
+ return [op];
277
+ // Track the removed block ID (from the split_block's newBlockId)
278
+ if (op.newBlockId) {
279
+ removedBlockIds.add(op.newBlockId);
280
+ }
281
+ const depth = getDepth(block);
282
+ if (depth > 0) {
283
+ // Outdent: decrease depth by 1
284
+ return [
285
+ {
286
+ type: 'set_block_attrs',
287
+ blockId: block.id,
288
+ attrs: { depth: depth - 1 },
289
+ },
290
+ ];
291
+ }
292
+ else {
293
+ // Depth 0: revert to plain text
294
+ return revertToText(block.id);
295
+ }
296
+ });
297
+ // Filter out orphan ops referencing removed block IDs
298
+ if (removedBlockIds.size === 0)
299
+ return result;
300
+ return result.filter((op) => {
301
+ if ('blockId' in op && typeof op.blockId === 'string') {
302
+ return !removedBlockIds.has(op.blockId);
303
+ }
304
+ return true;
305
+ });
306
+ },
307
+ };
308
+ }
309
+ //# sourceMappingURL=list-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-plugin.js","sourceRoot":"","sources":["../../src/plugins/list-plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Shared utilities for inline mark plugins.
3
+ *
4
+ * Provides `createToggleMarkCommand()` for building mark toggle commands,
5
+ * `toggleMark()` for the toggle logic, and `isMarkActiveAtSelection()`
6
+ * for querying active mark state.
7
+ *
8
+ * @module
9
+ */
10
+ import type { IEditorEngine, CommandDescriptor } from '@rtif-sdk/engine';
11
+ import type { Document } from '@rtif-sdk/core';
12
+ /**
13
+ * Create a `CommandDescriptor` for toggling a mark type on/off.
14
+ *
15
+ * When the cursor is collapsed, toggles a pending mark.
16
+ * When a selection exists, applies or removes the mark via `set_span_marks`.
17
+ *
18
+ * @param markType - The mark type string (e.g., "bold", "italic")
19
+ * @param markValue - The mark value to apply (default: `true`)
20
+ * @returns A `CommandDescriptor` with execute, canExecute, and isActive
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * const boldCommand = createToggleMarkCommand('bold');
25
+ * registries.registerCommand('toggleMark:bold', boldCommand);
26
+ * ```
27
+ */
28
+ export declare function createToggleMarkCommand(markType: string, markValue?: unknown): CommandDescriptor;
29
+ /**
30
+ * Toggle a mark on the current selection or as a pending mark.
31
+ *
32
+ * If the cursor is collapsed, toggles the mark as a pending mark (the next
33
+ * typed text will have or not have the mark). If a range is selected,
34
+ * dispatches `set_span_marks` to apply or remove the mark.
35
+ *
36
+ * @param engine - The editor engine instance
37
+ * @param markType - The mark type string (e.g., "bold")
38
+ * @param markValue - The value to apply (default: `true`)
39
+ * @returns `true` if the toggle was performed
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * toggleMark(engine, 'bold');
44
+ * ```
45
+ */
46
+ export declare function toggleMark(engine: IEditorEngine, markType: string, markValue?: unknown): boolean;
47
+ /**
48
+ * Check whether a mark type is active at the current selection.
49
+ *
50
+ * For collapsed cursors, checks the marks at the cursor offset and
51
+ * pending marks. For range selections, checks if the mark is present
52
+ * across the entire range (`common` marks).
53
+ *
54
+ * @param engine - The editor engine instance
55
+ * @param markType - The mark type to check (e.g., "bold")
56
+ * @returns `true` if the mark is active at the selection
57
+ *
58
+ * @example
59
+ * ```ts
60
+ * if (isMarkActiveAtSelection(engine, 'bold')) {
61
+ * // Bold button should show as pressed
62
+ * }
63
+ * ```
64
+ */
65
+ export declare function isMarkActiveAtSelection(engine: IEditorEngine, markType: string): boolean;
66
+ /**
67
+ * Create a `CommandDescriptor` that sets a parameterized mark value.
68
+ *
69
+ * On a collapsed cursor, sets the mark as a pending mark so the next typed
70
+ * text inherits the value. On a range selection, dispatches `set_span_marks`
71
+ * to apply the mark to the selected text.
72
+ *
73
+ * @param markType - The mark type string (e.g., "color", "fontSize")
74
+ * @param extractValue - A function that extracts the mark value from the command payload
75
+ * @returns A `CommandDescriptor` with execute and isActive
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * const cmd = createSetMarkCommand('color', (p) => (p as { color: string }).color);
80
+ * registries.registerCommand('setTextColor', cmd);
81
+ * ```
82
+ */
83
+ export declare function createSetMarkCommand(markType: string, extractValue: (payload: unknown) => unknown): CommandDescriptor;
84
+ /**
85
+ * Create a `CommandDescriptor` that removes a mark.
86
+ *
87
+ * On a collapsed cursor, sets the pending mark to `null` so the next typed
88
+ * text will not have the mark. On a range selection, dispatches `set_span_marks`
89
+ * with `null` to remove the mark from the selected text.
90
+ *
91
+ * @param markType - The mark type string (e.g., "color", "fontSize")
92
+ * @returns A `CommandDescriptor` with execute and canExecute
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * const cmd = createRemoveMarkCommand('color');
97
+ * registries.registerCommand('removeTextColor', cmd);
98
+ * ```
99
+ */
100
+ export declare function createRemoveMarkCommand(markType: string): CommandDescriptor;
101
+ /**
102
+ * Find the absolute document range of a contiguous mark span containing
103
+ * the given offset.
104
+ *
105
+ * Scans the spans of the block containing the offset to find the contiguous
106
+ * range of spans that share the same mark key (with a non-null object value).
107
+ *
108
+ * @param doc - The document to search
109
+ * @param offset - The absolute offset to find the mark at
110
+ * @param markKey - The mark key to search for (e.g., 'link', 'mention')
111
+ * @returns The absolute offset and count of the mark range, or null if no mark at offset
112
+ *
113
+ * @example
114
+ * ```ts
115
+ * const range = findContiguousMarkRange(doc, 5, 'link');
116
+ * if (range) {
117
+ * engine.dispatch({ type: 'set_span_marks', offset: range.offset, count: range.count, marks: { link: null } });
118
+ * }
119
+ * ```
120
+ */
121
+ export declare function findContiguousMarkRange(doc: Document, offset: number, markKey: string): {
122
+ offset: number;
123
+ count: number;
124
+ } | null;
125
+ /**
126
+ * Adjust an offset that falls inside an atomic mark range to the nearest boundary.
127
+ *
128
+ * When arrow keys or clicks land the cursor inside a `contenteditable="false"`
129
+ * span (e.g., an @mention), this function snaps the offset to the start or end
130
+ * of the atomic range based on the movement direction.
131
+ *
132
+ * Iterates up to `MAX_ITERATIONS` to handle adjacent atomic marks (e.g., two
133
+ * mentions side by side) — each iteration snaps to a boundary, then re-checks
134
+ * whether the boundary itself is inside another atomic range.
135
+ *
136
+ * @param offset - The absolute document offset to adjust
137
+ * @param direction - Which direction to snap: 'forward' snaps to end, 'backward' snaps to start, 'nearest' picks closer boundary
138
+ * @param findAtomicRange - Function that returns the atomic mark range at an offset, or null
139
+ * @returns The adjusted offset (unchanged if not inside an atomic range)
140
+ *
141
+ * @example
142
+ * ```ts
143
+ * // Mention "@alice" spans offsets 5..10
144
+ * const find = (o: number) =>
145
+ * o > 5 && o < 10 ? { offset: 5, count: 5 } : null;
146
+ * adjustOffsetAroundAtomicMarks(7, 'forward', find); // => 10
147
+ * adjustOffsetAroundAtomicMarks(7, 'backward', find); // => 5
148
+ * ```
149
+ */
150
+ export declare function adjustOffsetAroundAtomicMarks(offset: number, direction: 'forward' | 'backward' | 'nearest', findAtomicRange: (offset: number) => {
151
+ offset: number;
152
+ count: number;
153
+ } | null): number;
154
+ /**
155
+ * Adjust an absolute offset so it does not land inside an atomic block.
156
+ *
157
+ * When the cursor resolves to a block whose type is atomic (e.g., HR, image,
158
+ * embed), snap it to the nearest non-atomic block boundary based on the
159
+ * inferred movement direction.
160
+ *
161
+ * @param doc - The document
162
+ * @param offset - The absolute offset to adjust
163
+ * @param direction - Movement direction for choosing which boundary to snap to
164
+ * @param isAtomicBlock - Predicate that returns true for atomic block types
165
+ * @returns The adjusted offset, or the original if no adjustment needed
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * const adjusted = adjustOffsetAroundAtomicBlocks(doc, 6, 'forward', (t) => t === 'hr');
170
+ * ```
171
+ */
172
+ export declare function adjustOffsetAroundAtomicBlocks(doc: Document, offset: number, direction: 'forward' | 'backward' | 'nearest', isAtomicBlock: (blockType: string) => boolean): number;
173
+ //# sourceMappingURL=mark-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mark-utils.d.ts","sourceRoot":"","sources":["../../src/plugins/mark-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,QAAQ,EAAe,MAAM,gBAAgB,CAAC;AAG5D;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,OAAc,GACxB,iBAAiB,CAYnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,EAChB,SAAS,GAAE,OAAc,GACxB,OAAO,CAuBT;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAoBT;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,GAC1C,iBAAiB,CA0BnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,GACf,iBAAiB,CAyBnB;AAMD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAmB1C;AA0ED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,EAC7C,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAC5E,MAAM,CA2BR;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,8BAA8B,CAC5C,GAAG,EAAE,QAAQ,EACb,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,EAC7C,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,GAC5C,MAAM,CAoDR"}