@notectl/core 1.0.3 → 1.0.5
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/README.md +51 -148
- package/dist/chunks/AttrRegistry-DTsHyDVA.mjs +16 -0
- package/dist/chunks/AttrRegistry-DTsHyDVA.mjs.map +1 -0
- package/dist/chunks/Commands-DLP85Mp5.mjs +461 -0
- package/dist/chunks/Commands-DLP85Mp5.mjs.map +1 -0
- package/dist/chunks/Document-CI3iCwEP.mjs +177 -0
- package/dist/chunks/Document-CI3iCwEP.mjs.map +1 -0
- package/dist/chunks/HTMLUtils-0wvCRvJc.mjs +7 -0
- package/dist/chunks/HTMLUtils-0wvCRvJc.mjs.map +1 -0
- package/dist/chunks/NodeResolver-D68ZLXti.mjs +81 -0
- package/dist/chunks/NodeResolver-D68ZLXti.mjs.map +1 -0
- package/dist/chunks/NodeSpec-NZVvcCuH.mjs +8 -0
- package/dist/chunks/NodeSpec-NZVvcCuH.mjs.map +1 -0
- package/dist/chunks/Plugin-B9OZ6Y4c.mjs +15 -0
- package/dist/chunks/Plugin-B9OZ6Y4c.mjs.map +1 -0
- package/dist/chunks/Selection-D5ZjXoB7.mjs +44 -0
- package/dist/chunks/Selection-D5ZjXoB7.mjs.map +1 -0
- package/dist/chunks/ToolbarItem-ugDymuXi.mjs +7 -0
- package/dist/chunks/ToolbarItem-ugDymuXi.mjs.map +1 -0
- package/dist/chunks/ToolbarPlugin-D5VqeBPT.mjs +398 -0
- package/dist/chunks/ToolbarPlugin-D5VqeBPT.mjs.map +1 -0
- package/dist/chunks/TypeBrands-C09nE2qO.mjs +27 -0
- package/dist/chunks/TypeBrands-C09nE2qO.mjs.map +1 -0
- package/dist/chunks/color-picker-Csf0wx5a.mjs +5 -0
- package/dist/chunks/color-picker-Csf0wx5a.mjs.map +1 -0
- package/dist/chunks/index-CPPb-Jah.mjs +569 -0
- package/dist/chunks/index-CPPb-Jah.mjs.map +1 -0
- package/dist/commands/Commands.d.ts +71 -0
- package/dist/commands/Commands.d.ts.map +1 -0
- package/dist/commands/PasteCommand.d.ts +9 -0
- package/dist/commands/PasteCommand.d.ts.map +1 -0
- package/dist/decorations/Decoration.d.ts +76 -0
- package/dist/decorations/Decoration.d.ts.map +1 -0
- package/dist/decorations/PositionMapping.d.ts +9 -0
- package/dist/decorations/PositionMapping.d.ts.map +1 -0
- package/dist/editor/Announcer.d.ts +12 -0
- package/dist/editor/Announcer.d.ts.map +1 -0
- package/dist/editor/DocumentParser.d.ts +5 -0
- package/dist/editor/DocumentParser.d.ts.map +1 -0
- package/dist/editor/DocumentSerializer.d.ts +5 -0
- package/dist/editor/DocumentSerializer.d.ts.map +1 -0
- package/dist/editor/EditorDOM.d.ts +18 -0
- package/dist/editor/EditorDOM.d.ts.map +1 -0
- package/dist/editor/EditorThemeController.d.ts +21 -0
- package/dist/editor/EditorThemeController.d.ts.map +1 -0
- package/dist/editor/NotectlEditor.d.ts +131 -0
- package/dist/editor/NotectlEditor.d.ts.map +1 -0
- package/dist/editor/styles/base.d.ts +3 -0
- package/dist/editor/styles/base.d.ts.map +1 -0
- package/dist/editor/styles/code-block.d.ts +3 -0
- package/dist/editor/styles/code-block.d.ts.map +1 -0
- package/dist/editor/styles/color-picker.d.ts +3 -0
- package/dist/editor/styles/color-picker.d.ts.map +1 -0
- package/dist/editor/styles/font-select.d.ts +3 -0
- package/dist/editor/styles/font-select.d.ts.map +1 -0
- package/dist/editor/styles/font-size-select.d.ts +3 -0
- package/dist/editor/styles/font-size-select.d.ts.map +1 -0
- package/dist/editor/styles/heading-select.d.ts +3 -0
- package/dist/editor/styles/heading-select.d.ts.map +1 -0
- package/dist/editor/styles/image.d.ts +3 -0
- package/dist/editor/styles/image.d.ts.map +1 -0
- package/dist/editor/styles/list.d.ts +3 -0
- package/dist/editor/styles/list.d.ts.map +1 -0
- package/dist/editor/styles/reduced-motion.d.ts +3 -0
- package/dist/editor/styles/reduced-motion.d.ts.map +1 -0
- package/dist/editor/styles/table.d.ts +3 -0
- package/dist/editor/styles/table.d.ts.map +1 -0
- package/dist/editor/styles/toolbar.d.ts +3 -0
- package/dist/editor/styles/toolbar.d.ts.map +1 -0
- package/dist/editor/styles.d.ts +12 -0
- package/dist/editor/styles.d.ts.map +1 -0
- package/dist/editor/theme/ThemeEngine.d.ts +6 -0
- package/dist/editor/theme/ThemeEngine.d.ts.map +1 -0
- package/dist/editor/theme/ThemeTokens.d.ts +73 -0
- package/dist/editor/theme/ThemeTokens.d.ts.map +1 -0
- package/dist/fonts.d.ts +17 -0
- package/dist/fonts.d.ts.map +1 -0
- package/dist/fonts.mjs +7 -0
- package/dist/fonts.mjs.map +1 -0
- package/dist/index.d.ts +81 -2360
- package/dist/index.d.ts.map +1 -0
- package/dist/input/ClipboardHandler.d.ts +29 -0
- package/dist/input/ClipboardHandler.d.ts.map +1 -0
- package/dist/input/InputHandler.d.ts +32 -0
- package/dist/input/InputHandler.d.ts.map +1 -0
- package/dist/input/InputRule.d.ts +9 -0
- package/dist/input/InputRule.d.ts.map +1 -0
- package/dist/input/InternalClipboard.d.ts +23 -0
- package/dist/input/InternalClipboard.d.ts.map +1 -0
- package/dist/input/KeyboardHandler.d.ts +42 -0
- package/dist/input/KeyboardHandler.d.ts.map +1 -0
- package/dist/input/Keymap.d.ts +11 -0
- package/dist/input/Keymap.d.ts.map +1 -0
- package/dist/input/PasteHandler.d.ts +38 -0
- package/dist/input/PasteHandler.d.ts.map +1 -0
- package/dist/input/SourceNormalizer.d.ts +7 -0
- package/dist/input/SourceNormalizer.d.ts.map +1 -0
- package/dist/model/AttrRegistry.d.ts +39 -0
- package/dist/model/AttrRegistry.d.ts.map +1 -0
- package/dist/model/BuiltinSpecs.d.ts +4 -0
- package/dist/model/BuiltinSpecs.d.ts.map +1 -0
- package/dist/model/ContentModel.d.ts +12 -0
- package/dist/model/ContentModel.d.ts.map +1 -0
- package/dist/model/ContentSlice.d.ts +17 -0
- package/dist/model/ContentSlice.d.ts.map +1 -0
- package/dist/model/Document.d.ts +127 -0
- package/dist/model/Document.d.ts.map +1 -0
- package/dist/model/HTMLParser.d.ts +36 -0
- package/dist/model/HTMLParser.d.ts.map +1 -0
- package/dist/model/HTMLUtils.d.ts +6 -0
- package/dist/model/HTMLUtils.d.ts.map +1 -0
- package/dist/model/InlineNodeSpec.d.ts +20 -0
- package/dist/model/InlineNodeSpec.d.ts.map +1 -0
- package/dist/model/MarkSpec.d.ts +22 -0
- package/dist/model/MarkSpec.d.ts.map +1 -0
- package/dist/model/NodeResolver.d.ts +36 -0
- package/dist/model/NodeResolver.d.ts.map +1 -0
- package/dist/model/NodeSpec.d.ts +67 -0
- package/dist/model/NodeSpec.d.ts.map +1 -0
- package/dist/model/ParseRule.d.ts +11 -0
- package/dist/model/ParseRule.d.ts.map +1 -0
- package/dist/model/SanitizeConfig.d.ts +9 -0
- package/dist/model/SanitizeConfig.d.ts.map +1 -0
- package/dist/model/Schema.d.ts +17 -0
- package/dist/model/Schema.d.ts.map +1 -0
- package/dist/model/SchemaRegistry.d.ts +81 -0
- package/dist/model/SchemaRegistry.d.ts.map +1 -0
- package/dist/model/Selection.d.ts +52 -0
- package/dist/model/Selection.d.ts.map +1 -0
- package/dist/model/TypeBrands.d.ts +28 -0
- package/dist/model/TypeBrands.d.ts.map +1 -0
- package/dist/notectl-core.mjs +2576 -11104
- package/dist/notectl-core.mjs.map +1 -1
- package/dist/notectl-core.umd.js +6810 -0
- package/dist/notectl-core.umd.js.map +1 -0
- package/dist/plugins/EventBus.d.ts +13 -0
- package/dist/plugins/EventBus.d.ts.map +1 -0
- package/dist/plugins/Plugin.d.ts +85 -0
- package/dist/plugins/Plugin.d.ts.map +1 -0
- package/dist/plugins/PluginManager.d.ts +66 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -0
- package/dist/plugins/alignment/AlignmentPlugin.d.ts +48 -0
- package/dist/plugins/alignment/AlignmentPlugin.d.ts.map +1 -0
- package/dist/plugins/alignment/index.d.ts +2 -0
- package/dist/plugins/alignment/index.d.ts.map +1 -0
- package/dist/plugins/alignment.mjs +92 -0
- package/dist/plugins/alignment.mjs.map +1 -0
- package/dist/plugins/blockquote/BlockquotePlugin.d.ts +30 -0
- package/dist/plugins/blockquote/BlockquotePlugin.d.ts.map +1 -0
- package/dist/plugins/blockquote/index.d.ts +2 -0
- package/dist/plugins/blockquote/index.d.ts.map +1 -0
- package/dist/plugins/blockquote.mjs +58 -0
- package/dist/plugins/blockquote.mjs.map +1 -0
- package/dist/plugins/code-block/CodeBlockNodeView.d.ts +5 -0
- package/dist/plugins/code-block/CodeBlockNodeView.d.ts.map +1 -0
- package/dist/plugins/code-block/CodeBlockPlugin.d.ts +135 -0
- package/dist/plugins/code-block/CodeBlockPlugin.d.ts.map +1 -0
- package/dist/plugins/code-block/index.d.ts +2 -0
- package/dist/plugins/code-block/index.d.ts.map +1 -0
- package/dist/plugins/code-block.mjs +6 -0
- package/dist/plugins/code-block.mjs.map +1 -0
- package/dist/plugins/font/FontPlugin.d.ts +85 -0
- package/dist/plugins/font/FontPlugin.d.ts.map +1 -0
- package/dist/plugins/font/StarterFonts.d.ts +10 -0
- package/dist/plugins/font/StarterFonts.d.ts.map +1 -0
- package/dist/plugins/font/index.d.ts +2 -0
- package/dist/plugins/font/index.d.ts.map +1 -0
- package/dist/plugins/font-size/FontSizePlugin.d.ts +65 -0
- package/dist/plugins/font-size/FontSizePlugin.d.ts.map +1 -0
- package/dist/plugins/font-size/index.d.ts +2 -0
- package/dist/plugins/font-size/index.d.ts.map +1 -0
- package/dist/plugins/font-size.mjs +220 -0
- package/dist/plugins/font-size.mjs.map +1 -0
- package/dist/plugins/font.mjs +186 -0
- package/dist/plugins/font.mjs.map +1 -0
- package/dist/plugins/hard-break/HardBreakPlugin.d.ts +16 -0
- package/dist/plugins/hard-break/HardBreakPlugin.d.ts.map +1 -0
- package/dist/plugins/hard-break/index.d.ts +2 -0
- package/dist/plugins/hard-break/index.d.ts.map +1 -0
- package/dist/plugins/hard-break.mjs +28 -0
- package/dist/plugins/hard-break.mjs.map +1 -0
- package/dist/plugins/heading/BlockTypePickerEntry.d.ts +20 -0
- package/dist/plugins/heading/BlockTypePickerEntry.d.ts.map +1 -0
- package/dist/plugins/heading/HeadingPlugin.d.ts +78 -0
- package/dist/plugins/heading/HeadingPlugin.d.ts.map +1 -0
- package/dist/plugins/heading/index.d.ts +3 -0
- package/dist/plugins/heading/index.d.ts.map +1 -0
- package/dist/plugins/heading.mjs +188 -0
- package/dist/plugins/heading.mjs.map +1 -0
- package/dist/plugins/highlight/HighlightPlugin.d.ts +37 -0
- package/dist/plugins/highlight/HighlightPlugin.d.ts.map +1 -0
- package/dist/plugins/highlight/index.d.ts +2 -0
- package/dist/plugins/highlight/index.d.ts.map +1 -0
- package/dist/plugins/highlight.mjs +126 -0
- package/dist/plugins/highlight.mjs.map +1 -0
- package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts +29 -0
- package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts.map +1 -0
- package/dist/plugins/horizontal-rule/index.d.ts +2 -0
- package/dist/plugins/horizontal-rule/index.d.ts.map +1 -0
- package/dist/plugins/horizontal-rule.mjs +59 -0
- package/dist/plugins/horizontal-rule.mjs.map +1 -0
- package/dist/plugins/image/ImageCommands.d.ts +26 -0
- package/dist/plugins/image/ImageCommands.d.ts.map +1 -0
- package/dist/plugins/image/ImageNodeView.d.ts +6 -0
- package/dist/plugins/image/ImageNodeView.d.ts.map +1 -0
- package/dist/plugins/image/ImagePlugin.d.ts +43 -0
- package/dist/plugins/image/ImagePlugin.d.ts.map +1 -0
- package/dist/plugins/image/ImageUpload.d.ts +48 -0
- package/dist/plugins/image/ImageUpload.d.ts.map +1 -0
- package/dist/plugins/image/index.d.ts +3 -0
- package/dist/plugins/image/index.d.ts.map +1 -0
- package/dist/plugins/image.mjs +381 -0
- package/dist/plugins/image.mjs.map +1 -0
- package/dist/plugins/link/LinkPlugin.d.ts +32 -0
- package/dist/plugins/link/LinkPlugin.d.ts.map +1 -0
- package/dist/plugins/link/index.d.ts +2 -0
- package/dist/plugins/link/index.d.ts.map +1 -0
- package/dist/plugins/link.mjs +127 -0
- package/dist/plugins/link.mjs.map +1 -0
- package/dist/plugins/list/ListPlugin.d.ts +51 -0
- package/dist/plugins/list/ListPlugin.d.ts.map +1 -0
- package/dist/plugins/list/index.d.ts +2 -0
- package/dist/plugins/list/index.d.ts.map +1 -0
- package/dist/plugins/list.mjs +193 -0
- package/dist/plugins/list.mjs.map +1 -0
- package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts +23 -0
- package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts.map +1 -0
- package/dist/plugins/strikethrough/index.d.ts +2 -0
- package/dist/plugins/strikethrough/index.d.ts.map +1 -0
- package/dist/plugins/strikethrough.mjs +35 -0
- package/dist/plugins/strikethrough.mjs.map +1 -0
- package/dist/plugins/super-sub/SuperSubPlugin.d.ts +44 -0
- package/dist/plugins/super-sub/SuperSubPlugin.d.ts.map +1 -0
- package/dist/plugins/super-sub/index.d.ts +2 -0
- package/dist/plugins/super-sub/index.d.ts.map +1 -0
- package/dist/plugins/super-sub.mjs +81 -0
- package/dist/plugins/super-sub.mjs.map +1 -0
- package/dist/plugins/table/TableCommands.d.ts +50 -0
- package/dist/plugins/table/TableCommands.d.ts.map +1 -0
- package/dist/plugins/table/TableControls.d.ts +10 -0
- package/dist/plugins/table/TableControls.d.ts.map +1 -0
- package/dist/plugins/table/TableControlsDOM.d.ts +18 -0
- package/dist/plugins/table/TableControlsDOM.d.ts.map +1 -0
- package/dist/plugins/table/TableControlsLayout.d.ts +34 -0
- package/dist/plugins/table/TableControlsLayout.d.ts.map +1 -0
- package/dist/plugins/table/TableHelpers.d.ts +39 -0
- package/dist/plugins/table/TableHelpers.d.ts.map +1 -0
- package/dist/plugins/table/TableNavigation.d.ts +4 -0
- package/dist/plugins/table/TableNavigation.d.ts.map +1 -0
- package/dist/plugins/table/TableNodeViews.d.ts +18 -0
- package/dist/plugins/table/TableNodeViews.d.ts.map +1 -0
- package/dist/plugins/table/TablePlugin.d.ts +39 -0
- package/dist/plugins/table/TablePlugin.d.ts.map +1 -0
- package/dist/plugins/table/TableSelection.d.ts +26 -0
- package/dist/plugins/table/TableSelection.d.ts.map +1 -0
- package/dist/plugins/table/TableTestUtils.d.ts +45 -0
- package/dist/plugins/table/TableTestUtils.d.ts.map +1 -0
- package/dist/plugins/table/index.d.ts +4 -0
- package/dist/plugins/table/index.d.ts.map +1 -0
- package/dist/plugins/table.mjs +663 -0
- package/dist/plugins/table.mjs.map +1 -0
- package/dist/plugins/text-color/TextColorPlugin.d.ts +37 -0
- package/dist/plugins/text-color/TextColorPlugin.d.ts.map +1 -0
- package/dist/plugins/text-color/index.d.ts +2 -0
- package/dist/plugins/text-color/index.d.ts.map +1 -0
- package/dist/plugins/text-color.mjs +126 -0
- package/dist/plugins/text-color.mjs.map +1 -0
- package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts +34 -0
- package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts.map +1 -0
- package/dist/plugins/text-formatting/index.d.ts +2 -0
- package/dist/plugins/text-formatting/index.d.ts.map +1 -0
- package/dist/plugins/text-formatting.mjs +52 -0
- package/dist/plugins/text-formatting.mjs.map +1 -0
- package/dist/plugins/toolbar/ToolbarItem.d.ts +66 -0
- package/dist/plugins/toolbar/ToolbarItem.d.ts.map +1 -0
- package/dist/plugins/toolbar/ToolbarKeyboardNav.d.ts +25 -0
- package/dist/plugins/toolbar/ToolbarKeyboardNav.d.ts.map +1 -0
- package/dist/plugins/toolbar/ToolbarPlugin.d.ts +47 -0
- package/dist/plugins/toolbar/ToolbarPlugin.d.ts.map +1 -0
- package/dist/plugins/toolbar/ToolbarPopupController.d.ts +25 -0
- package/dist/plugins/toolbar/ToolbarPopupController.d.ts.map +1 -0
- package/dist/plugins/toolbar/ToolbarRenderers.d.ts +19 -0
- package/dist/plugins/toolbar/ToolbarRenderers.d.ts.map +1 -0
- package/dist/plugins/toolbar/ToolbarTooltip.d.ts +17 -0
- package/dist/plugins/toolbar/ToolbarTooltip.d.ts.map +1 -0
- package/dist/plugins/toolbar/index.d.ts +4 -0
- package/dist/plugins/toolbar/index.d.ts.map +1 -0
- package/dist/plugins/toolbar.mjs +8 -0
- package/dist/plugins/toolbar.mjs.map +1 -0
- package/dist/state/EditorState.d.ts +40 -0
- package/dist/state/EditorState.d.ts.map +1 -0
- package/dist/state/History.d.ts +38 -0
- package/dist/state/History.d.ts.map +1 -0
- package/dist/state/StepApplication.d.ts +5 -0
- package/dist/state/StepApplication.d.ts.map +1 -0
- package/dist/state/Transaction.d.ts +185 -0
- package/dist/state/Transaction.d.ts.map +1 -0
- package/dist/test/PluginTestUtils.d.ts +127 -0
- package/dist/test/PluginTestUtils.d.ts.map +1 -0
- package/dist/test/TestUtils.d.ts +153 -0
- package/dist/test/TestUtils.d.ts.map +1 -0
- package/dist/view/EditorView.d.ts +74 -0
- package/dist/view/EditorView.d.ts.map +1 -0
- package/dist/view/NodeView.d.ts +18 -0
- package/dist/view/NodeView.d.ts.map +1 -0
- package/dist/view/Reconciler.d.ts +23 -0
- package/dist/view/Reconciler.d.ts.map +1 -0
- package/dist/view/SelectionSync.d.ts +8 -0
- package/dist/view/SelectionSync.d.ts.map +1 -0
- package/package.json +112 -11
- package/dist/notectl-core.js +0 -1463
- package/dist/notectl-core.js.map +0 -1
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
function t(t2, n2, r2) {
|
|
2
|
+
const o2 = s(t2), i2 = [];
|
|
3
|
+
let u2 = 0;
|
|
4
|
+
for (const t3 of o2) {
|
|
5
|
+
const o3 = u2 + (e(t3) ? 1 : t3.text.length);
|
|
6
|
+
if (o3 <= n2 || u2 >= r2) {
|
|
7
|
+
u2 = o3;
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
if (e(t3)) {
|
|
11
|
+
u2 = o3;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const s2 = Math.max(0, n2 - u2), f2 = Math.min(t3.text.length, r2 - u2), c2 = t3.text.slice(s2, f2);
|
|
15
|
+
c2.length > 0 && i2.push({ text: c2, marks: t3.marks }), u2 = o3;
|
|
16
|
+
}
|
|
17
|
+
return i2;
|
|
18
|
+
}
|
|
19
|
+
function n(t2) {
|
|
20
|
+
return "object" == typeof t2 && null !== t2 && "text" === t2.type && "string" == typeof t2.text;
|
|
21
|
+
}
|
|
22
|
+
function e(t2) {
|
|
23
|
+
return "object" == typeof t2 && null !== t2 && "inline" === t2.type && "string" == typeof t2.inlineType;
|
|
24
|
+
}
|
|
25
|
+
function r(t2) {
|
|
26
|
+
return "object" == typeof t2 && null !== t2 && "string" == typeof t2.id && "string" == typeof t2.type && "text" !== t2.type && "inline" !== t2.type && Array.isArray(t2.children);
|
|
27
|
+
}
|
|
28
|
+
function o(t2) {
|
|
29
|
+
return t2.children.every((t3) => n(t3) || e(t3));
|
|
30
|
+
}
|
|
31
|
+
function i(t2) {
|
|
32
|
+
return t2.children.filter((t3) => n(t3));
|
|
33
|
+
}
|
|
34
|
+
function s(t2) {
|
|
35
|
+
return t2.children.filter((t3) => n(t3) || e(t3));
|
|
36
|
+
}
|
|
37
|
+
function u(t2) {
|
|
38
|
+
return t2.children.filter((t3) => r(t3));
|
|
39
|
+
}
|
|
40
|
+
function f() {
|
|
41
|
+
return `block-${crypto.randomUUID()}`;
|
|
42
|
+
}
|
|
43
|
+
function c(t2) {
|
|
44
|
+
return { children: t2 ?? [l("paragraph")] };
|
|
45
|
+
}
|
|
46
|
+
function l(t2, n2, e2, r2) {
|
|
47
|
+
return { id: e2 ?? f(), type: t2, ...r2 ? { attrs: r2 } : {}, children: n2 ?? [a("")] };
|
|
48
|
+
}
|
|
49
|
+
function a(t2, n2) {
|
|
50
|
+
return { type: "text", text: t2, marks: n2 ?? [] };
|
|
51
|
+
}
|
|
52
|
+
function h(t2, n2) {
|
|
53
|
+
return { type: "inline", inlineType: t2, attrs: n2 ?? {} };
|
|
54
|
+
}
|
|
55
|
+
function g(t2) {
|
|
56
|
+
const e2 = s(t2);
|
|
57
|
+
let r2 = "";
|
|
58
|
+
for (const t3 of e2) n(t3) && (r2 += t3.text);
|
|
59
|
+
return r2;
|
|
60
|
+
}
|
|
61
|
+
function y(t2) {
|
|
62
|
+
const n2 = s(t2);
|
|
63
|
+
let r2 = 0;
|
|
64
|
+
for (const t3 of n2) r2 += e(t3) ? 1 : t3.text.length;
|
|
65
|
+
return r2;
|
|
66
|
+
}
|
|
67
|
+
function p(t2, r2) {
|
|
68
|
+
const o2 = s(t2);
|
|
69
|
+
let i2 = 0;
|
|
70
|
+
for (const t3 of o2) {
|
|
71
|
+
if (e(t3)) {
|
|
72
|
+
if (r2 === i2) return [];
|
|
73
|
+
i2 += 1;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
const n2 = i2 + t3.text.length;
|
|
77
|
+
if (r2 >= i2 && r2 < n2) return t3.marks;
|
|
78
|
+
if (r2 === i2 && 0 === t3.text.length) return t3.marks;
|
|
79
|
+
i2 = n2;
|
|
80
|
+
}
|
|
81
|
+
for (let t3 = o2.length - 1; t3 >= 0; t3--) {
|
|
82
|
+
const e2 = o2[t3];
|
|
83
|
+
if (e2 && n(e2)) return e2.marks;
|
|
84
|
+
}
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
function x(t2, n2) {
|
|
88
|
+
return t2.length === n2.length && t2.every((t3) => n2.some((n3) => (function(t4, n4) {
|
|
89
|
+
if (t4.type !== n4.type) return false;
|
|
90
|
+
const e2 = t4.attrs, r2 = n4.attrs;
|
|
91
|
+
if (!e2 && !r2) return true;
|
|
92
|
+
if (!e2 || !r2) return false;
|
|
93
|
+
const o2 = Object.keys(e2), i2 = Object.keys(r2);
|
|
94
|
+
return o2.length === i2.length && o2.every((t5) => e2[t5] === r2[t5]);
|
|
95
|
+
})(t3, n3)));
|
|
96
|
+
}
|
|
97
|
+
function m(t2, n2) {
|
|
98
|
+
return t2.some((t3) => t3.type === n2);
|
|
99
|
+
}
|
|
100
|
+
function k(t2, n2) {
|
|
101
|
+
return m(t2, n2.type) ? t2 : [...t2, n2];
|
|
102
|
+
}
|
|
103
|
+
function d(t2, n2) {
|
|
104
|
+
return t2.filter((t3) => t3.type !== n2);
|
|
105
|
+
}
|
|
106
|
+
function b(t2) {
|
|
107
|
+
if (0 === t2.length) return [a("")];
|
|
108
|
+
if (t2.every((t3) => n(t3))) return (function(t3) {
|
|
109
|
+
if (0 === t3.length) return [a("")];
|
|
110
|
+
const n2 = [];
|
|
111
|
+
for (const e2 of t3) {
|
|
112
|
+
const t4 = n2[n2.length - 1];
|
|
113
|
+
t4 && x(t4.marks, e2.marks) ? n2[n2.length - 1] = a(t4.text + e2.text, t4.marks) : (e2.text.length > 0 || 0 === n2.length) && n2.push(e2);
|
|
114
|
+
}
|
|
115
|
+
return 0 === n2.length ? [a("")] : n2;
|
|
116
|
+
})(t2);
|
|
117
|
+
const r2 = [];
|
|
118
|
+
for (const o3 of t2) {
|
|
119
|
+
if (e(o3)) {
|
|
120
|
+
r2.push(o3);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const t3 = r2[r2.length - 1];
|
|
124
|
+
t3 && n(t3) && x(t3.marks, o3.marks) ? r2[r2.length - 1] = a(t3.text + o3.text, t3.marks) : (o3.text.length > 0 || 0 === r2.length) && r2.push(o3);
|
|
125
|
+
}
|
|
126
|
+
const o2 = r2.filter((t3, n2) => {
|
|
127
|
+
if (e(t3)) return true;
|
|
128
|
+
if (t3.text.length > 0) return true;
|
|
129
|
+
if (1 === r2.length) return true;
|
|
130
|
+
const o3 = r2[n2 - 1], i2 = r2[n2 + 1];
|
|
131
|
+
return !(o3 && e(o3) || i2 && e(i2));
|
|
132
|
+
});
|
|
133
|
+
return 0 === o2.length ? [a("")] : o2.some((t3) => n(t3)) ? o2 : [a(""), ...o2];
|
|
134
|
+
}
|
|
135
|
+
function j(t2, n2) {
|
|
136
|
+
const r2 = s(t2);
|
|
137
|
+
for (const { child: t3, from: o2 } of (function* (t4) {
|
|
138
|
+
let n3 = 0;
|
|
139
|
+
for (const r3 of t4) {
|
|
140
|
+
const t5 = e(r3) ? 1 : r3.text.length;
|
|
141
|
+
yield { child: r3, from: n3, to: n3 + t5 }, n3 += t5;
|
|
142
|
+
}
|
|
143
|
+
})(r2)) {
|
|
144
|
+
if (e(t3)) {
|
|
145
|
+
if (n2 === o2) return { kind: "inline", node: t3 };
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const r3 = n2 - o2;
|
|
149
|
+
if (r3 >= 0 && r3 < t3.text.length) return { kind: "text", char: t3.text[r3] ?? "", marks: t3.marks };
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
export {
|
|
154
|
+
r as a,
|
|
155
|
+
f as b,
|
|
156
|
+
l as c,
|
|
157
|
+
a as d,
|
|
158
|
+
p as e,
|
|
159
|
+
h as f,
|
|
160
|
+
y as g,
|
|
161
|
+
m as h,
|
|
162
|
+
e as i,
|
|
163
|
+
s as j,
|
|
164
|
+
n as k,
|
|
165
|
+
j as l,
|
|
166
|
+
k as m,
|
|
167
|
+
b as n,
|
|
168
|
+
t as o,
|
|
169
|
+
g as p,
|
|
170
|
+
c as q,
|
|
171
|
+
d as r,
|
|
172
|
+
o as s,
|
|
173
|
+
x as t,
|
|
174
|
+
u,
|
|
175
|
+
i as v
|
|
176
|
+
};
|
|
177
|
+
//# sourceMappingURL=Document-CI3iCwEP.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Document-CI3iCwEP.mjs","sources":["../../src/model/Document.ts"],"sourcesContent":["/**\n * Core document model types for the Notectl editor.\n * All types are deeply readonly — mutations create new instances.\n */\n\nimport type { BlockId, InlineTypeName, MarkTypeName, NodeTypeName } from './TypeBrands.js';\n\n// --- Mark Types ---\n\n/** @deprecated Use {@link MarkTypeName} for new code. */\nexport type MarkType = MarkTypeName;\n\nexport interface Mark {\n\treadonly type: MarkTypeName;\n\treadonly attrs?: Readonly<Record<string, string | number | boolean>>;\n}\n\nexport interface BoldMark extends Mark {\n\treadonly type: MarkTypeName & 'bold';\n}\n\nexport interface ItalicMark extends Mark {\n\treadonly type: MarkTypeName & 'italic';\n}\n\nexport interface UnderlineMark extends Mark {\n\treadonly type: MarkTypeName & 'underline';\n}\n\n// --- Node Types ---\n\n/** @deprecated Use {@link NodeTypeName} for new code. */\nexport type NodeType = NodeTypeName;\n\nexport interface BlockAttrs {\n\treadonly [key: string]: string | number | boolean;\n}\n\nexport interface TextNode {\n\treadonly type: 'text';\n\treadonly text: string;\n\treadonly marks: readonly Mark[];\n}\n\n/** Atomic inline element (width 1 in offset space). */\nexport interface InlineNode {\n\treadonly type: 'inline';\n\treadonly inlineType: InlineTypeName;\n\treadonly attrs: Readonly<Record<string, string | number | boolean>>;\n}\n\n/** A child of a BlockNode: text, inline element, or nested block. */\nexport type ChildNode = TextNode | InlineNode | BlockNode;\n\nexport interface BlockNode {\n\treadonly id: BlockId;\n\treadonly type: NodeTypeName;\n\treadonly attrs?: BlockAttrs;\n\treadonly children: readonly ChildNode[];\n}\n\nexport interface Document {\n\treadonly children: readonly BlockNode[];\n}\n\n// --- Text Segment (for mark-preserving undo) ---\n\nexport interface TextSegment {\n\treadonly text: string;\n\treadonly marks: readonly Mark[];\n}\n\n/** A content segment: either text (with marks) or an inline node. */\nexport type ContentSegment =\n\t| { readonly kind: 'text'; readonly text: string; readonly marks: readonly Mark[] }\n\t| { readonly kind: 'inline'; readonly node: InlineNode };\n\n/** Extracts TextNode segments within a block for the given offset range. */\nexport function getBlockSegmentsInRange(\n\tblock: BlockNode,\n\tfrom: number,\n\tto: number,\n): readonly TextSegment[] {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\tconst segments: TextSegment[] = [];\n\tlet pos = 0;\n\n\tfor (const child of inlineChildren) {\n\t\tconst childWidth: number = isInlineNode(child) ? 1 : child.text.length;\n\t\tconst childEnd: number = pos + childWidth;\n\n\t\tif (childEnd <= from || pos >= to) {\n\t\t\tpos = childEnd;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isInlineNode(child)) {\n\t\t\t// InlineNodes are skipped for TextSegment extraction\n\t\t\tpos = childEnd;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst sliceFrom: number = Math.max(0, from - pos);\n\t\tconst sliceTo: number = Math.min(child.text.length, to - pos);\n\t\tconst text: string = child.text.slice(sliceFrom, sliceTo);\n\n\t\tif (text.length > 0) {\n\t\t\tsegments.push({ text, marks: child.marks });\n\t\t}\n\n\t\tpos = childEnd;\n\t}\n\n\treturn segments;\n}\n\n/** Returns content segments (text and inline) for a block range. */\nexport function getBlockContentSegmentsInRange(\n\tblock: BlockNode,\n\tfrom: number,\n\tto: number,\n): readonly ContentSegment[] {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\tconst segments: ContentSegment[] = [];\n\tlet pos = 0;\n\n\tfor (const child of inlineChildren) {\n\t\tconst childWidth: number = isInlineNode(child) ? 1 : child.text.length;\n\t\tconst childEnd: number = pos + childWidth;\n\n\t\tif (childEnd <= from || pos >= to) {\n\t\t\tpos = childEnd;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isInlineNode(child)) {\n\t\t\tsegments.push({ kind: 'inline', node: child });\n\t\t} else {\n\t\t\tconst sliceFrom: number = Math.max(0, from - pos);\n\t\t\tconst sliceTo: number = Math.min(child.text.length, to - pos);\n\t\t\tconst text: string = child.text.slice(sliceFrom, sliceTo);\n\t\t\tif (text.length > 0) {\n\t\t\t\tsegments.push({ kind: 'text', text, marks: child.marks });\n\t\t\t}\n\t\t}\n\n\t\tpos = childEnd;\n\t}\n\n\treturn segments;\n}\n\n// --- Type Guards ---\n\n/** Checks whether a value is a {@link TextNode}. */\nexport function isTextNode(node: unknown): node is TextNode {\n\treturn (\n\t\ttypeof node === 'object' &&\n\t\tnode !== null &&\n\t\t(node as TextNode).type === 'text' &&\n\t\ttypeof (node as TextNode).text === 'string'\n\t);\n}\n\n/** Checks whether a value is an {@link InlineNode}. */\nexport function isInlineNode(node: unknown): node is InlineNode {\n\treturn (\n\t\ttypeof node === 'object' &&\n\t\tnode !== null &&\n\t\t(node as InlineNode).type === 'inline' &&\n\t\ttypeof (node as InlineNode).inlineType === 'string'\n\t);\n}\n\n/** Checks whether a value is a {@link BlockNode}. */\nexport function isBlockNode(node: unknown): node is BlockNode {\n\treturn (\n\t\ttypeof node === 'object' &&\n\t\tnode !== null &&\n\t\ttypeof (node as BlockNode).id === 'string' &&\n\t\ttypeof (node as BlockNode).type === 'string' &&\n\t\t(node as BlockNode).type !== ('text' as string) &&\n\t\t(node as BlockNode).type !== ('inline' as string) &&\n\t\tArray.isArray((node as BlockNode).children)\n\t);\n}\n\n// --- Child Node Helpers ---\n\n/** Returns true if a block has only inline content (TextNodes and InlineNodes). */\nexport function isLeafBlock(node: BlockNode): boolean {\n\treturn node.children.every((c) => isTextNode(c) || isInlineNode(c));\n}\n\n/** Returns only the TextNode children of a block. */\nexport function getTextChildren(node: BlockNode): readonly TextNode[] {\n\treturn node.children.filter((c): c is TextNode => isTextNode(c));\n}\n\n/** Returns the inline content children (TextNode | InlineNode) of a block. */\nexport function getInlineChildren(node: BlockNode): readonly (TextNode | InlineNode)[] {\n\treturn node.children.filter((c): c is TextNode | InlineNode => isTextNode(c) || isInlineNode(c));\n}\n\n/** Returns only the BlockNode children of a block. */\nexport function getBlockChildren(node: BlockNode): readonly BlockNode[] {\n\treturn node.children.filter((c): c is BlockNode => isBlockNode(c));\n}\n\n// --- Factory Functions ---\n\n/** Generates a unique block ID using crypto.randomUUID(). */\nexport function generateBlockId(): BlockId {\n\treturn `block-${crypto.randomUUID()}` as BlockId;\n}\n\n/** Creates a new empty {@link Document} with a single empty paragraph. */\nexport function createDocument(children?: readonly BlockNode[]): Document {\n\treturn {\n\t\tchildren: children ?? [createBlockNode('paragraph' as NodeTypeName)],\n\t};\n}\n\n/** Creates a new {@link BlockNode}. */\nexport function createBlockNode(\n\ttype: NodeTypeName,\n\tchildren?: readonly ChildNode[],\n\tid?: BlockId,\n\tattrs?: BlockAttrs,\n): BlockNode {\n\treturn {\n\t\tid: id ?? generateBlockId(),\n\t\ttype,\n\t\t...(attrs ? { attrs } : {}),\n\t\tchildren: children ?? [createTextNode('')],\n\t};\n}\n\n/** Creates a new {@link TextNode}. */\nexport function createTextNode(text: string, marks?: readonly Mark[]): TextNode {\n\treturn {\n\t\ttype: 'text',\n\t\ttext,\n\t\tmarks: marks ?? [],\n\t};\n}\n\n/** Creates a new {@link InlineNode}. */\nexport function createInlineNode(\n\tinlineType: InlineTypeName,\n\tattrs?: Readonly<Record<string, string | number | boolean>>,\n): InlineNode {\n\treturn {\n\t\ttype: 'inline',\n\t\tinlineType,\n\t\tattrs: attrs ?? {},\n\t};\n}\n\n// --- Utility Functions ---\n\n/** Extracts plain text from a block (InlineNodes are skipped). */\nexport function getBlockText(block: BlockNode): string {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\tlet text = '';\n\tfor (const child of inlineChildren) {\n\t\tif (isTextNode(child)) {\n\t\t\ttext += child.text;\n\t\t}\n\t}\n\treturn text;\n}\n\n/** Returns the length of a block's inline content (InlineNodes count as 1). */\nexport function getBlockLength(block: BlockNode): number {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\tlet len = 0;\n\tfor (const child of inlineChildren) {\n\t\tlen += isInlineNode(child) ? 1 : child.text.length;\n\t}\n\treturn len;\n}\n\n/** Returns the marks active at the given offset (empty for InlineNode offsets). */\nexport function getBlockMarksAtOffset(block: BlockNode, offset: number): readonly Mark[] {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\tlet pos = 0;\n\n\tfor (const child of inlineChildren) {\n\t\tif (isInlineNode(child)) {\n\t\t\tif (offset === pos) return [];\n\t\t\tpos += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tconst end: number = pos + child.text.length;\n\t\tif (offset >= pos && offset < end) {\n\t\t\treturn child.marks;\n\t\t}\n\t\tif (offset === pos && child.text.length === 0) {\n\t\t\treturn child.marks;\n\t\t}\n\t\tpos = end;\n\t}\n\n\t// Fall back to last text child's marks\n\tfor (let i: number = inlineChildren.length - 1; i >= 0; i--) {\n\t\tconst child: TextNode | InlineNode | undefined = inlineChildren[i];\n\t\tif (child && isTextNode(child)) {\n\t\t\treturn child.marks;\n\t\t}\n\t}\n\treturn [];\n}\n\n/** Checks whether two marks are equal by type and attrs. */\nexport function marksEqual(a: Mark, b: Mark): boolean {\n\tif (a.type !== b.type) return false;\n\tconst aAttrs = a.attrs;\n\tconst bAttrs = b.attrs;\n\tif (!aAttrs && !bAttrs) return true;\n\tif (!aAttrs || !bAttrs) return false;\n\tconst aKeys = Object.keys(aAttrs);\n\tconst bKeys = Object.keys(bAttrs);\n\tif (aKeys.length !== bKeys.length) return false;\n\treturn aKeys.every((key) => aAttrs[key] === bAttrs[key]);\n}\n\n/** Checks whether two mark arrays contain the same marks (order-independent). */\nexport function markSetsEqual(a: readonly Mark[], b: readonly Mark[]): boolean {\n\tif (a.length !== b.length) return false;\n\treturn a.every((markA) => b.some((markB) => marksEqual(markA, markB)));\n}\n\n/** Returns true if the mark set contains a mark of the given type. */\nexport function hasMark(marks: readonly Mark[], markType: MarkTypeName): boolean {\n\treturn marks.some((m) => m.type === markType);\n}\n\n/** Adds a mark to a mark set (no duplicates). */\nexport function addMarkToSet(marks: readonly Mark[], mark: Mark): readonly Mark[] {\n\tif (hasMark(marks, mark.type)) return marks;\n\treturn [...marks, mark];\n}\n\n/** Removes a mark type from a mark set. */\nexport function removeMarkFromSet(marks: readonly Mark[], markType: MarkTypeName): readonly Mark[] {\n\treturn marks.filter((m) => m.type !== markType);\n}\n\n/**\n * Normalizes text nodes within a block: merges adjacent nodes with identical marks,\n * removes empty text nodes (keeping at least one).\n */\nexport function normalizeTextNodes(nodes: readonly TextNode[]): readonly TextNode[] {\n\tif (nodes.length === 0) return [createTextNode('')];\n\n\tconst result: TextNode[] = [];\n\tfor (const node of nodes) {\n\t\tconst prev: TextNode | undefined = result[result.length - 1];\n\t\tif (prev && markSetsEqual(prev.marks, node.marks)) {\n\t\t\tresult[result.length - 1] = createTextNode(prev.text + node.text, prev.marks);\n\t\t} else if (node.text.length > 0 || result.length === 0) {\n\t\t\tresult.push(node);\n\t\t}\n\t}\n\n\treturn result.length === 0 ? [createTextNode('')] : result;\n}\n\n/**\n * Normalizes mixed inline content: merges adjacent TextNodes with same marks,\n * removes empty TextNodes adjacent to InlineNodes, preserves InlineNodes as-is.\n * Guarantees at least one TextNode exists if all text is empty.\n */\nexport function normalizeInlineContent(\n\tnodes: readonly (TextNode | InlineNode)[],\n): readonly (TextNode | InlineNode)[] {\n\tif (nodes.length === 0) return [createTextNode('')];\n\n\t// Fast path: no InlineNodes, delegate to normalizeTextNodes\n\tif (nodes.every((n): n is TextNode => isTextNode(n))) {\n\t\treturn normalizeTextNodes(nodes);\n\t}\n\n\tconst result: (TextNode | InlineNode)[] = [];\n\n\tfor (const node of nodes) {\n\t\tif (isInlineNode(node)) {\n\t\t\tresult.push(node);\n\t\t\tcontinue;\n\t\t}\n\t\t// TextNode: try to merge with previous TextNode\n\t\tconst prev: TextNode | InlineNode | undefined = result[result.length - 1];\n\t\tif (prev && isTextNode(prev) && markSetsEqual(prev.marks, node.marks)) {\n\t\t\tresult[result.length - 1] = createTextNode(prev.text + node.text, prev.marks);\n\t\t} else if (node.text.length > 0 || result.length === 0) {\n\t\t\tresult.push(node);\n\t\t}\n\t}\n\n\t// Remove empty TextNodes that are adjacent to InlineNodes\n\tconst cleaned: (TextNode | InlineNode)[] = result.filter((node, i) => {\n\t\tif (isInlineNode(node)) return true;\n\t\tif (node.text.length > 0) return true;\n\t\t// Keep if it's the only node\n\t\tif (result.length === 1) return true;\n\t\t// Remove empty TextNode if adjacent to InlineNode\n\t\tconst prev: TextNode | InlineNode | undefined = result[i - 1];\n\t\tconst next: TextNode | InlineNode | undefined = result[i + 1];\n\t\tif ((prev && isInlineNode(prev)) || (next && isInlineNode(next))) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t});\n\n\t// Ensure at least one TextNode exists\n\tif (cleaned.length === 0) return [createTextNode('')];\n\tif (!cleaned.some((n) => isTextNode(n))) {\n\t\treturn [createTextNode(''), ...cleaned];\n\t}\n\n\treturn cleaned;\n}\n\n/** Yields each inline child with its offset range. InlineNodes have width 1. */\nexport function* walkInlineContent(children: readonly (TextNode | InlineNode)[]): Generator<{\n\treadonly child: TextNode | InlineNode;\n\treadonly from: number;\n\treadonly to: number;\n}> {\n\tlet pos = 0;\n\tfor (const child of children) {\n\t\tconst width: number = isInlineNode(child) ? 1 : child.text.length;\n\t\tyield { child, from: pos, to: pos + width };\n\t\tpos += width;\n\t}\n}\n\n/** Returns the content at a specific offset: text char, inline node, or null. */\nexport function getContentAtOffset(\n\tblock: BlockNode,\n\toffset: number,\n):\n\t| { readonly kind: 'text'; readonly char: string; readonly marks: readonly Mark[] }\n\t| { readonly kind: 'inline'; readonly node: InlineNode }\n\t| null {\n\tconst inlineChildren: readonly (TextNode | InlineNode)[] = getInlineChildren(block);\n\n\tfor (const { child, from } of walkInlineContent(inlineChildren)) {\n\t\tif (isInlineNode(child)) {\n\t\t\tif (offset === from) return { kind: 'inline', node: child };\n\t\t\tcontinue;\n\t\t}\n\t\tconst localOffset: number = offset - from;\n\t\tif (localOffset >= 0 && localOffset < child.text.length) {\n\t\t\treturn {\n\t\t\t\tkind: 'text',\n\t\t\t\tchar: child.text[localOffset] ?? '',\n\t\t\t\tmarks: child.marks,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn null;\n}\n"],"names":["getBlockSegmentsInRange","block","from","to","inlineChildren","getInlineChildren","segments","pos","child","childEnd","isInlineNode","text","length","sliceFrom","Math","max","sliceTo","min","slice","push","marks","isTextNode","node","type","inlineType","isBlockNode","id","Array","isArray","children","isLeafBlock","every","c","getTextChildren","filter","getBlockChildren","generateBlockId","crypto","randomUUID","createDocument","createBlockNode","attrs","createTextNode","createInlineNode","getBlockText","getBlockLength","len","getBlockMarksAtOffset","offset","end","i","markSetsEqual","a","b","markA","some","markB","aAttrs","bAttrs","aKeys","Object","keys","bKeys","key","hasMark","markType","m","addMarkToSet","mark","removeMarkFromSet","normalizeInlineContent","nodes","n","result","prev","cleaned","next","getContentAtOffset","width","kind","localOffset","char"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HTMLUtils-0wvCRvJc.mjs","sources":["../../src/model/HTMLUtils.ts"],"sourcesContent":["/**\n * HTML string escaping utilities shared across serialization and parsing.\n */\n\n/** Escapes special HTML characters in text content. */\nexport function escapeHTML(text: string): string {\n\treturn text\n\t\t.replace(/&/g, '&')\n\t\t.replace(/</g, '<')\n\t\t.replace(/>/g, '>')\n\t\t.replace(/\"/g, '"');\n}\n"],"names":["escapeHTML","text","replace"],"mappings":"AAKO,SAASA,EAAWC,IAAAA;AAC1B,SAAOA,GACLC,QAAQ,MAAM,OAAA,EACdA,QAAQ,MAAM,MAAA,EACdA,QAAQ,MAAM,MAAA,EACdA,QAAQ,MAAM;AACjB;"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { a as n } from "./Document-CI3iCwEP.mjs";
|
|
2
|
+
function i(i2, r2) {
|
|
3
|
+
if (0 === r2.length) return;
|
|
4
|
+
let t2 = i2.children.find((n2) => n2.id === r2[0]);
|
|
5
|
+
if (t2) {
|
|
6
|
+
for (let i3 = 1; i3 < r2.length; i3++) {
|
|
7
|
+
const e2 = r2[i3];
|
|
8
|
+
if (!e2) return;
|
|
9
|
+
const o2 = t2?.children.find((i4) => n(i4) && i4.id === e2);
|
|
10
|
+
if (!o2) return;
|
|
11
|
+
t2 = o2;
|
|
12
|
+
}
|
|
13
|
+
return t2;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function r(r2, t2) {
|
|
17
|
+
if (0 === t2.length) return;
|
|
18
|
+
if (1 === t2.length) {
|
|
19
|
+
const n2 = r2.children.findIndex((n3) => n3.id === t2[0]);
|
|
20
|
+
if (-1 === n2) return;
|
|
21
|
+
return { parent: r2, index: n2 };
|
|
22
|
+
}
|
|
23
|
+
const e2 = i(r2, t2.slice(0, -1));
|
|
24
|
+
if (!e2) return;
|
|
25
|
+
const o2 = t2[t2.length - 1];
|
|
26
|
+
if (!o2) return;
|
|
27
|
+
const f2 = e2.children.findIndex((i2) => n(i2) && i2.id === o2);
|
|
28
|
+
return -1 !== f2 ? { parent: e2, index: f2 } : void 0;
|
|
29
|
+
}
|
|
30
|
+
function t(n2, i2) {
|
|
31
|
+
for (const r2 of n2.children) {
|
|
32
|
+
if (r2.id === i2) return [i2];
|
|
33
|
+
const n3 = e(r2, i2);
|
|
34
|
+
if (n3) return [r2.id, ...n3];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function e(i2, r2) {
|
|
38
|
+
for (const t2 of i2.children) {
|
|
39
|
+
if (!n(t2)) continue;
|
|
40
|
+
if (t2.id === r2) return [r2];
|
|
41
|
+
const i3 = e(t2, r2);
|
|
42
|
+
if (i3) return [t2.id, ...i3];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function o(n2, i2) {
|
|
46
|
+
for (const r2 of n2.children) f(r2, [r2.id], i2);
|
|
47
|
+
}
|
|
48
|
+
function f(i2, r2, t2) {
|
|
49
|
+
t2(i2, r2);
|
|
50
|
+
for (const e2 of i2.children) n(e2) && f(e2, [...r2, e2.id], t2);
|
|
51
|
+
}
|
|
52
|
+
function c(n2, i2) {
|
|
53
|
+
for (const r2 of n2.children) {
|
|
54
|
+
if (r2.id === i2) return r2;
|
|
55
|
+
const n3 = d(r2, i2);
|
|
56
|
+
if (n3) return n3;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function d(i2, r2) {
|
|
60
|
+
for (const t2 of i2.children) {
|
|
61
|
+
if (!n(t2)) continue;
|
|
62
|
+
if (t2.id === r2) return t2;
|
|
63
|
+
const i3 = d(t2, r2);
|
|
64
|
+
if (i3) return i3;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function u(n2, r2) {
|
|
68
|
+
const e2 = t(n2, r2);
|
|
69
|
+
if (!e2) return;
|
|
70
|
+
const o2 = i(n2, e2);
|
|
71
|
+
return o2 ? { node: o2, path: e2 } : void 0;
|
|
72
|
+
}
|
|
73
|
+
export {
|
|
74
|
+
c as a,
|
|
75
|
+
u as b,
|
|
76
|
+
r as c,
|
|
77
|
+
t as f,
|
|
78
|
+
i as r,
|
|
79
|
+
o as w
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=NodeResolver-D68ZLXti.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeResolver-D68ZLXti.mjs","sources":["../../src/model/NodeResolver.ts"],"sourcesContent":["/**\n * Utilities for resolving nodes by path within the document tree.\n * Supports both flat and recursive (nested) document structures.\n */\n\nimport type { BlockNode, Document } from './Document.js';\nimport { isBlockNode } from './Document.js';\n\n/**\n * Resolves a node in the document tree by its path (array of block IDs).\n * The path traces the lineage from the root block down to the target.\n */\nexport function resolveNodeByPath(doc: Document, path: readonly string[]): BlockNode | undefined {\n\tif (path.length === 0) return undefined;\n\n\tlet current: BlockNode | undefined = doc.children.find((b) => b.id === path[0]);\n\tif (!current) return undefined;\n\n\tfor (let i = 1; i < path.length; i++) {\n\t\tconst childId = path[i];\n\t\tif (!childId) return undefined;\n\t\tconst next: BlockNode | undefined = current?.children.find(\n\t\t\t(c): c is BlockNode => isBlockNode(c) && c.id === childId,\n\t\t);\n\t\tif (!next) return undefined;\n\t\tcurrent = next;\n\t}\n\n\treturn current;\n}\n\n/**\n * Resolves the parent of a node at the given path.\n * Returns the parent container (Document or BlockNode) and the child's index within it.\n */\nexport function resolveParentByPath(\n\tdoc: Document,\n\tpath: readonly string[],\n): { parent: Document | BlockNode; index: number } | undefined {\n\tif (path.length === 0) return undefined;\n\n\tif (path.length === 1) {\n\t\tconst index = doc.children.findIndex((b) => b.id === path[0]);\n\t\tif (index === -1) return undefined;\n\t\treturn { parent: doc, index };\n\t}\n\n\tconst parentPath = path.slice(0, -1);\n\tconst parent = resolveNodeByPath(doc, parentPath);\n\tif (!parent) return undefined;\n\n\tconst childId = path[path.length - 1];\n\tif (!childId) return undefined;\n\tconst index = parent.children.findIndex(\n\t\t(c): c is BlockNode => isBlockNode(c) && c.id === childId,\n\t);\n\tif (index === -1) return undefined;\n\n\treturn { parent, index };\n}\n\n/**\n * Finds the path (array of block IDs) to a node by its ID.\n * Performs recursive DFS through the document tree.\n */\nexport function findNodePath(doc: Document, nodeId: string): string[] | undefined {\n\tfor (const block of doc.children) {\n\t\tif (block.id === nodeId) return [nodeId];\n\n\t\tconst subPath = findNodePathInBlock(block, nodeId);\n\t\tif (subPath) return [block.id, ...subPath];\n\t}\n\treturn undefined;\n}\n\nfunction findNodePathInBlock(block: BlockNode, nodeId: string): string[] | undefined {\n\tfor (const child of block.children) {\n\t\tif (!isBlockNode(child)) continue;\n\t\tif (child.id === nodeId) return [nodeId];\n\n\t\tconst subPath = findNodePathInBlock(child, nodeId);\n\t\tif (subPath) return [child.id, ...subPath];\n\t}\n\treturn undefined;\n}\n\n/**\n * Walks all block nodes in the document tree in depth-first order.\n * Visits every BlockNode, including nested ones, with their full path.\n */\nexport function walkNodes(\n\tdoc: Document,\n\tcallback: (node: BlockNode, path: string[]) => void,\n): void {\n\tfor (const block of doc.children) {\n\t\twalkNodeRecursive(block, [block.id], callback);\n\t}\n}\n\nfunction walkNodeRecursive(\n\tnode: BlockNode,\n\tpath: string[],\n\tcallback: (node: BlockNode, path: string[]) => void,\n): void {\n\tcallback(node, path);\n\tfor (const child of node.children) {\n\t\tif (isBlockNode(child)) {\n\t\t\twalkNodeRecursive(child, [...path, child.id], callback);\n\t\t}\n\t}\n}\n\n/**\n * Finds a block node by ID anywhere in the document tree (recursive DFS).\n */\nexport function findNode(doc: Document, nodeId: string): BlockNode | undefined {\n\tfor (const block of doc.children) {\n\t\tif (block.id === nodeId) return block;\n\t\tconst found = findNodeInBlock(block, nodeId);\n\t\tif (found) return found;\n\t}\n\treturn undefined;\n}\n\nfunction findNodeInBlock(block: BlockNode, nodeId: string): BlockNode | undefined {\n\tfor (const child of block.children) {\n\t\tif (!isBlockNode(child)) continue;\n\t\tif (child.id === nodeId) return child;\n\t\tconst found = findNodeInBlock(child, nodeId);\n\t\tif (found) return found;\n\t}\n\treturn undefined;\n}\n\n/**\n * Finds a block node and returns it together with its path.\n */\nexport function findNodeWithPath(\n\tdoc: Document,\n\tnodeId: string,\n): { node: BlockNode; path: string[] } | undefined {\n\tconst path = findNodePath(doc, nodeId);\n\tif (!path) return undefined;\n\tconst node = resolveNodeByPath(doc, path);\n\tif (!node) return undefined;\n\treturn { node, path };\n}\n"],"names":["resolveNodeByPath","doc","path","length","current","children","find","b","id","i","childId","next","c","isBlockNode","resolveParentByPath","index","findIndex","parent","slice","findNodePath","nodeId","block","subPath","findNodePathInBlock","child","walkNodes","callback","walkNodeRecursive","node","findNode","found","findNodeInBlock","findNodeWithPath"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NodeSpec-NZVvcCuH.mjs","sources":["../../src/model/NodeSpec.ts"],"sourcesContent":["/**\n * NodeSpec: defines how a block-node type behaves and renders to the DOM.\n */\n\nimport type { NodeAttrsFor } from './AttrRegistry.js';\nimport type { BlockNode } from './Document.js';\nimport type { ParseRule } from './ParseRule.js';\nimport type { SanitizeConfig } from './SanitizeConfig.js';\nimport type { BlockId } from './TypeBrands.js';\n\nexport interface AttrSpec {\n\treadonly default?: string | number | boolean;\n}\n\n/** Describes a wrapper element that groups consecutive blocks of the same kind. */\nexport interface WrapperSpec {\n\t/** The HTML tag for the wrapper element (e.g., 'ul', 'ol'). */\n\treadonly tag: string;\n\t/** A key to group consecutive blocks. Blocks with the same key share a wrapper. */\n\treadonly key: string;\n\t/** Optional CSS class for the wrapper element. */\n\treadonly className?: string;\n\t/** Optional attributes for the wrapper element. */\n\treadonly attrs?: Readonly<Record<string, string>>;\n}\n\n/** Describes which children a node type is allowed to contain. */\nexport interface ContentRule {\n\t/** Allowed child types or group names. */\n\treadonly allow: readonly string[];\n\treadonly min?: number;\n\treadonly max?: number;\n}\n\n/** Creates an HTMLElement with the required `data-block-id` attribute. */\nexport function createBlockElement(tag: string, blockId: BlockId): HTMLElement {\n\tconst el = document.createElement(tag);\n\tel.setAttribute('data-block-id', blockId);\n\treturn el;\n}\n\nexport interface NodeSpec<T extends string = string> {\n\treadonly type: T;\n\t/** Renders the block to a DOM element. Must set `data-block-id` on the root. */\n\ttoDOM(node: Omit<BlockNode, 'attrs'> & { readonly attrs: NodeAttrsFor<T> }): HTMLElement;\n\treadonly attrs?: Readonly<Record<string, AttrSpec>>;\n\t/** If true, the node contains no editable text (e.g. Image, HR). */\n\treadonly isVoid?: boolean;\n\t/** Content model: which children this node can contain. */\n\treadonly content?: ContentRule;\n\t/** Group membership: 'block' | 'inline' | custom. */\n\treadonly group?: string;\n\t/** If true, selection cannot cross this node's boundary (e.g. table_cell). */\n\treadonly isolating?: boolean;\n\t/** If true, node can be selected as an object via mouse interaction. */\n\treadonly selectable?: boolean;\n\t/**\n\t * Mark types that are incompatible with this block type.\n\t * When a block is converted to this type, marks listed here\n\t * are stripped from the block's inline content.\n\t */\n\treadonly excludeMarks?: readonly string[];\n\t/** Serializes the block to an HTML string. `content` is the pre-serialized inline children. */\n\treadonly toHTML?: (node: BlockNode, content: string) => string;\n\t/** Rules for matching HTML elements to this block type during parsing. */\n\treadonly parseHTML?: readonly ParseRule[];\n\t/** Tags and attributes this spec needs through DOMPurify sanitization. */\n\treadonly sanitize?: SanitizeConfig;\n\t/**\n\t * If provided, the Reconciler groups consecutive blocks with the same\n\t * wrapper key into a shared wrapper element. Useful for semantic list\n\t * wrappers (`<ul>`, `<ol>`) around `<li>` block elements.\n\t */\n\twrapper?(node: Omit<BlockNode, 'attrs'> & { readonly attrs: NodeAttrsFor<T> }): WrapperSpec;\n}\n"],"names":["createBlockElement","tag","blockId","el","document","createElement","setAttribute"],"mappings":"AAmCO,SAASA,EAAmBC,IAAaC,GAAAA;AAC/C,QAAMC,IAAKC,SAASC,cAAcJ,EAAAA;AAElC,SADAE,EAAGG,aAAa,iBAAiBJ,CAAAA,GAC1BC;AACR;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Plugin-B9OZ6Y4c.mjs","sources":["../../src/plugins/Plugin.ts"],"sourcesContent":["/**\n * Plugin system types for the Notectl editor.\n */\n\nimport type { DecorationSet } from '../decorations/Decoration.js';\nimport type { InputRule } from '../input/InputRule.js';\nimport type { Keymap } from '../input/Keymap.js';\nimport type { InlineNodeSpec } from '../model/InlineNodeSpec.js';\nimport type { MarkSpec } from '../model/MarkSpec.js';\nimport type { NodeSpec } from '../model/NodeSpec.js';\nimport type { FileHandler } from '../model/SchemaRegistry.js';\nimport type { SchemaRegistry } from '../model/SchemaRegistry.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport type { NodeViewFactory } from '../view/NodeView.js';\nimport type { BlockTypePickerEntry } from './heading/BlockTypePickerEntry.js';\nimport type { ToolbarItem } from './toolbar/ToolbarItem.js';\n\n// --- Type-Safe Keys ---\n\n/** Type-safe event key for compile-time payload checking. */\nexport class EventKey<T> {\n\tdeclare readonly _type: T;\n\tconstructor(public readonly id: string) {}\n}\n\n/** Type-safe service key for compile-time type checking. */\nexport class ServiceKey<T> {\n\tdeclare readonly _type: T;\n\tconstructor(public readonly id: string) {}\n}\n\n// --- Command System ---\n\nexport type CommandHandler = () => boolean;\n\nexport interface CommandEntry {\n\treadonly name: string;\n\treadonly handler: CommandHandler;\n\treadonly pluginId: string;\n}\n\n// --- Event System ---\n\nexport type PluginEventCallback<T = unknown> = (payload: T) => void;\n\nexport interface PluginEventBus {\n\temit<T>(key: EventKey<T>, payload: T): void;\n\ton<T>(key: EventKey<T>, callback: PluginEventCallback<T>): () => void;\n\toff<T>(key: EventKey<T>, callback: PluginEventCallback<T>): void;\n}\n\n// --- Configuration ---\n\nexport type PluginConfig = Record<string, unknown>;\n\n// --- Middleware ---\n\nexport type MiddlewareNext = (tr: Transaction) => void;\nexport type TransactionMiddleware = (\n\ttr: Transaction,\n\tstate: EditorState,\n\tnext: MiddlewareNext,\n) => void;\n\n// --- Plugin Context ---\n\nexport interface PluginContext {\n\tgetState(): EditorState;\n\tdispatch(transaction: Transaction): void;\n\tgetContainer(): HTMLElement;\n\tgetPluginContainer(position: 'top' | 'bottom'): HTMLElement;\n\tregisterCommand(name: string, handler: CommandHandler): void;\n\texecuteCommand(name: string): boolean;\n\tgetEventBus(): PluginEventBus;\n\tregisterMiddleware(middleware: TransactionMiddleware, priority?: number): void;\n\tregisterService<T>(key: ServiceKey<T>, service: T): void;\n\tgetService<T>(key: ServiceKey<T>): T | undefined;\n\tupdateConfig(config: PluginConfig): void;\n\n\t// --- Schema Extension ---\n\tregisterNodeSpec<T extends string>(spec: NodeSpec<T>): void;\n\tregisterMarkSpec<T extends string>(spec: MarkSpec<T>): void;\n\tregisterNodeView(type: string, factory: NodeViewFactory): void;\n\tregisterKeymap(keymap: Keymap): void;\n\tregisterInputRule(rule: InputRule): void;\n\tregisterToolbarItem(item: ToolbarItem): void;\n\tregisterInlineNodeSpec<T extends string>(spec: InlineNodeSpec<T>): void;\n\tregisterFileHandler(pattern: string, handler: FileHandler): void;\n\tregisterBlockTypePickerEntry(entry: BlockTypePickerEntry): void;\n\tgetSchemaRegistry(): SchemaRegistry;\n\n\t/** Registers a CSS string to be added to the editor's adopted stylesheets. */\n\tregisterStyleSheet(css: string): void;\n\n\t/** Pushes a screen reader announcement via the editor's aria-live region. */\n\tannounce(text: string): void;\n}\n\n// --- Plugin Interface ---\n\nexport interface Plugin<TConfig extends Record<string, unknown> = Record<string, unknown>> {\n\treadonly id: string;\n\treadonly name: string;\n\treadonly priority?: number;\n\treadonly dependencies?: readonly string[];\n\n\tinit(context: PluginContext): void | Promise<void>;\n\tdestroy?(): void | Promise<void>;\n\tonStateChange?(oldState: EditorState, newState: EditorState, tr: Transaction): void;\n\tonConfigure?(config: TConfig): void;\n\t/** Called after ALL plugins have been initialized. */\n\tonReady?(): void | Promise<void>;\n\t/**\n\t * Returns decorations for the given state.\n\t * Called after state.apply() but BEFORE reconciliation.\n\t * Plugins should cache and only recompute when needed.\n\t */\n\tdecorations?(state: EditorState, tr?: Transaction): DecorationSet;\n}\n"],"names":["EventKey","id","this","ServiceKey"],"mappings":"AAqBO,MAAMA;EAEZ,YAA4BC,IAAAA;AAAAC,SAAAD,KAAAA;AAAAA,EAAa;AAAA;AAInC,MAAME,EAAAA;AAAAA,EAEZ,YAA4BF,IAAAA;AAAAC,SAAAD,KAAAA;AAAAA,EAAa;;"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function o(o2, n2) {
|
|
2
|
+
return { type: "node", nodeId: o2, path: n2 };
|
|
3
|
+
}
|
|
4
|
+
function n(o2) {
|
|
5
|
+
return "type" in o2 && "node" === o2.type;
|
|
6
|
+
}
|
|
7
|
+
function e(o2) {
|
|
8
|
+
return !n(o2);
|
|
9
|
+
}
|
|
10
|
+
function t(o2, t2) {
|
|
11
|
+
return n(o2) && n(t2) ? o2.nodeId === t2.nodeId : !(!e(o2) || !e(t2)) && o2.anchor.blockId === t2.anchor.blockId && o2.anchor.offset === t2.anchor.offset && o2.head.blockId === t2.head.blockId && o2.head.offset === t2.head.offset;
|
|
12
|
+
}
|
|
13
|
+
function a(o2, n2, e2) {
|
|
14
|
+
return e2 ? { blockId: o2, offset: n2, path: e2 } : { blockId: o2, offset: n2 };
|
|
15
|
+
}
|
|
16
|
+
function c(o2, n2) {
|
|
17
|
+
return { anchor: o2, head: n2 };
|
|
18
|
+
}
|
|
19
|
+
function d(o2, n2) {
|
|
20
|
+
const e2 = { blockId: o2, offset: n2 };
|
|
21
|
+
return { anchor: e2, head: e2 };
|
|
22
|
+
}
|
|
23
|
+
function f(o2) {
|
|
24
|
+
return !n(o2) && o2.anchor.blockId === o2.head.blockId && o2.anchor.offset === o2.head.offset;
|
|
25
|
+
}
|
|
26
|
+
function r(o2, e2) {
|
|
27
|
+
return !!n(o2) || (o2.anchor.blockId === o2.head.blockId ? o2.anchor.offset <= o2.head.offset : !e2 || e2.indexOf(o2.anchor.blockId) <= e2.indexOf(o2.head.blockId));
|
|
28
|
+
}
|
|
29
|
+
function h(o2, n2) {
|
|
30
|
+
return r(o2, n2) ? { from: o2.anchor, to: o2.head } : { from: o2.head, to: o2.anchor };
|
|
31
|
+
}
|
|
32
|
+
export {
|
|
33
|
+
f as a,
|
|
34
|
+
o as b,
|
|
35
|
+
d as c,
|
|
36
|
+
c as d,
|
|
37
|
+
a as e,
|
|
38
|
+
e as f,
|
|
39
|
+
t as g,
|
|
40
|
+
r as h,
|
|
41
|
+
n as i,
|
|
42
|
+
h as s
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=Selection-D5ZjXoB7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Selection-D5ZjXoB7.mjs","sources":["../../src/model/Selection.ts"],"sourcesContent":["/**\n * Selection model for the Notectl editor.\n * A selection is defined by an anchor and head position within the document.\n */\n\nimport type { BlockId } from './TypeBrands.js';\n\nexport interface Position {\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n\t/** Path from root block to leaf block (optional, for nested structures). */\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface Selection {\n\treadonly anchor: Position;\n\treadonly head: Position;\n}\n\nexport interface SelectionRange {\n\treadonly from: Position;\n\treadonly to: Position;\n}\n\n/** A selection that selects an entire node (e.g. void blocks, table selection). */\nexport interface NodeSelection {\n\treadonly type: 'node';\n\treadonly nodeId: BlockId;\n\treadonly path: readonly BlockId[];\n}\n\n/** Union type representing either a text selection or a node selection. */\nexport type EditorSelection = Selection | NodeSelection;\n\n/** Creates a NodeSelection for the given block. */\nexport function createNodeSelection(nodeId: BlockId, path: readonly BlockId[]): NodeSelection {\n\treturn { type: 'node', nodeId, path };\n}\n\n/** Type guard: returns true if the selection is a NodeSelection. */\nexport function isNodeSelection(sel: EditorSelection): sel is NodeSelection {\n\treturn 'type' in sel && sel.type === 'node';\n}\n\n/** Type guard: returns true if the selection is a text Selection. */\nexport function isTextSelection(sel: EditorSelection): sel is Selection {\n\treturn !isNodeSelection(sel);\n}\n\n/** Compares two EditorSelections for equality. */\nexport function selectionsEqual(a: EditorSelection, b: EditorSelection): boolean {\n\tif (isNodeSelection(a) && isNodeSelection(b)) {\n\t\treturn a.nodeId === b.nodeId;\n\t}\n\tif (isTextSelection(a) && isTextSelection(b)) {\n\t\treturn (\n\t\t\ta.anchor.blockId === b.anchor.blockId &&\n\t\t\ta.anchor.offset === b.anchor.offset &&\n\t\t\ta.head.blockId === b.head.blockId &&\n\t\t\ta.head.offset === b.head.offset\n\t\t);\n\t}\n\treturn false;\n}\n\n/** Creates a Position, optionally with a path. */\nexport function createPosition(\n\tblockId: BlockId,\n\toffset: number,\n\tpath?: readonly BlockId[],\n): Position {\n\treturn path ? { blockId, offset, path } : { blockId, offset };\n}\n\n/** Creates a selection with distinct anchor and head. */\nexport function createSelection(anchor: Position, head: Position): Selection {\n\treturn { anchor, head };\n}\n\n/** Creates a collapsed selection (cursor) at the given position. */\nexport function createCollapsedSelection(blockId: BlockId, offset: number): Selection {\n\tconst pos: Position = { blockId, offset };\n\treturn { anchor: pos, head: pos };\n}\n\n/** Returns true if the selection is collapsed (cursor with no range). NodeSelection is never collapsed. */\nexport function isCollapsed(sel: EditorSelection): boolean {\n\tif (isNodeSelection(sel)) return false;\n\treturn sel.anchor.blockId === sel.head.blockId && sel.anchor.offset === sel.head.offset;\n}\n\n/**\n * Returns true if the selection direction is forward (anchor before head).\n * When anchor and head are in the same block, compares offsets.\n * Cross-block ordering uses document order (not determinable here — caller provides block order).\n * For NodeSelection, always returns true.\n */\nexport function isForward(sel: EditorSelection, blockOrder?: readonly BlockId[]): boolean {\n\tif (isNodeSelection(sel)) return true;\n\tif (sel.anchor.blockId === sel.head.blockId) {\n\t\treturn sel.anchor.offset <= sel.head.offset;\n\t}\n\tif (blockOrder) {\n\t\tconst anchorIdx = blockOrder.indexOf(sel.anchor.blockId);\n\t\tconst headIdx = blockOrder.indexOf(sel.head.blockId);\n\t\treturn anchorIdx <= headIdx;\n\t}\n\treturn true;\n}\n\n/**\n * Returns a normalized range where `from` is always before `to`.\n * Throws for NodeSelection — use isNodeSelection() guard first.\n */\nexport function selectionRange(sel: Selection, blockOrder?: readonly BlockId[]): SelectionRange {\n\tif (isForward(sel, blockOrder)) {\n\t\treturn { from: sel.anchor, to: sel.head };\n\t}\n\treturn { from: sel.head, to: sel.anchor };\n}\n"],"names":["createNodeSelection","nodeId","path","type","isNodeSelection","sel","isTextSelection","selectionsEqual","a","b","anchor","blockId","offset","head","createPosition","createSelection","createCollapsedSelection","pos","isCollapsed","isForward","blockOrder","indexOf","selectionRange","from","to"],"mappings":"AAmCO,SAASA,EAAoBC,IAAiBC,IAAAA;AACpD,SAAO,EAAEC,MAAM,QAAQF,YAAQC,MAAAA,GAAAA;AAChC;AAGO,SAASE,EAAgBC,IAAAA;AAC/B,SAAO,UAAUA,MAAoB,WAAbA,GAAIF;AAC7B;AAGO,SAASG,EAAgBD;AAC/B,SAAA,CAAQD,EAAgBC;AACzB;AAGO,SAASE,EAAgBC,IAAoBC,IAAAA;AACnD,SAAIL,EAAgBI,EAAAA,KAAMJ,EAAgBK,EAAAA,IAClCD,GAAEP,WAAWQ,GAAER,SAAAA,EAAAA,CAEnBK,EAAgBE,EAAAA,KAAAA,CAAMF,EAAgBG,QAExCD,GAAEE,OAAOC,YAAYF,GAAEC,OAAOC,WAC9BH,GAAEE,OAAOE,WAAWH,GAAEC,OAAOE,UAC7BJ,GAAEK,KAAKF,YAAYF,GAAEI,KAAKF,WAC1BH,GAAEK,KAAKD,WAAWH,GAAEI,KAAKD;AAI5B;AAGO,SAASE,EACfH,IACAC,IACAV;AAEA,SAAOA,KAAO,EAAES,SAAAA,IAASC,QAAAA,IAAQV,aAAS,EAAES,SAAAA,IAASC;AACtD;AAGO,SAASG,EAAgBL,IAAkBG,IAAAA;AACjD,SAAO,EAAEH,QAAAA,IAAQG,MAAAA,GAAAA;AAClB;AAGO,SAASG,EAAyBL,IAAkBC,IAAAA;AAC1D,QAAMK,KAAgB,EAAEN,SAAAA,IAASC;AACjC,SAAO,EAAEF,QAAQO,IAAKJ,MAAMI;AAC7B;AAGO,SAASC,EAAYb,IAAAA;AAC3B,SAAA,CAAID,EAAgBC,EAAAA,KACbA,GAAIK,OAAOC,YAAYN,GAAIQ,KAAKF,WAAWN,GAAIK,OAAOE,WAAWP,GAAIQ,KAAKD;AAClF;AAQO,SAASO,EAAUd,IAAsBe;AAC/C,SAAA,CAAA,CAAIhB,EAAgBC,QAChBA,GAAIK,OAAOC,YAAYN,GAAIQ,KAAKF,UAC5BN,GAAIK,OAAOE,UAAUP,GAAIQ,KAAKD,UAElCQ,MACeA,GAAWC,QAAQhB,GAAIK,OAAOC,YAChCS,GAAWC,QAAQhB,GAAIQ,KAAKF,OAAAA;AAI9C;AAMO,SAASW,EAAejB,IAAgBe,IAAAA;AAC9C,SAAID,EAAUd,IAAKe,EAAAA,IACX,EAAEG,MAAMlB,GAAIK,QAAQc,IAAInB,GAAIQ,SAE7B,EAAEU,MAAMlB,GAAIQ,MAAMW,IAAInB,GAAIK,OAAAA;AAClC;"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
function e(e2) {
|
|
2
|
+
return "undefined" != typeof navigator && /Mac|iPhone|iPad|iPod/.test(navigator.platform) ? e2.replace(/Mod/g, "⌘").replace(/Shift/g, "⇧").replace(/Alt/g, "⌥").replace(/-/g, "") : e2.replace(/Mod/g, "Ctrl").replace(/-/g, "+");
|
|
3
|
+
}
|
|
4
|
+
export {
|
|
5
|
+
e as f
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=ToolbarItem-ugDymuXi.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolbarItem-ugDymuXi.mjs","sources":["../../src/plugins/toolbar/ToolbarItem.ts"],"sourcesContent":["/**\n * ToolbarItem: describes a toolbar button registered by a plugin.\n */\n\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { PluginContext } from '../Plugin.js';\n\nexport interface GridPickerConfig {\n\treadonly maxRows: number;\n\treadonly maxCols: number;\n\tonSelect(rows: number, cols: number): void;\n}\n\nexport interface DropdownConfig {\n\treadonly items: readonly { label: string; command: string; icon?: string }[];\n}\n\nexport type ToolbarGroup = 'format' | 'block' | 'insert' | (string & {});\nexport type PopupType = 'gridPicker' | 'dropdown' | 'custom';\n\ninterface ToolbarItemBase {\n\treadonly id: string;\n\t/** Grouping key: 'format' | 'insert' | 'block' or custom. */\n\treadonly group: ToolbarGroup;\n\t/** Icon content: inline SVG markup or plain text. Rendered via innerHTML. */\n\treadonly icon: string;\n\treadonly label: string;\n\t/** Tooltip shown on hover, e.g. \"Bold (Ctrl+B)\". Falls back to label. */\n\treadonly tooltip?: string;\n\t/** Command name to execute on click. */\n\treadonly command: string;\n\t/**\n\t * Lower priority renders further left.\n\t * @deprecated Use the declarative `toolbar` config on `createEditor()` instead.\n\t */\n\treadonly priority?: number;\n\t/**\n\t * When true, a visual separator is rendered after this item.\n\t * @deprecated Use the declarative `toolbar` config on `createEditor()` instead.\n\t */\n\treadonly separatorAfter?: boolean;\n\tisActive?(state: EditorState): boolean;\n\tisEnabled?(state: EditorState): boolean;\n}\n\ninterface ToolbarItemNoPopup extends ToolbarItemBase {\n\treadonly popupType?: undefined;\n}\n\ninterface ToolbarItemGridPicker extends ToolbarItemBase {\n\treadonly popupType: 'gridPicker';\n\treadonly popupConfig: GridPickerConfig;\n}\n\ninterface ToolbarItemDropdown extends ToolbarItemBase {\n\treadonly popupType: 'dropdown';\n\treadonly popupConfig: DropdownConfig;\n}\n\ninterface ToolbarItemCustomPopup extends ToolbarItemBase {\n\treadonly popupType: 'custom';\n\trenderPopup(container: HTMLElement, context: PluginContext, onClose: () => void): void;\n}\n\nexport type ToolbarItem =\n\t| ToolbarItemNoPopup\n\t| ToolbarItemGridPicker\n\t| ToolbarItemDropdown\n\t| ToolbarItemCustomPopup;\n\n/**\n * Formats a keymap binding string into a human-readable shortcut,\n * using platform-appropriate modifier symbols (⌘ on Mac, Ctrl on others).\n *\n * @example formatShortcut('Mod-B') → \"Ctrl+B\" or \"⌘B\"\n * @example formatShortcut('Mod-Shift-X') → \"Ctrl+Shift+X\" or \"⌘⇧X\"\n */\nexport function formatShortcut(binding: string): string {\n\tconst isMac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad|iPod/.test(navigator.platform);\n\tif (isMac) {\n\t\treturn binding\n\t\t\t.replace(/Mod/g, '⌘')\n\t\t\t.replace(/Shift/g, '⇧')\n\t\t\t.replace(/Alt/g, '⌥')\n\t\t\t.replace(/-/g, '');\n\t}\n\treturn binding.replace(/Mod/g, 'Ctrl').replace(/-/g, '+');\n}\n"],"names":["formatShortcut","binding","navigator","test","platform","replace"],"mappings":"AA6EO,SAASA,EAAeC,IAAAA;AAE9B,SADmC,eAAA,OAAdC,aAA6B,uBAAuBC,KAAKD,UAAUE,QAAAA,IAEhFH,GACLI,QAAQ,QAAQ,GAAA,EAChBA,QAAQ,UAAU,GAAA,EAClBA,QAAQ,QAAQ,GAAA,EAChBA,QAAQ,MAAM,EAAA,IAEVJ,GAAQI,QAAQ,QAAQ,MAAA,EAAQA,QAAQ,MAAM;AACtD;"}
|