@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.
- package/LICENSE +21 -0
- package/README.md +67 -0
- package/dist/block-drag-handler.d.ts +189 -0
- package/dist/block-drag-handler.d.ts.map +1 -0
- package/dist/block-drag-handler.js +745 -0
- package/dist/block-drag-handler.js.map +1 -0
- package/dist/block-renderer.d.ts +402 -0
- package/dist/block-renderer.d.ts.map +1 -0
- package/dist/block-renderer.js +424 -0
- package/dist/block-renderer.js.map +1 -0
- package/dist/clipboard.d.ts +178 -0
- package/dist/clipboard.d.ts.map +1 -0
- package/dist/clipboard.js +432 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/command-bus.d.ts +113 -0
- package/dist/command-bus.d.ts.map +1 -0
- package/dist/command-bus.js +70 -0
- package/dist/command-bus.js.map +1 -0
- package/dist/composition.d.ts +220 -0
- package/dist/composition.d.ts.map +1 -0
- package/dist/composition.js +271 -0
- package/dist/composition.js.map +1 -0
- package/dist/content-extraction.d.ts +69 -0
- package/dist/content-extraction.d.ts.map +1 -0
- package/dist/content-extraction.js +228 -0
- package/dist/content-extraction.js.map +1 -0
- package/dist/content-handler-file.d.ts +40 -0
- package/dist/content-handler-file.d.ts.map +1 -0
- package/dist/content-handler-file.js +91 -0
- package/dist/content-handler-file.js.map +1 -0
- package/dist/content-handler-image.d.ts +82 -0
- package/dist/content-handler-image.d.ts.map +1 -0
- package/dist/content-handler-image.js +120 -0
- package/dist/content-handler-image.js.map +1 -0
- package/dist/content-handler-url.d.ts +129 -0
- package/dist/content-handler-url.d.ts.map +1 -0
- package/dist/content-handler-url.js +244 -0
- package/dist/content-handler-url.js.map +1 -0
- package/dist/content-handlers.d.ts +67 -0
- package/dist/content-handlers.d.ts.map +1 -0
- package/dist/content-handlers.js +263 -0
- package/dist/content-handlers.js.map +1 -0
- package/dist/content-pipeline.d.ts +383 -0
- package/dist/content-pipeline.d.ts.map +1 -0
- package/dist/content-pipeline.js +232 -0
- package/dist/content-pipeline.js.map +1 -0
- package/dist/cursor-nav.d.ts +149 -0
- package/dist/cursor-nav.d.ts.map +1 -0
- package/dist/cursor-nav.js +230 -0
- package/dist/cursor-nav.js.map +1 -0
- package/dist/cursor-rect.d.ts +65 -0
- package/dist/cursor-rect.d.ts.map +1 -0
- package/dist/cursor-rect.js +98 -0
- package/dist/cursor-rect.js.map +1 -0
- package/dist/drop-indicator.d.ts +108 -0
- package/dist/drop-indicator.d.ts.map +1 -0
- package/dist/drop-indicator.js +236 -0
- package/dist/drop-indicator.js.map +1 -0
- package/dist/editor.d.ts +41 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +710 -0
- package/dist/editor.js.map +1 -0
- package/dist/floating-toolbar.d.ts +93 -0
- package/dist/floating-toolbar.d.ts.map +1 -0
- package/dist/floating-toolbar.js +159 -0
- package/dist/floating-toolbar.js.map +1 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +119 -0
- package/dist/index.js.map +1 -0
- package/dist/input-bridge.d.ts +273 -0
- package/dist/input-bridge.d.ts.map +1 -0
- package/dist/input-bridge.js +884 -0
- package/dist/input-bridge.js.map +1 -0
- package/dist/link-popover.d.ts +38 -0
- package/dist/link-popover.d.ts.map +1 -0
- package/dist/link-popover.js +278 -0
- package/dist/link-popover.js.map +1 -0
- package/dist/mark-renderer.d.ts +275 -0
- package/dist/mark-renderer.d.ts.map +1 -0
- package/dist/mark-renderer.js +210 -0
- package/dist/mark-renderer.js.map +1 -0
- package/dist/perf.d.ts +145 -0
- package/dist/perf.d.ts.map +1 -0
- package/dist/perf.js +260 -0
- package/dist/perf.js.map +1 -0
- package/dist/plugin-kit.d.ts +265 -0
- package/dist/plugin-kit.d.ts.map +1 -0
- package/dist/plugin-kit.js +234 -0
- package/dist/plugin-kit.js.map +1 -0
- package/dist/plugins/alignment-plugin.d.ts +68 -0
- package/dist/plugins/alignment-plugin.d.ts.map +1 -0
- package/dist/plugins/alignment-plugin.js +98 -0
- package/dist/plugins/alignment-plugin.js.map +1 -0
- package/dist/plugins/block-utils.d.ts +113 -0
- package/dist/plugins/block-utils.d.ts.map +1 -0
- package/dist/plugins/block-utils.js +191 -0
- package/dist/plugins/block-utils.js.map +1 -0
- package/dist/plugins/blockquote-plugin.d.ts +39 -0
- package/dist/plugins/blockquote-plugin.d.ts.map +1 -0
- package/dist/plugins/blockquote-plugin.js +88 -0
- package/dist/plugins/blockquote-plugin.js.map +1 -0
- package/dist/plugins/bold-plugin.d.ts +37 -0
- package/dist/plugins/bold-plugin.d.ts.map +1 -0
- package/dist/plugins/bold-plugin.js +48 -0
- package/dist/plugins/bold-plugin.js.map +1 -0
- package/dist/plugins/callout-plugin.d.ts +100 -0
- package/dist/plugins/callout-plugin.d.ts.map +1 -0
- package/dist/plugins/callout-plugin.js +200 -0
- package/dist/plugins/callout-plugin.js.map +1 -0
- package/dist/plugins/code-block-plugin.d.ts +62 -0
- package/dist/plugins/code-block-plugin.d.ts.map +1 -0
- package/dist/plugins/code-block-plugin.js +176 -0
- package/dist/plugins/code-block-plugin.js.map +1 -0
- package/dist/plugins/code-plugin.d.ts +37 -0
- package/dist/plugins/code-plugin.d.ts.map +1 -0
- package/dist/plugins/code-plugin.js +48 -0
- package/dist/plugins/code-plugin.js.map +1 -0
- package/dist/plugins/embed-plugin.d.ts +90 -0
- package/dist/plugins/embed-plugin.d.ts.map +1 -0
- package/dist/plugins/embed-plugin.js +147 -0
- package/dist/plugins/embed-plugin.js.map +1 -0
- package/dist/plugins/font-family-plugin.d.ts +58 -0
- package/dist/plugins/font-family-plugin.d.ts.map +1 -0
- package/dist/plugins/font-family-plugin.js +57 -0
- package/dist/plugins/font-family-plugin.js.map +1 -0
- package/dist/plugins/font-size-plugin.d.ts +57 -0
- package/dist/plugins/font-size-plugin.d.ts.map +1 -0
- package/dist/plugins/font-size-plugin.js +56 -0
- package/dist/plugins/font-size-plugin.js.map +1 -0
- package/dist/plugins/heading-plugin.d.ts +52 -0
- package/dist/plugins/heading-plugin.d.ts.map +1 -0
- package/dist/plugins/heading-plugin.js +114 -0
- package/dist/plugins/heading-plugin.js.map +1 -0
- package/dist/plugins/hr-plugin.d.ts +33 -0
- package/dist/plugins/hr-plugin.d.ts.map +1 -0
- package/dist/plugins/hr-plugin.js +75 -0
- package/dist/plugins/hr-plugin.js.map +1 -0
- package/dist/plugins/image-plugin.d.ts +115 -0
- package/dist/plugins/image-plugin.d.ts.map +1 -0
- package/dist/plugins/image-plugin.js +199 -0
- package/dist/plugins/image-plugin.js.map +1 -0
- package/dist/plugins/indent-plugin.d.ts +62 -0
- package/dist/plugins/indent-plugin.d.ts.map +1 -0
- package/dist/plugins/indent-plugin.js +128 -0
- package/dist/plugins/indent-plugin.js.map +1 -0
- package/dist/plugins/index.d.ts +45 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +42 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/italic-plugin.d.ts +37 -0
- package/dist/plugins/italic-plugin.d.ts.map +1 -0
- package/dist/plugins/italic-plugin.js +48 -0
- package/dist/plugins/italic-plugin.js.map +1 -0
- package/dist/plugins/link-plugin.d.ts +129 -0
- package/dist/plugins/link-plugin.d.ts.map +1 -0
- package/dist/plugins/link-plugin.js +212 -0
- package/dist/plugins/link-plugin.js.map +1 -0
- package/dist/plugins/list-plugin.d.ts +53 -0
- package/dist/plugins/list-plugin.d.ts.map +1 -0
- package/dist/plugins/list-plugin.js +309 -0
- package/dist/plugins/list-plugin.js.map +1 -0
- package/dist/plugins/mark-utils.d.ts +173 -0
- package/dist/plugins/mark-utils.d.ts.map +1 -0
- package/dist/plugins/mark-utils.js +425 -0
- package/dist/plugins/mark-utils.js.map +1 -0
- package/dist/plugins/mention-plugin.d.ts +191 -0
- package/dist/plugins/mention-plugin.d.ts.map +1 -0
- package/dist/plugins/mention-plugin.js +295 -0
- package/dist/plugins/mention-plugin.js.map +1 -0
- package/dist/plugins/strikethrough-plugin.d.ts +37 -0
- package/dist/plugins/strikethrough-plugin.d.ts.map +1 -0
- package/dist/plugins/strikethrough-plugin.js +48 -0
- package/dist/plugins/strikethrough-plugin.js.map +1 -0
- package/dist/plugins/text-color-plugin.d.ts +57 -0
- package/dist/plugins/text-color-plugin.d.ts.map +1 -0
- package/dist/plugins/text-color-plugin.js +56 -0
- package/dist/plugins/text-color-plugin.js.map +1 -0
- package/dist/plugins/underline-plugin.d.ts +37 -0
- package/dist/plugins/underline-plugin.d.ts.map +1 -0
- package/dist/plugins/underline-plugin.js +48 -0
- package/dist/plugins/underline-plugin.js.map +1 -0
- package/dist/presets.d.ts +95 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +159 -0
- package/dist/presets.js.map +1 -0
- package/dist/renderer.d.ts +125 -0
- package/dist/renderer.d.ts.map +1 -0
- package/dist/renderer.js +415 -0
- package/dist/renderer.js.map +1 -0
- package/dist/scroll-to-cursor.d.ts +25 -0
- package/dist/scroll-to-cursor.d.ts.map +1 -0
- package/dist/scroll-to-cursor.js +59 -0
- package/dist/scroll-to-cursor.js.map +1 -0
- package/dist/selection-sync.d.ts +159 -0
- package/dist/selection-sync.d.ts.map +1 -0
- package/dist/selection-sync.js +527 -0
- package/dist/selection-sync.js.map +1 -0
- package/dist/shortcut-handler.d.ts +98 -0
- package/dist/shortcut-handler.d.ts.map +1 -0
- package/dist/shortcut-handler.js +155 -0
- package/dist/shortcut-handler.js.map +1 -0
- package/dist/toolbar.d.ts +103 -0
- package/dist/toolbar.d.ts.map +1 -0
- package/dist/toolbar.js +134 -0
- package/dist/toolbar.js.map +1 -0
- package/dist/trigger-manager.d.ts +205 -0
- package/dist/trigger-manager.d.ts.map +1 -0
- package/dist/trigger-manager.js +466 -0
- package/dist/trigger-manager.js.map +1 -0
- package/dist/types.d.ts +216 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- 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"}
|