@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,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embed block type plugin — registers the `embed` block type and
|
|
3
|
+
* `insertEmbed` / `removeEmbed` commands for embedding external content
|
|
4
|
+
* (YouTube, Twitter/X, Vimeo, etc.) as atomic, non-editable blocks.
|
|
5
|
+
*
|
|
6
|
+
* Embed blocks are atomic — they carry no meaningful text content.
|
|
7
|
+
* Their visual representation is determined by the block renderer layer
|
|
8
|
+
* (iframe, provider-specific HTML, etc.) based on the `url` and
|
|
9
|
+
* `embedType` attributes.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { blockTextLength } from '@rtif-sdk/core';
|
|
14
|
+
import { getBlockAtCursor, getBlockStartOffset } from './block-utils.js';
|
|
15
|
+
/**
|
|
16
|
+
* Command name constants for the embed plugin.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* engine.exec(EmbedCommands.INSERT, { url: 'https://youtube.com/...' });
|
|
21
|
+
* engine.exec(EmbedCommands.REMOVE, { blockId: 'b3' });
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export const EmbedCommands = {
|
|
25
|
+
INSERT: 'insertEmbed',
|
|
26
|
+
REMOVE: 'removeEmbed',
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Create the embed block type plugin.
|
|
30
|
+
*
|
|
31
|
+
* Registers:
|
|
32
|
+
* - Block type: `embed` (attrs must include `url` as a non-empty string)
|
|
33
|
+
* - Command: `insertEmbed` — inserts a new embed block after the current block
|
|
34
|
+
* - Command: `removeEmbed` — reverts an embed block to plain text, clearing embed attrs
|
|
35
|
+
*
|
|
36
|
+
* @returns A plugin instance ready for `engine.use()`
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* const engine = createEngine(initialDoc);
|
|
41
|
+
* engine.use(embedPlugin());
|
|
42
|
+
*
|
|
43
|
+
* // Insert a YouTube embed after the current block
|
|
44
|
+
* engine.exec(EmbedCommands.INSERT, {
|
|
45
|
+
* url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
|
|
46
|
+
* type: 'video',
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* // Remove the embed, reverting to a plain text block
|
|
50
|
+
* engine.exec(EmbedCommands.REMOVE, { blockId: 'b2' });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export function embedPlugin() {
|
|
54
|
+
return {
|
|
55
|
+
id: 'block-embed',
|
|
56
|
+
init(ctx) {
|
|
57
|
+
// ---------------------------------------------------------------
|
|
58
|
+
// Block type registration
|
|
59
|
+
// ---------------------------------------------------------------
|
|
60
|
+
ctx.registerBlockType('embed', {
|
|
61
|
+
validate: (attrs) => {
|
|
62
|
+
return typeof attrs.url === 'string' && attrs.url.length > 0;
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
// ---------------------------------------------------------------
|
|
66
|
+
// insertEmbed command
|
|
67
|
+
// ---------------------------------------------------------------
|
|
68
|
+
ctx.registerCommand(EmbedCommands.INSERT, {
|
|
69
|
+
/**
|
|
70
|
+
* Insert a new embed block after the block at the cursor.
|
|
71
|
+
*
|
|
72
|
+
* Implementation:
|
|
73
|
+
* 1. Get the current block and compute its end offset.
|
|
74
|
+
* 2. `split_block` at the end offset to create a new empty block.
|
|
75
|
+
* 3. `set_block_type` on the new block to `'embed'`.
|
|
76
|
+
* 4. `set_block_attrs` on the new block with `{ url, embedType }`.
|
|
77
|
+
*
|
|
78
|
+
* @param engine - The editor engine instance
|
|
79
|
+
* @param payload - {@link InsertEmbedPayload} with `url` and optional `type`
|
|
80
|
+
*/
|
|
81
|
+
execute(engine, payload) {
|
|
82
|
+
const p = payload;
|
|
83
|
+
if (!p || typeof p.url !== 'string' || p.url.length === 0)
|
|
84
|
+
return;
|
|
85
|
+
const block = getBlockAtCursor(engine);
|
|
86
|
+
const blockStart = getBlockStartOffset(engine.state.doc, block.id);
|
|
87
|
+
const blockLen = blockTextLength(block);
|
|
88
|
+
const splitOffset = blockStart + blockLen;
|
|
89
|
+
const newBlockId = `${block.id}_embed`;
|
|
90
|
+
const embedType = p.type ?? 'generic';
|
|
91
|
+
const ops = [
|
|
92
|
+
{ type: 'split_block', offset: splitOffset, newBlockId },
|
|
93
|
+
{ type: 'set_block_type', blockId: newBlockId, blockType: 'embed' },
|
|
94
|
+
{
|
|
95
|
+
type: 'set_block_attrs',
|
|
96
|
+
blockId: newBlockId,
|
|
97
|
+
attrs: { url: p.url, embedType },
|
|
98
|
+
},
|
|
99
|
+
];
|
|
100
|
+
engine.dispatch(ops);
|
|
101
|
+
},
|
|
102
|
+
canExecute(_engine) {
|
|
103
|
+
return true;
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
// ---------------------------------------------------------------
|
|
107
|
+
// removeEmbed command
|
|
108
|
+
// ---------------------------------------------------------------
|
|
109
|
+
ctx.registerCommand(EmbedCommands.REMOVE, {
|
|
110
|
+
/**
|
|
111
|
+
* Remove an embed block, reverting it to a plain text block.
|
|
112
|
+
*
|
|
113
|
+
* Sets the block's type to `'text'` and clears the embed-specific
|
|
114
|
+
* attrs (`url` and `embedType`).
|
|
115
|
+
*
|
|
116
|
+
* @param engine - The editor engine instance
|
|
117
|
+
* @param payload - {@link RemoveEmbedPayload} with `blockId`
|
|
118
|
+
*/
|
|
119
|
+
execute(engine, payload) {
|
|
120
|
+
const p = payload;
|
|
121
|
+
if (!p || typeof p.blockId !== 'string')
|
|
122
|
+
return;
|
|
123
|
+
const block = engine.state.doc.blocks.find((b) => b.id === p.blockId);
|
|
124
|
+
if (!block || block.type !== 'embed')
|
|
125
|
+
return;
|
|
126
|
+
const ops = [
|
|
127
|
+
{ type: 'set_block_type', blockId: p.blockId, blockType: 'text' },
|
|
128
|
+
{
|
|
129
|
+
type: 'set_block_attrs',
|
|
130
|
+
blockId: p.blockId,
|
|
131
|
+
attrs: { url: null, embedType: null },
|
|
132
|
+
},
|
|
133
|
+
];
|
|
134
|
+
engine.dispatch(ops);
|
|
135
|
+
},
|
|
136
|
+
canExecute(engine, payload) {
|
|
137
|
+
const p = payload;
|
|
138
|
+
if (!p || typeof p.blockId !== 'string')
|
|
139
|
+
return false;
|
|
140
|
+
const block = engine.state.doc.blocks.find((b) => b.id === p.blockId);
|
|
141
|
+
return block !== undefined && block.type === 'embed';
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=embed-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embed-plugin.js","sourceRoot":"","sources":["../../src/plugins/embed-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Font family mark plugin — registers the `fontFamily` mark type,
|
|
3
|
+
* `setFontFamily` and `removeFontFamily` commands.
|
|
4
|
+
*
|
|
5
|
+
* This is a parameterized mark plugin: the mark value is a non-empty string
|
|
6
|
+
* representing a CSS font-family value (e.g., `"Arial"`, `"monospace"`,
|
|
7
|
+
* `"'Courier New', monospace"`).
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import type { Plugin } from '@rtif-sdk/engine';
|
|
12
|
+
/**
|
|
13
|
+
* Command name constants for the font family plugin.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* engine.exec(FontFamilyCommands.SET, { family: 'Georgia' });
|
|
18
|
+
* engine.exec(FontFamilyCommands.REMOVE);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare const FontFamilyCommands: {
|
|
22
|
+
readonly SET: "setFontFamily";
|
|
23
|
+
readonly REMOVE: "removeFontFamily";
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Payload for the `setFontFamily` command.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* engine.exec('setFontFamily', { family: 'Arial' });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export interface SetFontFamilyPayload {
|
|
34
|
+
/** The CSS font-family value to apply */
|
|
35
|
+
readonly family: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create the font family mark plugin.
|
|
39
|
+
*
|
|
40
|
+
* Registers:
|
|
41
|
+
* - Mark type: `fontFamily` (value must be a non-empty string)
|
|
42
|
+
* - Command: `setFontFamily` — apply font family to selection or set pending mark
|
|
43
|
+
* - Command: `removeFontFamily` — remove font family from selection or set pending mark null
|
|
44
|
+
*
|
|
45
|
+
* No keyboard shortcuts are registered.
|
|
46
|
+
*
|
|
47
|
+
* @returns A plugin instance ready for `engine.use()`
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* const engine = createEngine(initialDoc);
|
|
52
|
+
* engine.use(fontFamilyPlugin());
|
|
53
|
+
* engine.exec(FontFamilyCommands.SET, { family: 'Georgia' });
|
|
54
|
+
* engine.exec(FontFamilyCommands.REMOVE);
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function fontFamilyPlugin(): Plugin;
|
|
58
|
+
//# sourceMappingURL=font-family-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font-family-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/font-family-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG/C;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAgBzC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Font family mark plugin — registers the `fontFamily` mark type,
|
|
3
|
+
* `setFontFamily` and `removeFontFamily` commands.
|
|
4
|
+
*
|
|
5
|
+
* This is a parameterized mark plugin: the mark value is a non-empty string
|
|
6
|
+
* representing a CSS font-family value (e.g., `"Arial"`, `"monospace"`,
|
|
7
|
+
* `"'Courier New', monospace"`).
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
import { createSetMarkCommand, createRemoveMarkCommand } from './mark-utils.js';
|
|
12
|
+
/**
|
|
13
|
+
* Command name constants for the font family plugin.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* engine.exec(FontFamilyCommands.SET, { family: 'Georgia' });
|
|
18
|
+
* engine.exec(FontFamilyCommands.REMOVE);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export const FontFamilyCommands = {
|
|
22
|
+
SET: 'setFontFamily',
|
|
23
|
+
REMOVE: 'removeFontFamily',
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Create the font family mark plugin.
|
|
27
|
+
*
|
|
28
|
+
* Registers:
|
|
29
|
+
* - Mark type: `fontFamily` (value must be a non-empty string)
|
|
30
|
+
* - Command: `setFontFamily` — apply font family to selection or set pending mark
|
|
31
|
+
* - Command: `removeFontFamily` — remove font family from selection or set pending mark null
|
|
32
|
+
*
|
|
33
|
+
* No keyboard shortcuts are registered.
|
|
34
|
+
*
|
|
35
|
+
* @returns A plugin instance ready for `engine.use()`
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* ```ts
|
|
39
|
+
* const engine = createEngine(initialDoc);
|
|
40
|
+
* engine.use(fontFamilyPlugin());
|
|
41
|
+
* engine.exec(FontFamilyCommands.SET, { family: 'Georgia' });
|
|
42
|
+
* engine.exec(FontFamilyCommands.REMOVE);
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function fontFamilyPlugin() {
|
|
46
|
+
return {
|
|
47
|
+
id: 'mark-fontFamily',
|
|
48
|
+
init(ctx) {
|
|
49
|
+
ctx.registerMarkType('fontFamily', {
|
|
50
|
+
validate: (value) => typeof value === 'string' && value.length > 0,
|
|
51
|
+
});
|
|
52
|
+
ctx.registerCommand(FontFamilyCommands.SET, createSetMarkCommand('fontFamily', (p) => p.family));
|
|
53
|
+
ctx.registerCommand(FontFamilyCommands.REMOVE, createRemoveMarkCommand('fontFamily'));
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=font-family-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font-family-plugin.js","sourceRoot":"","sources":["../../src/plugins/font-family-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAEhF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,GAAG,EAAE,eAAe;IACpB,MAAM,EAAE,kBAAkB;CAClB,CAAC;AAeX;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO;QACL,EAAE,EAAE,iBAAiB;QACrB,IAAI,CAAC,GAAG;YACN,GAAG,CAAC,gBAAgB,CAAC,YAAY,EAAE;gBACjC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;aACnE,CAAC,CAAC;YAEH,GAAG,CAAC,eAAe,CACjB,kBAAkB,CAAC,GAAG,EACtB,oBAAoB,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAE,CAA0B,CAAC,MAAM,CAAC,CAC9E,CAAC;YAEF,GAAG,CAAC,eAAe,CAAC,kBAAkB,CAAC,MAAM,EAAE,uBAAuB,CAAC,YAAY,CAAC,CAAC,CAAC;QACxF,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Font size mark plugin — registers the `fontSize` mark type,
|
|
3
|
+
* `setFontSize` and `removeFontSize` commands.
|
|
4
|
+
*
|
|
5
|
+
* This is a parameterized mark plugin: the mark value is a positive number
|
|
6
|
+
* representing the font size (unit is consumer-defined, typically px or pt).
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import type { Plugin } from '@rtif-sdk/engine';
|
|
11
|
+
/**
|
|
12
|
+
* Command name constants for the font size plugin.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* engine.exec(FontSizeCommands.SET, { size: 24 });
|
|
17
|
+
* engine.exec(FontSizeCommands.REMOVE);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare const FontSizeCommands: {
|
|
21
|
+
readonly SET: "setFontSize";
|
|
22
|
+
readonly REMOVE: "removeFontSize";
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Payload for the `setFontSize` command.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* engine.exec('setFontSize', { size: 16 });
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export interface SetFontSizePayload {
|
|
33
|
+
/** The font size value (must be a positive number) */
|
|
34
|
+
readonly size: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create the font size mark plugin.
|
|
38
|
+
*
|
|
39
|
+
* Registers:
|
|
40
|
+
* - Mark type: `fontSize` (value must be a positive number)
|
|
41
|
+
* - Command: `setFontSize` — apply font size to selection or set pending mark
|
|
42
|
+
* - Command: `removeFontSize` — remove font size from selection or set pending mark null
|
|
43
|
+
*
|
|
44
|
+
* No keyboard shortcuts are registered.
|
|
45
|
+
*
|
|
46
|
+
* @returns A plugin instance ready for `engine.use()`
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const engine = createEngine(initialDoc);
|
|
51
|
+
* engine.use(fontSizePlugin());
|
|
52
|
+
* engine.exec(FontSizeCommands.SET, { size: 24 });
|
|
53
|
+
* engine.exec(FontSizeCommands.REMOVE);
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export declare function fontSizePlugin(): Plugin;
|
|
57
|
+
//# sourceMappingURL=font-size-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font-size-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/font-size-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAG/C;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB;;;CAGnB,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAgBvC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Font size mark plugin — registers the `fontSize` mark type,
|
|
3
|
+
* `setFontSize` and `removeFontSize` commands.
|
|
4
|
+
*
|
|
5
|
+
* This is a parameterized mark plugin: the mark value is a positive number
|
|
6
|
+
* representing the font size (unit is consumer-defined, typically px or pt).
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import { createSetMarkCommand, createRemoveMarkCommand } from './mark-utils.js';
|
|
11
|
+
/**
|
|
12
|
+
* Command name constants for the font size plugin.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* engine.exec(FontSizeCommands.SET, { size: 24 });
|
|
17
|
+
* engine.exec(FontSizeCommands.REMOVE);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export const FontSizeCommands = {
|
|
21
|
+
SET: 'setFontSize',
|
|
22
|
+
REMOVE: 'removeFontSize',
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Create the font size mark plugin.
|
|
26
|
+
*
|
|
27
|
+
* Registers:
|
|
28
|
+
* - Mark type: `fontSize` (value must be a positive number)
|
|
29
|
+
* - Command: `setFontSize` — apply font size to selection or set pending mark
|
|
30
|
+
* - Command: `removeFontSize` — remove font size from selection or set pending mark null
|
|
31
|
+
*
|
|
32
|
+
* No keyboard shortcuts are registered.
|
|
33
|
+
*
|
|
34
|
+
* @returns A plugin instance ready for `engine.use()`
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```ts
|
|
38
|
+
* const engine = createEngine(initialDoc);
|
|
39
|
+
* engine.use(fontSizePlugin());
|
|
40
|
+
* engine.exec(FontSizeCommands.SET, { size: 24 });
|
|
41
|
+
* engine.exec(FontSizeCommands.REMOVE);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export function fontSizePlugin() {
|
|
45
|
+
return {
|
|
46
|
+
id: 'mark-fontSize',
|
|
47
|
+
init(ctx) {
|
|
48
|
+
ctx.registerMarkType('fontSize', {
|
|
49
|
+
validate: (value) => typeof value === 'number' && value > 0,
|
|
50
|
+
});
|
|
51
|
+
ctx.registerCommand(FontSizeCommands.SET, createSetMarkCommand('fontSize', (p) => p.size));
|
|
52
|
+
ctx.registerCommand(FontSizeCommands.REMOVE, createRemoveMarkCommand('fontSize'));
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=font-size-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"font-size-plugin.js","sourceRoot":"","sources":["../../src/plugins/font-size-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAEhF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,GAAG,EAAE,aAAa;IAClB,MAAM,EAAE,gBAAgB;CAChB,CAAC;AAeX;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,EAAE,EAAE,eAAe;QACnB,IAAI,CAAC,GAAG;YACN,GAAG,CAAC,gBAAgB,CAAC,UAAU,EAAE;gBAC/B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC;aAC5D,CAAC,CAAC;YAEH,GAAG,CAAC,eAAe,CACjB,gBAAgB,CAAC,GAAG,EACpB,oBAAoB,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAE,CAAwB,CAAC,IAAI,CAAC,CACxE,CAAC;YAEF,GAAG,CAAC,eAAe,CAAC,gBAAgB,CAAC,MAAM,EAAE,uBAAuB,CAAC,UAAU,CAAC,CAAC,CAAC;QACpF,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heading block type plugin — registers the `heading` block type, `toggleHeading`
|
|
3
|
+
* command, input rules for `# ` through `###### `, and Cmd/Ctrl+Alt+1/2/3 shortcuts.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import type { Plugin } from '@rtif-sdk/engine';
|
|
8
|
+
/**
|
|
9
|
+
* Command name constants for the heading plugin.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* engine.exec(HeadingCommands.TOGGLE, { level: 2 });
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare const HeadingCommands: {
|
|
17
|
+
readonly TOGGLE: "toggleHeading";
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Payload for the `toggleHeading` command.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* engine.exec('toggleHeading', { level: 2 });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export interface ToggleHeadingPayload {
|
|
28
|
+
/** Heading level (1-6) */
|
|
29
|
+
readonly level: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Create the heading block type plugin.
|
|
33
|
+
*
|
|
34
|
+
* Registers:
|
|
35
|
+
* - Block type: `heading` (attrs must have `level` between 1 and 6)
|
|
36
|
+
* - Command: `toggleHeading` — toggle between heading at a given level and plain text
|
|
37
|
+
* - Input rules: `# ` through `###### ` at block start converts to heading
|
|
38
|
+
* - Shortcuts: Cmd/Ctrl+Alt+1/2/3 for heading levels 1-3
|
|
39
|
+
*
|
|
40
|
+
* @returns A plugin instance ready for `engine.use()`
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* const engine = createEngine(initialDoc);
|
|
45
|
+
* engine.use(headingPlugin());
|
|
46
|
+
*
|
|
47
|
+
* // Toggle heading level 2 on the block at cursor
|
|
48
|
+
* engine.exec(HeadingCommands.TOGGLE, { level: 2 });
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare function headingPlugin(): Plugin;
|
|
52
|
+
//# sourceMappingURL=heading-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heading-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/heading-plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AAG9D;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;CAElB,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,IAAI,MAAM,CA2FtC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heading block type plugin — registers the `heading` block type, `toggleHeading`
|
|
3
|
+
* command, input rules for `# ` through `###### `, and Cmd/Ctrl+Alt+1/2/3 shortcuts.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { getBlockStartOffset, getBlockAtCursor, isBlockType, setBlockType } from './block-utils.js';
|
|
8
|
+
/**
|
|
9
|
+
* Command name constants for the heading plugin.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* engine.exec(HeadingCommands.TOGGLE, { level: 2 });
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export const HeadingCommands = {
|
|
17
|
+
TOGGLE: 'toggleHeading',
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Create the heading block type plugin.
|
|
21
|
+
*
|
|
22
|
+
* Registers:
|
|
23
|
+
* - Block type: `heading` (attrs must have `level` between 1 and 6)
|
|
24
|
+
* - Command: `toggleHeading` — toggle between heading at a given level and plain text
|
|
25
|
+
* - Input rules: `# ` through `###### ` at block start converts to heading
|
|
26
|
+
* - Shortcuts: Cmd/Ctrl+Alt+1/2/3 for heading levels 1-3
|
|
27
|
+
*
|
|
28
|
+
* @returns A plugin instance ready for `engine.use()`
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const engine = createEngine(initialDoc);
|
|
33
|
+
* engine.use(headingPlugin());
|
|
34
|
+
*
|
|
35
|
+
* // Toggle heading level 2 on the block at cursor
|
|
36
|
+
* engine.exec(HeadingCommands.TOGGLE, { level: 2 });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export function headingPlugin() {
|
|
40
|
+
return {
|
|
41
|
+
id: 'block-heading',
|
|
42
|
+
init(ctx) {
|
|
43
|
+
// ---------------------------------------------------------------
|
|
44
|
+
// Block type registration
|
|
45
|
+
// ---------------------------------------------------------------
|
|
46
|
+
ctx.registerBlockType('heading', {
|
|
47
|
+
defaultAttrs: { level: 1 },
|
|
48
|
+
validate: (attrs) => {
|
|
49
|
+
return (typeof attrs.level === 'number' &&
|
|
50
|
+
attrs.level >= 1 &&
|
|
51
|
+
attrs.level <= 6);
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
// ---------------------------------------------------------------
|
|
55
|
+
// toggleHeading command
|
|
56
|
+
// ---------------------------------------------------------------
|
|
57
|
+
ctx.registerCommand(HeadingCommands.TOGGLE, {
|
|
58
|
+
execute(engine, payload) {
|
|
59
|
+
const p = payload;
|
|
60
|
+
if (!p || typeof p.level !== 'number')
|
|
61
|
+
return;
|
|
62
|
+
const block = getBlockAtCursor(engine);
|
|
63
|
+
if (isBlockType(engine, 'heading', { level: p.level })) {
|
|
64
|
+
// Already a heading at this level — revert to plain text
|
|
65
|
+
engine.dispatch([
|
|
66
|
+
{ type: 'set_block_type', blockId: block.id, blockType: 'text' },
|
|
67
|
+
{ type: 'set_block_attrs', blockId: block.id, attrs: { level: null } },
|
|
68
|
+
]);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Set to heading with the requested level
|
|
72
|
+
setBlockType(engine, block.id, 'heading', { level: p.level });
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
canExecute(_engine) {
|
|
76
|
+
return true;
|
|
77
|
+
},
|
|
78
|
+
isActive(engine, payload) {
|
|
79
|
+
const p = payload;
|
|
80
|
+
if (!p || typeof p.level !== 'number')
|
|
81
|
+
return false;
|
|
82
|
+
return isBlockType(engine, 'heading', { level: p.level });
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
// ---------------------------------------------------------------
|
|
86
|
+
// Input rules: # through ###### followed by space
|
|
87
|
+
// ---------------------------------------------------------------
|
|
88
|
+
for (let level = 1; level <= 6; level++) {
|
|
89
|
+
const hashes = '#'.repeat(level);
|
|
90
|
+
const pattern = new RegExp(`^${hashes} $`);
|
|
91
|
+
ctx.registerInputRule({
|
|
92
|
+
pattern,
|
|
93
|
+
exclusive: true,
|
|
94
|
+
handler(engine, match, blockId) {
|
|
95
|
+
const blockStart = getBlockStartOffset(engine.state.doc, blockId);
|
|
96
|
+
const prefixLength = match[0].length;
|
|
97
|
+
engine.dispatch([
|
|
98
|
+
{ type: 'delete_text', offset: blockStart, count: prefixLength },
|
|
99
|
+
{ type: 'set_block_type', blockId, blockType: 'heading' },
|
|
100
|
+
{ type: 'set_block_attrs', blockId, attrs: { level } },
|
|
101
|
+
]);
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
// ---------------------------------------------------------------
|
|
106
|
+
// Keyboard shortcuts: Cmd/Ctrl+Alt+1/2/3
|
|
107
|
+
// ---------------------------------------------------------------
|
|
108
|
+
for (let level = 1; level <= 3; level++) {
|
|
109
|
+
ctx.registerShortcut({ key: String(level), mod: true, alt: true }, HeadingCommands.TOGGLE, { level });
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=heading-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heading-plugin.js","sourceRoot":"","sources":["../../src/plugins/heading-plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEpG;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,MAAM,EAAE,eAAe;CACf,CAAC;AAeX;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO;QACL,EAAE,EAAE,eAAe;QACnB,IAAI,CAAC,GAAG;YACN,kEAAkE;YAClE,0BAA0B;YAC1B,kEAAkE;YAElE,GAAG,CAAC,iBAAiB,CAAC,SAAS,EAAE;gBAC/B,YAAY,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE;gBAC1B,QAAQ,EAAE,CAAC,KAA8B,EAAW,EAAE;oBACpD,OAAO,CACL,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;wBAC/B,KAAK,CAAC,KAAK,IAAI,CAAC;wBAChB,KAAK,CAAC,KAAK,IAAI,CAAC,CACjB,CAAC;gBACJ,CAAC;aACF,CAAC,CAAC;YAEH,kEAAkE;YAClE,wBAAwB;YACxB,kEAAkE;YAElE,GAAG,CAAC,eAAe,CAAC,eAAe,CAAC,MAAM,EAAE;gBAC1C,OAAO,CAAC,MAAqB,EAAE,OAAiB;oBAC9C,MAAM,CAAC,GAAG,OAA2C,CAAC;oBACtD,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;wBAAE,OAAO;oBAE9C,MAAM,KAAK,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;oBAEvC,IAAI,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;wBACvD,yDAAyD;wBACzD,MAAM,CAAC,QAAQ,CAAC;4BACd,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE;4BAChE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;yBACvE,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,0CAA0C;wBAC1C,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;oBAChE,CAAC;gBACH,CAAC;gBAED,UAAU,CAAC,OAAsB;oBAC/B,OAAO,IAAI,CAAC;gBACd,CAAC;gBAED,QAAQ,CAAC,MAAqB,EAAE,OAAiB;oBAC/C,MAAM,CAAC,GAAG,OAA2C,CAAC;oBACtD,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ;wBAAE,OAAO,KAAK,CAAC;oBAEpD,OAAO,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;gBAC5D,CAAC;aACF,CAAC,CAAC;YAEH,kEAAkE;YAClE,kDAAkD;YAClD,kEAAkE;YAElE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACxC,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACjC,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,CAAC;gBAE3C,GAAG,CAAC,iBAAiB,CAAC;oBACpB,OAAO;oBACP,SAAS,EAAE,IAAI;oBACf,OAAO,CAAC,MAAqB,EAAE,KAAuB,EAAE,OAAe;wBACrE,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;wBAClE,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC;wBAEtC,MAAM,CAAC,QAAQ,CAAC;4BACd,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE;4BAChE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE;4BACzD,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE;yBACvD,CAAC,CAAC;oBACL,CAAC;iBACF,CAAC,CAAC;YACL,CAAC;YAED,kEAAkE;YAClE,yCAAyC;YACzC,kEAAkE;YAElE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACxC,GAAG,CAAC,gBAAgB,CAClB,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAC5C,eAAe,CAAC,MAAM,EACtB,EAAE,KAAK,EAAE,CACV,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Horizontal rule block type plugin — registers the `hr` block type and
|
|
3
|
+
* an input rule for `---` at the start of an empty block.
|
|
4
|
+
*
|
|
5
|
+
* The HR plugin does not register any commands — horizontal rules are
|
|
6
|
+
* created exclusively via the input rule or programmatic operation dispatch.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/
|
|
10
|
+
import type { Plugin } from '@rtif-sdk/engine';
|
|
11
|
+
/**
|
|
12
|
+
* Create the horizontal rule block type plugin.
|
|
13
|
+
*
|
|
14
|
+
* Registers:
|
|
15
|
+
* - Block type: `hr` (no default attrs)
|
|
16
|
+
* - Input rule: `---` at the start of an empty block converts to an HR
|
|
17
|
+
* and inserts a new empty text block below it
|
|
18
|
+
*
|
|
19
|
+
* @returns A plugin instance ready for `engine.use()`
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* const engine = createEngine(initialDoc);
|
|
24
|
+
* engine.use(hrPlugin());
|
|
25
|
+
*
|
|
26
|
+
* // Type "---" then the input rule fires:
|
|
27
|
+
* // 1. Deletes the "---" text
|
|
28
|
+
* // 2. Sets block type to 'hr'
|
|
29
|
+
* // 3. Splits block to create a new empty text block below
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function hrPlugin(): Plugin;
|
|
33
|
+
//# sourceMappingURL=hr-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hr-plugin.d.ts","sourceRoot":"","sources":["../../src/plugins/hr-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AAI9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,QAAQ,IAAI,MAAM,CA+CjC"}
|