@notectl/core 1.0.4 → 1.0.6
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 +52 -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-sJTiZr-S.mjs +398 -0
- package/dist/chunks/ToolbarPlugin-sJTiZr-S.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-QvKiO9_4.mjs +538 -0
- package/dist/chunks/index-QvKiO9_4.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 +135 -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 +83 -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 +2715 -11109
- package/dist/notectl-core.mjs.map +1 -1
- package/dist/notectl-core.umd.js +6894 -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 +68 -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/CodeBlockCommands.d.ts +5 -0
- package/dist/plugins/code-block/CodeBlockCommands.d.ts.map +1 -0
- package/dist/plugins/code-block/CodeBlockKeyboardHandlers.d.ts +10 -0
- package/dist/plugins/code-block/CodeBlockKeyboardHandlers.d.ts.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 +27 -0
- package/dist/plugins/code-block/CodeBlockPlugin.d.ts.map +1 -0
- package/dist/plugins/code-block/CodeBlockService.d.ts +5 -0
- package/dist/plugins/code-block/CodeBlockService.d.ts.map +1 -0
- package/dist/plugins/code-block/CodeBlockTypes.d.ts +69 -0
- package/dist/plugins/code-block/CodeBlockTypes.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/FontSizeOperations.d.ts +22 -0
- package/dist/plugins/font-size/FontSizeOperations.d.ts.map +1 -0
- package/dist/plugins/font-size/FontSizePlugin.d.ts +56 -0
- package/dist/plugins/font-size/FontSizePlugin.d.ts.map +1 -0
- package/dist/plugins/font-size/FontSizePopup.d.ts +9 -0
- package/dist/plugins/font-size/FontSizePopup.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 +204 -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/print/PrintContentPreparer.d.ts +12 -0
- package/dist/plugins/print/PrintContentPreparer.d.ts.map +1 -0
- package/dist/plugins/print/PrintPlugin.d.ts +12 -0
- package/dist/plugins/print/PrintPlugin.d.ts.map +1 -0
- package/dist/plugins/print/PrintServiceImpl.d.ts +7 -0
- package/dist/plugins/print/PrintServiceImpl.d.ts.map +1 -0
- package/dist/plugins/print/PrintStyleCollector.d.ts +10 -0
- package/dist/plugins/print/PrintStyleCollector.d.ts.map +1 -0
- package/dist/plugins/print/PrintTypes.d.ts +56 -0
- package/dist/plugins/print/PrintTypes.d.ts.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,127 @@
|
|
|
1
|
+
import { t } from "../chunks/Commands-DLP85Mp5.mjs";
|
|
2
|
+
import { e, h as n } from "../chunks/Document-CI3iCwEP.mjs";
|
|
3
|
+
import { e as r } from "../chunks/HTMLUtils-0wvCRvJc.mjs";
|
|
4
|
+
import { a as o, i, s } from "../chunks/Selection-D5ZjXoB7.mjs";
|
|
5
|
+
import { m as a } from "../chunks/TypeBrands-C09nE2qO.mjs";
|
|
6
|
+
import { f as c } from "../chunks/ToolbarItem-ugDymuXi.mjs";
|
|
7
|
+
const l = { openInNewTab: true };
|
|
8
|
+
class p {
|
|
9
|
+
id = "link";
|
|
10
|
+
name = "Link";
|
|
11
|
+
priority = 25;
|
|
12
|
+
config;
|
|
13
|
+
constructor(t2) {
|
|
14
|
+
this.config = { ...l, ...t2 };
|
|
15
|
+
}
|
|
16
|
+
init(t2) {
|
|
17
|
+
this.registerMarkSpec(t2), this.registerCommands(t2), this.registerKeymap(t2), this.registerToolbarItem(t2);
|
|
18
|
+
}
|
|
19
|
+
registerMarkSpec(t2) {
|
|
20
|
+
const e2 = this.config.openInNewTab;
|
|
21
|
+
t2.registerMarkSpec({ type: "link", rank: 10, attrs: { href: { default: "" } }, toDOM(t3) {
|
|
22
|
+
const n2 = document.createElement("a"), r2 = t3.attrs?.href ?? "";
|
|
23
|
+
return n2.setAttribute("href", r2), e2 && (n2.setAttribute("target", "_blank"), n2.setAttribute("rel", "noopener noreferrer")), n2;
|
|
24
|
+
}, toHTMLString: (t3, e3) => `<a href="${r(String(t3.attrs?.href ?? ""))}">${e3}</a>`, parseHTML: [{ tag: "a", getAttrs: (t3) => ({ href: t3.getAttribute("href") ?? "" }) }], sanitize: { tags: ["a"], attrs: ["href", "target", "rel"] } });
|
|
25
|
+
}
|
|
26
|
+
registerCommands(t2) {
|
|
27
|
+
t2.registerCommand("toggleLink", () => {
|
|
28
|
+
const e2 = t2.getState();
|
|
29
|
+
return this.toggleLink(t2, e2);
|
|
30
|
+
}), t2.registerCommand("setLink", () => false), t2.registerCommand("removeLink", () => {
|
|
31
|
+
const e2 = t2.getState();
|
|
32
|
+
return this.removeLink(t2, e2);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
registerKeymap(t2) {
|
|
36
|
+
t2.registerKeymap({ "Mod-K": () => t2.executeCommand("toggleLink") });
|
|
37
|
+
}
|
|
38
|
+
registerToolbarItem(t2) {
|
|
39
|
+
t2.registerToolbarItem({ id: "link", group: "insert", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>', label: "Link", tooltip: `Insert Link (${c("Mod-K")})`, command: "toggleLink", priority: 60, popupType: "custom", separatorAfter: this.config.separatorAfter, renderPopup: (t3, e2) => {
|
|
40
|
+
this.renderLinkPopup(t3, e2);
|
|
41
|
+
}, isActive: (t3) => this.isLinkActive(t3), isEnabled: (t3) => !o(t3.selection) });
|
|
42
|
+
}
|
|
43
|
+
isLinkActive(t2) {
|
|
44
|
+
const r2 = t2.selection;
|
|
45
|
+
if (i(r2)) return false;
|
|
46
|
+
if (o(r2)) {
|
|
47
|
+
const o2 = t2.getBlock(r2.anchor.blockId);
|
|
48
|
+
if (!o2) return false;
|
|
49
|
+
const i2 = e(o2, r2.anchor.offset);
|
|
50
|
+
return n(i2, a("link"));
|
|
51
|
+
}
|
|
52
|
+
const s2 = t2.getBlock(r2.anchor.blockId);
|
|
53
|
+
if (!s2) return false;
|
|
54
|
+
const c2 = e(s2, r2.anchor.offset);
|
|
55
|
+
return n(c2, a("link"));
|
|
56
|
+
}
|
|
57
|
+
toggleLink(t2, e2) {
|
|
58
|
+
return !!this.isLinkActive(e2) && this.removeLink(t2, e2);
|
|
59
|
+
}
|
|
60
|
+
addLink(e2, n2, r2) {
|
|
61
|
+
const c2 = n2.selection;
|
|
62
|
+
if (i(c2)) return false;
|
|
63
|
+
if (o(c2)) return false;
|
|
64
|
+
const l2 = s(c2, n2.getBlockOrder()), p2 = n2.transaction("command"), d = { type: a("link"), attrs: { href: r2 } };
|
|
65
|
+
return t(n2, l2, (t2, e3, n3) => {
|
|
66
|
+
p2.addMark(t2, e3, n3, d);
|
|
67
|
+
}), p2.setSelection(c2), e2.dispatch(p2.build()), true;
|
|
68
|
+
}
|
|
69
|
+
removeLink(e2, r2) {
|
|
70
|
+
const c2 = r2.selection;
|
|
71
|
+
if (i(c2)) return false;
|
|
72
|
+
const l2 = r2.getBlockOrder(), p2 = o(c2) ? { from: c2.anchor, to: c2.anchor } : s(c2, l2), d = r2.transaction("command");
|
|
73
|
+
if (o(c2)) {
|
|
74
|
+
const t2 = r2.getBlock(c2.anchor.blockId);
|
|
75
|
+
if (!t2) return false;
|
|
76
|
+
const e3 = [];
|
|
77
|
+
let o2 = 0;
|
|
78
|
+
for (const r3 of t2.children) {
|
|
79
|
+
if (!("text" in r3)) continue;
|
|
80
|
+
const t3 = o2 + r3.text.length;
|
|
81
|
+
e3.push({ pos: o2, end: t3, hasLink: n(r3.marks, a("link")) }), o2 = t3;
|
|
82
|
+
}
|
|
83
|
+
const i2 = e3.findIndex((t3) => c2.anchor.offset >= t3.pos && c2.anchor.offset <= t3.end), s2 = i2 >= 0 ? e3[i2] : void 0;
|
|
84
|
+
if (-1 === i2 || !s2?.hasLink) return false;
|
|
85
|
+
let l3 = i2;
|
|
86
|
+
for (; l3 > 0 && e3[l3 - 1]?.hasLink; ) l3--;
|
|
87
|
+
let p3 = i2;
|
|
88
|
+
for (; p3 < e3.length - 1 && e3[p3 + 1]?.hasLink; ) p3++;
|
|
89
|
+
const m = e3[l3], h = e3[p3];
|
|
90
|
+
if (!m || !h) return false;
|
|
91
|
+
const u = m.pos, k = h.end;
|
|
92
|
+
d.removeMark(c2.anchor.blockId, u, k, { type: a("link") });
|
|
93
|
+
} else t(r2, p2, (t2, e3, n2) => {
|
|
94
|
+
d.removeMark(t2, e3, n2, { type: a("link") });
|
|
95
|
+
});
|
|
96
|
+
return d.setSelection(c2), e2.dispatch(d.build()), true;
|
|
97
|
+
}
|
|
98
|
+
renderLinkPopup(t2, e2) {
|
|
99
|
+
t2.style.padding = "8px", t2.style.minWidth = "200px";
|
|
100
|
+
const n2 = e2.getState();
|
|
101
|
+
if (this.isLinkActive(n2)) {
|
|
102
|
+
const n3 = document.createElement("button");
|
|
103
|
+
n3.type = "button", n3.textContent = "Remove Link", n3.setAttribute("aria-label", "Remove link"), n3.style.cssText = "width:100%;padding:6px 12px;cursor:pointer;", n3.addEventListener("mousedown", (t3) => {
|
|
104
|
+
t3.preventDefault(), t3.stopPropagation(), e2.executeCommand("removeLink");
|
|
105
|
+
}), t2.appendChild(n3);
|
|
106
|
+
} else {
|
|
107
|
+
const n3 = document.createElement("input");
|
|
108
|
+
n3.type = "url", n3.placeholder = "https://...", n3.setAttribute("aria-label", "URL"), n3.style.cssText = "width:100%;padding:4px;box-sizing:border-box;";
|
|
109
|
+
const r2 = document.createElement("button");
|
|
110
|
+
r2.type = "button", r2.textContent = "Apply", r2.setAttribute("aria-label", "Apply link"), r2.style.cssText = "width:100%;padding:6px 12px;margin-top:4px;cursor:pointer;", r2.addEventListener("mousedown", (t3) => {
|
|
111
|
+
t3.preventDefault(), t3.stopPropagation();
|
|
112
|
+
const r3 = n3.value.trim();
|
|
113
|
+
r3 && this.addLink(e2, e2.getState(), r3);
|
|
114
|
+
}), n3.addEventListener("keydown", (t3) => {
|
|
115
|
+
if ("Enter" === t3.key) {
|
|
116
|
+
t3.preventDefault();
|
|
117
|
+
const r3 = n3.value.trim();
|
|
118
|
+
r3 && this.addLink(e2, e2.getState(), r3);
|
|
119
|
+
}
|
|
120
|
+
}), t2.appendChild(n3), t2.appendChild(r2), requestAnimationFrame(() => n3.focus());
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
export {
|
|
125
|
+
p as LinkPlugin
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=link.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.mjs","sources":["../../src/plugins/link/LinkPlugin.ts"],"sourcesContent":["/**\n * LinkPlugin: registers a link mark type with href attribute,\n * toggle command, keyboard shortcut (Mod-K), and toolbar button\n * with a URL input popup.\n */\n\nimport { forEachBlockInRange } from '../../commands/Commands.js';\nimport { getBlockMarksAtOffset, hasMark } from '../../model/Document.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport { isCollapsed, isNodeSelection, selectionRange } from '../../model/Selection.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tlink: { href: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface LinkConfig {\n\t/** Whether to add rel=\"noopener noreferrer\" and target=\"_blank\" by default. */\n\treadonly openInNewTab: boolean;\n\t/** When true, a separator is rendered after the link toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: LinkConfig = {\n\topenInNewTab: true,\n};\n\n// --- Plugin ---\n\nexport class LinkPlugin implements Plugin {\n\treadonly id = 'link';\n\treadonly name = 'Link';\n\treadonly priority = 25;\n\n\tprivate readonly config: LinkConfig;\n\n\tconstructor(config?: Partial<LinkConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymap(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tconst openInNewTab = this.config.openInNewTab;\n\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'link',\n\t\t\trank: 10,\n\t\t\tattrs: {\n\t\t\t\thref: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst a = document.createElement('a');\n\t\t\t\tconst href = mark.attrs?.href ?? '';\n\t\t\t\ta.setAttribute('href', href);\n\t\t\t\tif (openInNewTab) {\n\t\t\t\t\ta.setAttribute('target', '_blank');\n\t\t\t\t\ta.setAttribute('rel', 'noopener noreferrer');\n\t\t\t\t}\n\t\t\t\treturn a;\n\t\t\t},\n\t\t\ttoHTMLString: (mark, content) => {\n\t\t\t\tconst href: string = escapeHTML(String(mark.attrs?.href ?? ''));\n\t\t\t\treturn `<a href=\"${href}\">${content}</a>`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'a',\n\t\t\t\t\tgetAttrs: (el) => {\n\t\t\t\t\t\tconst href: string = el.getAttribute('href') ?? '';\n\t\t\t\t\t\treturn { href };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['a'], attrs: ['href', 'target', 'rel'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('toggleLink', () => {\n\t\t\tconst state = context.getState();\n\t\t\treturn this.toggleLink(context, state);\n\t\t});\n\n\t\tcontext.registerCommand('setLink', () => {\n\t\t\t// setLink is called by the popup after URL input\n\t\t\t// The actual URL is set via the popup's custom render\n\t\t\treturn false;\n\t\t});\n\n\t\tcontext.registerCommand('removeLink', () => {\n\t\t\tconst state = context.getState();\n\t\t\treturn this.removeLink(context, state);\n\t\t});\n\t}\n\n\tprivate registerKeymap(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-K': () => context.executeCommand('toggleLink'),\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon =\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z\"/></svg>';\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'link',\n\t\t\tgroup: 'insert',\n\t\t\ticon,\n\t\t\tlabel: 'Link',\n\t\t\ttooltip: `Insert Link (${formatShortcut('Mod-K')})`,\n\t\t\tcommand: 'toggleLink',\n\t\t\tpriority: 60,\n\t\t\tpopupType: 'custom',\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\trenderPopup: (container, ctx) => {\n\t\t\t\tthis.renderLinkPopup(container, ctx);\n\t\t\t},\n\t\t\tisActive: (state) => this.isLinkActive(state),\n\t\t\tisEnabled: (state) => !isCollapsed(state.selection),\n\t\t});\n\t}\n\n\tprivate isLinkActive(state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\t\tif (isNodeSelection(sel)) return false;\n\t\tif (isCollapsed(sel)) {\n\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!block) return false;\n\t\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\t\treturn hasMark(marks, markType('link'));\n\t\t}\n\n\t\t// Check if link is active anywhere in selection\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return false;\n\t\tconst marks = getBlockMarksAtOffset(block, sel.anchor.offset);\n\t\treturn hasMark(marks, markType('link'));\n\t}\n\n\tprivate toggleLink(context: PluginContext, state: EditorState): boolean {\n\t\tif (this.isLinkActive(state)) {\n\t\t\treturn this.removeLink(context, state);\n\t\t}\n\t\t// Adding links requires the toolbar popup for URL input\n\t\treturn false;\n\t}\n\n\tprivate addLink(context: PluginContext, state: EditorState, href: string): boolean {\n\t\tconst sel = state.selection;\n\t\tif (isNodeSelection(sel)) return false;\n\t\tif (isCollapsed(sel)) return false;\n\n\t\tconst range = selectionRange(sel, state.getBlockOrder());\n\t\tconst builder = state.transaction('command');\n\t\tconst mark = { type: markType('link'), attrs: { href } };\n\n\t\tforEachBlockInRange(state, range, (blockId, from, to) => {\n\t\t\tbuilder.addMark(blockId, from, to, mark);\n\t\t});\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\tprivate removeLink(context: PluginContext, state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\t\tif (isNodeSelection(sel)) return false;\n\t\tconst blockOrder = state.getBlockOrder();\n\t\tconst range = isCollapsed(sel)\n\t\t\t? { from: sel.anchor, to: sel.anchor }\n\t\t\t: selectionRange(sel, blockOrder);\n\n\t\tconst builder = state.transaction('command');\n\n\t\tif (isCollapsed(sel)) {\n\t\t\t// Remove link from entire link span around cursor\n\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\tif (!block) return false;\n\n\t\t\t// Find the extent of the link mark around the cursor.\n\t\t\t// Build a list of text children with their positions first,\n\t\t\t// then scan backward and forward from the cursor node.\n\t\t\tconst textChildren: { pos: number; end: number; hasLink: boolean }[] = [];\n\t\t\tlet pos = 0;\n\t\t\tfor (const child of block.children) {\n\t\t\t\tif (!('text' in child)) continue;\n\t\t\t\tconst end = pos + child.text.length;\n\t\t\t\ttextChildren.push({ pos, end, hasLink: hasMark(child.marks, markType('link')) });\n\t\t\t\tpos = end;\n\t\t\t}\n\n\t\t\t// Find the text child containing the cursor\n\t\t\tconst cursorIdx = textChildren.findIndex(\n\t\t\t\t(c) => sel.anchor.offset >= c.pos && sel.anchor.offset <= c.end,\n\t\t\t);\n\t\t\tconst cursorEntry = cursorIdx >= 0 ? textChildren[cursorIdx] : undefined;\n\t\t\tif (cursorIdx === -1 || !cursorEntry?.hasLink) return false;\n\n\t\t\t// Scan backward from cursor node to find link start\n\t\t\tlet startIdx = cursorIdx;\n\t\t\twhile (startIdx > 0 && textChildren[startIdx - 1]?.hasLink) {\n\t\t\t\tstartIdx--;\n\t\t\t}\n\n\t\t\t// Scan forward from cursor node to find link end\n\t\t\tlet endIdx = cursorIdx;\n\t\t\twhile (endIdx < textChildren.length - 1 && textChildren[endIdx + 1]?.hasLink) {\n\t\t\t\tendIdx++;\n\t\t\t}\n\n\t\t\tconst startEntry = textChildren[startIdx];\n\t\t\tconst endEntry = textChildren[endIdx];\n\t\t\tif (!startEntry || !endEntry) return false;\n\n\t\t\tconst linkStart = startEntry.pos;\n\t\t\tconst linkEnd = endEntry.end;\n\n\t\t\tbuilder.removeMark(sel.anchor.blockId, linkStart, linkEnd, { type: markType('link') });\n\t\t} else {\n\t\t\t// Remove link from selection range\n\t\t\tforEachBlockInRange(state, range, (blockId, from, to) => {\n\t\t\t\tbuilder.removeMark(blockId, from, to, { type: markType('link') });\n\t\t\t});\n\t\t}\n\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\tprivate renderLinkPopup(container: HTMLElement, context: PluginContext): void {\n\t\tcontainer.style.padding = '8px';\n\t\tcontainer.style.minWidth = '200px';\n\n\t\tconst state = context.getState();\n\t\tconst isActive = this.isLinkActive(state);\n\n\t\tif (isActive) {\n\t\t\t// Show remove link button\n\t\t\tconst removeBtn = document.createElement('button');\n\t\t\tremoveBtn.type = 'button';\n\t\t\tremoveBtn.textContent = 'Remove Link';\n\t\t\tremoveBtn.setAttribute('aria-label', 'Remove link');\n\t\t\tremoveBtn.style.cssText = 'width:100%;padding:6px 12px;cursor:pointer;';\n\t\t\tremoveBtn.addEventListener('mousedown', (e) => {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tcontext.executeCommand('removeLink');\n\t\t\t});\n\t\t\tcontainer.appendChild(removeBtn);\n\t\t} else {\n\t\t\t// Show URL input\n\t\t\tconst input = document.createElement('input');\n\t\t\tinput.type = 'url';\n\t\t\tinput.placeholder = 'https://...';\n\t\t\tinput.setAttribute('aria-label', 'URL');\n\t\t\tinput.style.cssText = 'width:100%;padding:4px;box-sizing:border-box;';\n\n\t\t\tconst applyBtn = document.createElement('button');\n\t\t\tapplyBtn.type = 'button';\n\t\t\tapplyBtn.textContent = 'Apply';\n\t\t\tapplyBtn.setAttribute('aria-label', 'Apply link');\n\t\t\tapplyBtn.style.cssText = 'width:100%;padding:6px 12px;margin-top:4px;cursor:pointer;';\n\n\t\t\tapplyBtn.addEventListener('mousedown', (e) => {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tconst href = input.value.trim();\n\t\t\t\tif (href) {\n\t\t\t\t\tthis.addLink(context, context.getState(), href);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tinput.addEventListener('keydown', (e) => {\n\t\t\t\tif (e.key === 'Enter') {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tconst href = input.value.trim();\n\t\t\t\t\tif (href) {\n\t\t\t\t\t\tthis.addLink(context, context.getState(), href);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tcontainer.appendChild(input);\n\t\t\tcontainer.appendChild(applyBtn);\n\n\t\t\t// Auto-focus input\n\t\t\trequestAnimationFrame(() => input.focus());\n\t\t}\n\t}\n}\n"],"names":["DEFAULT_CONFIG","openInNewTab","LinkPlugin","id","name","priority","config","this","context","registerMarkSpec","registerCommands","registerKeymap","registerToolbarItem","type","rank","attrs","href","default","mark","a","document","createElement","setAttribute","toHTMLString","content","escapeHTML","String","parseHTML","tag","getAttrs","el","getAttribute","sanitize","tags","registerCommand","state","getState","toggleLink","removeLink","executeCommand","group","icon","label","tooltip","formatShortcut","command","popupType","separatorAfter","renderPopup","container","ctx","renderLinkPopup","isActive","isLinkActive","isEnabled","isCollapsed","selection","sel","isNodeSelection","block","getBlock","anchor","blockId","marks","getBlockMarksAtOffset","offset","hasMark","markType","range","selectionRange","getBlockOrder","builder","transaction","forEachBlockInRange","from","to","addMark","setSelection","dispatch","build","blockOrder","textChildren","pos","child","children","end","text","length","push","hasLink","cursorIdx","findIndex","c","cursorEntry","startIdx","endIdx","startEntry","endEntry","linkStart","linkEnd","removeMark","style","padding","minWidth","removeBtn","textContent","cssText","addEventListener","e","preventDefault","stopPropagation","appendChild","input","placeholder","applyBtn","value","trim","addLink","key","requestAnimationFrame","focus"],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Plugin, PluginContext } from '../Plugin.js';
|
|
2
|
+
export type ListType = 'bullet' | 'ordered' | 'checklist';
|
|
3
|
+
declare module '../../model/AttrRegistry.js' {
|
|
4
|
+
interface NodeAttrRegistry {
|
|
5
|
+
list_item: {
|
|
6
|
+
listType: ListType;
|
|
7
|
+
indent: number;
|
|
8
|
+
checked: boolean;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export interface ListConfig {
|
|
13
|
+
/** Which list types to enable. Defaults to all. */
|
|
14
|
+
readonly types: readonly ListType[];
|
|
15
|
+
/** Maximum indent depth. Defaults to 4. */
|
|
16
|
+
readonly maxIndent: number;
|
|
17
|
+
/** When true, a separator is rendered after the last list toolbar item. */
|
|
18
|
+
readonly separatorAfter?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare class ListPlugin implements Plugin {
|
|
21
|
+
readonly id = "list";
|
|
22
|
+
readonly name = "List";
|
|
23
|
+
readonly priority = 35;
|
|
24
|
+
private readonly config;
|
|
25
|
+
constructor(config?: Partial<ListConfig>);
|
|
26
|
+
init(context: PluginContext): void;
|
|
27
|
+
private registerNodeSpec;
|
|
28
|
+
private registerCommands;
|
|
29
|
+
private registerKeymaps;
|
|
30
|
+
private registerInputRules;
|
|
31
|
+
private registerToolbarItems;
|
|
32
|
+
private toggleList;
|
|
33
|
+
private indent;
|
|
34
|
+
private outdent;
|
|
35
|
+
private setIndent;
|
|
36
|
+
private toggleChecked;
|
|
37
|
+
/**
|
|
38
|
+
* Handles Backspace at the start of a list item.
|
|
39
|
+
* Converts the list item back to a paragraph, preserving text.
|
|
40
|
+
*/
|
|
41
|
+
private handleBackspace;
|
|
42
|
+
/**
|
|
43
|
+
* Handles Enter inside a list item.
|
|
44
|
+
* Empty item → exit list (convert to paragraph).
|
|
45
|
+
* Non-empty item → split and create a new list item with the same type.
|
|
46
|
+
*/
|
|
47
|
+
private handleEnter;
|
|
48
|
+
private isListActive;
|
|
49
|
+
private getEnabledTypes;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=ListPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/list/ListPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI1D,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;AAE1D,OAAO,QAAQ,6BAA6B,CAAC;IAC5C,UAAU,gBAAgB;QACzB,SAAS,EAAE;YAAE,QAAQ,EAAE,QAAQ,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,OAAO,CAAA;SAAE,CAAC;KACpE;CACD;AAID,MAAM,WAAW,UAAU;IAC1B,mDAAmD;IACnD,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IACpC,2CAA2C;IAC3C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;CAClC;AAkDD,qBAAa,UAAW,YAAW,MAAM;IACxC,QAAQ,CAAC,EAAE,UAAU;IACrB,QAAQ,CAAC,IAAI,UAAU;IACvB,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;gBAExB,MAAM,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC;IAIxC,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IASlC,OAAO,CAAC,gBAAgB;IAmDxB,OAAO,CAAC,gBAAgB;IAwBxB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,UAAU;IAoClB,OAAO,CAAC,MAAM;IAWd,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,SAAS;IAiBjB,OAAO,CAAC,aAAa;IAoBrB;;;OAGG;IACH,OAAO,CAAC,eAAe;IAmBvB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IA4CnB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,eAAe;CAGvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/list/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,UAAU,EACV,KAAK,UAAU,EACf,KAAK,QAAQ,GACb,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { i as t } from "../chunks/AttrRegistry-DTsHyDVA.mjs";
|
|
2
|
+
import { p as e, b as n } from "../chunks/Document-CI3iCwEP.mjs";
|
|
3
|
+
import { c as i } from "../chunks/NodeSpec-NZVvcCuH.mjs";
|
|
4
|
+
import { i as s, a as r, c as o } from "../chunks/Selection-D5ZjXoB7.mjs";
|
|
5
|
+
import { n as c } from "../chunks/TypeBrands-C09nE2qO.mjs";
|
|
6
|
+
const l = { types: ["bullet", "ordered", "checklist"], maxIndent: 4 }, a = [{ type: "bullet", label: "Bullet List", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z"/></svg>', inputPattern: /^[-*] $/, inputPrefix: "- " }, { type: "ordered", label: "Numbered List", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z"/></svg>', inputPattern: /^\d+\. $/, inputPrefix: "1. " }, { type: "checklist", label: "Checklist", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M22 7h-9v2h9V7zm0 8h-9v2h9v-2zM5.54 11L2 7.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 11zm0 8L2 15.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 19z"/></svg>', inputPattern: /^\[[ x]] $/, inputPrefix: "[ ] " }];
|
|
7
|
+
class d {
|
|
8
|
+
id = "list";
|
|
9
|
+
name = "List";
|
|
10
|
+
priority = 35;
|
|
11
|
+
config;
|
|
12
|
+
constructor(t2) {
|
|
13
|
+
this.config = { ...l, ...t2 };
|
|
14
|
+
}
|
|
15
|
+
init(t2) {
|
|
16
|
+
t2.registerStyleSheet(`
|
|
17
|
+
/* List Wrappers — suppress native markers, we use ::before pseudo-elements */
|
|
18
|
+
.notectl-list {
|
|
19
|
+
list-style: none;
|
|
20
|
+
margin: 0;
|
|
21
|
+
padding: 0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/* Ordered List — each <ol> wrapper resets the counter */
|
|
25
|
+
.notectl-list--ordered {
|
|
26
|
+
counter-reset: notectl-ordered;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/* List Items */
|
|
30
|
+
.notectl-list-item {
|
|
31
|
+
margin: 0;
|
|
32
|
+
padding: 2px 0 2px 24px;
|
|
33
|
+
min-height: 1.6em;
|
|
34
|
+
position: relative;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.notectl-list-item::before {
|
|
38
|
+
position: absolute;
|
|
39
|
+
left: 0;
|
|
40
|
+
display: inline-block;
|
|
41
|
+
width: 24px;
|
|
42
|
+
text-align: center;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/* Bullet List */
|
|
46
|
+
.notectl-list-item--bullet::before {
|
|
47
|
+
content: '\\2022';
|
|
48
|
+
color: var(--notectl-fg);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Ordered List — counter increment per item */
|
|
52
|
+
.notectl-list-item--ordered {
|
|
53
|
+
counter-increment: notectl-ordered;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.notectl-list-item--ordered::before {
|
|
57
|
+
content: counter(notectl-ordered) '.';
|
|
58
|
+
color: var(--notectl-fg);
|
|
59
|
+
font-size: 14px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/* Checklist */
|
|
63
|
+
.notectl-list-item--checklist::before {
|
|
64
|
+
content: '\\2610';
|
|
65
|
+
font-size: 16px;
|
|
66
|
+
color: var(--notectl-fg-muted);
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.notectl-list-item--checklist[data-checked="true"]::before {
|
|
71
|
+
content: '\\2611';
|
|
72
|
+
color: var(--notectl-success);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.notectl-list-item--checklist[data-checked="true"] {
|
|
76
|
+
color: var(--notectl-fg-muted);
|
|
77
|
+
text-decoration: line-through;
|
|
78
|
+
}
|
|
79
|
+
`), this.registerNodeSpec(t2), this.registerCommands(t2), this.registerKeymaps(t2), this.registerInputRules(t2), this.registerToolbarItems(t2);
|
|
80
|
+
}
|
|
81
|
+
registerNodeSpec(t2) {
|
|
82
|
+
t2.registerNodeSpec({ type: "list_item", group: "block", content: { allow: ["text"] }, attrs: { listType: { default: "bullet" }, indent: { default: 0 }, checked: { default: false } }, toDOM(t3) {
|
|
83
|
+
const e2 = t3.attrs?.listType ?? "bullet", n2 = t3.attrs?.indent ?? 0, s2 = t3.attrs?.checked ?? false, r2 = i("li", t3.id);
|
|
84
|
+
return r2.setAttribute("role", "listitem"), r2.setAttribute("data-list-type", e2), r2.setAttribute("data-indent", String(n2)), r2.className = `notectl-list-item notectl-list-item--${e2}`, n2 > 0 && (r2.style.marginLeft = 24 * n2 + "px"), "checklist" === e2 && (r2.setAttribute("data-checked", String(s2)), r2.setAttribute("aria-checked", String(s2))), r2.setAttribute("aria-level", String(n2 + 1)), r2;
|
|
85
|
+
}, wrapper(t3) {
|
|
86
|
+
const e2 = t3.attrs?.listType ?? "bullet";
|
|
87
|
+
return { tag: "ordered" === e2 ? "ol" : "ul", key: `list-${e2}`, className: `notectl-list notectl-list--${e2}`, attrs: { role: "list" } };
|
|
88
|
+
}, toHTML: (t3, e2) => `<li>${e2 || "<br>"}</li>`, parseHTML: [{ tag: "li" }], sanitize: { tags: ["ul", "ol", "li"] } });
|
|
89
|
+
}
|
|
90
|
+
registerCommands(t2) {
|
|
91
|
+
const e2 = this.getEnabledTypes();
|
|
92
|
+
for (const n2 of e2) t2.registerCommand(`toggleList:${n2.type}`, () => this.toggleList(t2, n2.type));
|
|
93
|
+
t2.registerCommand("indentListItem", () => this.indent(t2)), t2.registerCommand("outdentListItem", () => this.outdent(t2)), this.config.types.includes("checklist") && t2.registerCommand("toggleChecklistItem", () => this.toggleChecked(t2));
|
|
94
|
+
}
|
|
95
|
+
registerKeymaps(t2) {
|
|
96
|
+
t2.registerKeymap({ Enter: () => this.handleEnter(t2), Backspace: () => this.handleBackspace(t2), Tab: () => this.indent(t2), "Shift-Tab": () => this.outdent(t2) });
|
|
97
|
+
}
|
|
98
|
+
registerInputRules(t2) {
|
|
99
|
+
const e2 = this.getEnabledTypes();
|
|
100
|
+
for (const n2 of e2) t2.registerInputRule({ pattern: n2.inputPattern, handler: (t3, e3, i2, l2) => {
|
|
101
|
+
const a2 = t3.selection;
|
|
102
|
+
if (s(a2)) return null;
|
|
103
|
+
if (!r(a2)) return null;
|
|
104
|
+
const d2 = t3.getBlock(a2.anchor.blockId);
|
|
105
|
+
if (!d2 || "paragraph" !== d2.type) return null;
|
|
106
|
+
const p = e3[0] ?? "", h = p.length, u = { listType: n2.type, indent: 0 };
|
|
107
|
+
return "checklist" === n2.type && (u.checked = p.includes("[x]")), t3.transaction("input").deleteTextAt(a2.anchor.blockId, i2, i2 + h).setBlockType(a2.anchor.blockId, c("list_item"), u).setSelection(o(a2.anchor.blockId, 0)).build();
|
|
108
|
+
} });
|
|
109
|
+
}
|
|
110
|
+
registerToolbarItems(t2) {
|
|
111
|
+
const e2 = this.getEnabledTypes(), n2 = e2.at(-1);
|
|
112
|
+
for (const i2 of e2) t2.registerToolbarItem({ id: `list-${i2.type}`, group: "block", icon: i2.icon, label: i2.label, command: `toggleList:${i2.type}`, priority: "bullet" === i2.type ? 70 : "ordered" === i2.type ? 71 : 72, separatorAfter: this.config.separatorAfter && i2 === n2, isActive: (t3) => this.isListActive(t3, i2.type) });
|
|
113
|
+
}
|
|
114
|
+
toggleList(e2, n2) {
|
|
115
|
+
const i2 = e2.getState(), r2 = i2.selection;
|
|
116
|
+
if (s(r2)) return false;
|
|
117
|
+
const o2 = i2.getBlock(r2.anchor.blockId);
|
|
118
|
+
if (!o2) return false;
|
|
119
|
+
if ("list_item" === o2.type && o2.attrs?.listType === n2) {
|
|
120
|
+
const t2 = i2.transaction("command").setBlockType(r2.anchor.blockId, c("paragraph")).setSelection(r2).build();
|
|
121
|
+
return e2.dispatch(t2), true;
|
|
122
|
+
}
|
|
123
|
+
const l2 = { listType: n2, indent: t(o2, "list_item") ? o2.attrs.indent : 0 };
|
|
124
|
+
"checklist" === n2 && (l2.checked = false);
|
|
125
|
+
const a2 = i2.transaction("command").setBlockType(r2.anchor.blockId, c("list_item"), l2).setSelection(r2).build();
|
|
126
|
+
return e2.dispatch(a2), true;
|
|
127
|
+
}
|
|
128
|
+
indent(e2) {
|
|
129
|
+
const n2 = e2.getState();
|
|
130
|
+
if (s(n2.selection)) return false;
|
|
131
|
+
const i2 = n2.getBlock(n2.selection.anchor.blockId);
|
|
132
|
+
return !(!i2 || !t(i2, "list_item")) && !(i2.attrs.indent >= this.config.maxIndent) && this.setIndent(e2, n2, i2.attrs.indent + 1);
|
|
133
|
+
}
|
|
134
|
+
outdent(e2) {
|
|
135
|
+
const n2 = e2.getState();
|
|
136
|
+
if (s(n2.selection)) return false;
|
|
137
|
+
const i2 = n2.getBlock(n2.selection.anchor.blockId);
|
|
138
|
+
return !(!i2 || !t(i2, "list_item")) && !(i2.attrs.indent <= 0) && this.setIndent(e2, n2, i2.attrs.indent - 1);
|
|
139
|
+
}
|
|
140
|
+
setIndent(t2, e2, n2) {
|
|
141
|
+
const i2 = e2.selection;
|
|
142
|
+
if (s(i2)) return false;
|
|
143
|
+
const r2 = e2.getBlock(i2.anchor.blockId);
|
|
144
|
+
if (!r2) return false;
|
|
145
|
+
const o2 = { ...r2.attrs, indent: n2 }, l2 = e2.transaction("command").setBlockType(i2.anchor.blockId, c("list_item"), o2).setSelection(i2).build();
|
|
146
|
+
return t2.dispatch(l2), true;
|
|
147
|
+
}
|
|
148
|
+
toggleChecked(t2) {
|
|
149
|
+
const e2 = t2.getState();
|
|
150
|
+
if (s(e2.selection)) return false;
|
|
151
|
+
const n2 = e2.getBlock(e2.selection.anchor.blockId);
|
|
152
|
+
if (!n2 || "list_item" !== n2.type || "checklist" !== n2.attrs?.listType) return false;
|
|
153
|
+
const i2 = !n2.attrs?.checked, r2 = { ...n2.attrs, checked: i2 }, o2 = e2.transaction("command").setBlockType(e2.selection.anchor.blockId, c("list_item"), r2).setSelection(e2.selection).build();
|
|
154
|
+
return t2.dispatch(o2), true;
|
|
155
|
+
}
|
|
156
|
+
handleBackspace(t2) {
|
|
157
|
+
const e2 = t2.getState(), n2 = e2.selection;
|
|
158
|
+
if (s(n2)) return false;
|
|
159
|
+
if (!r(n2)) return false;
|
|
160
|
+
const i2 = e2.getBlock(n2.anchor.blockId);
|
|
161
|
+
if (!i2 || "list_item" !== i2.type) return false;
|
|
162
|
+
if (0 !== n2.anchor.offset) return false;
|
|
163
|
+
const o2 = e2.transaction("input").setBlockType(n2.anchor.blockId, c("paragraph")).setSelection(n2).build();
|
|
164
|
+
return t2.dispatch(o2), true;
|
|
165
|
+
}
|
|
166
|
+
handleEnter(i2) {
|
|
167
|
+
const l2 = i2.getState(), a2 = l2.selection;
|
|
168
|
+
if (s(a2)) return false;
|
|
169
|
+
if (!r(a2)) return false;
|
|
170
|
+
const d2 = l2.getBlock(a2.anchor.blockId);
|
|
171
|
+
if (!d2 || "list_item" !== d2.type) return false;
|
|
172
|
+
if ("" === e(d2)) {
|
|
173
|
+
const t2 = l2.transaction("input").setBlockType(a2.anchor.blockId, c("paragraph")).setSelection(a2).build();
|
|
174
|
+
return i2.dispatch(t2), true;
|
|
175
|
+
}
|
|
176
|
+
const p = n(), h = { listType: t(d2, "list_item") ? d2.attrs.listType : "bullet", indent: t(d2, "list_item") ? d2.attrs.indent : 0 };
|
|
177
|
+
"checklist" === h.listType && (h.checked = false);
|
|
178
|
+
const u = l2.transaction("input").splitBlock(a2.anchor.blockId, a2.anchor.offset, p).setBlockType(p, c("list_item"), h).setSelection(o(p, 0)).build();
|
|
179
|
+
return i2.dispatch(u), true;
|
|
180
|
+
}
|
|
181
|
+
isListActive(t2, e2) {
|
|
182
|
+
if (s(t2.selection)) return false;
|
|
183
|
+
const n2 = t2.getBlock(t2.selection.anchor.blockId);
|
|
184
|
+
return "list_item" === n2?.type && n2.attrs?.listType === e2;
|
|
185
|
+
}
|
|
186
|
+
getEnabledTypes() {
|
|
187
|
+
return a.filter((t2) => this.config.types.includes(t2.type));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
export {
|
|
191
|
+
d as ListPlugin
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=list.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.mjs","sources":["../../src/editor/styles/list.ts","../../src/plugins/list/ListPlugin.ts"],"sourcesContent":["/** List styles — bullet, ordered, checklist items. */\nexport const LIST_CSS = `\n/* List Wrappers — suppress native markers, we use ::before pseudo-elements */\n.notectl-list {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n/* Ordered List — each <ol> wrapper resets the counter */\n.notectl-list--ordered {\n\tcounter-reset: notectl-ordered;\n}\n\n/* List Items */\n.notectl-list-item {\n\tmargin: 0;\n\tpadding: 2px 0 2px 24px;\n\tmin-height: 1.6em;\n\tposition: relative;\n}\n\n.notectl-list-item::before {\n\tposition: absolute;\n\tleft: 0;\n\tdisplay: inline-block;\n\twidth: 24px;\n\ttext-align: center;\n}\n\n/* Bullet List */\n.notectl-list-item--bullet::before {\n\tcontent: '\\\\2022';\n\tcolor: var(--notectl-fg);\n}\n\n/* Ordered List — counter increment per item */\n.notectl-list-item--ordered {\n\tcounter-increment: notectl-ordered;\n}\n\n.notectl-list-item--ordered::before {\n\tcontent: counter(notectl-ordered) '.';\n\tcolor: var(--notectl-fg);\n\tfont-size: 14px;\n}\n\n/* Checklist */\n.notectl-list-item--checklist::before {\n\tcontent: '\\\\2610';\n\tfont-size: 16px;\n\tcolor: var(--notectl-fg-muted);\n\tcursor: pointer;\n}\n\n.notectl-list-item--checklist[data-checked=\"true\"]::before {\n\tcontent: '\\\\2611';\n\tcolor: var(--notectl-success);\n}\n\n.notectl-list-item--checklist[data-checked=\"true\"] {\n\tcolor: var(--notectl-fg-muted);\n\ttext-decoration: line-through;\n}\n`;\n","/**\n * ListPlugin: registers ordered, unordered, and checklist block types\n * with NodeSpecs, toggle commands, indent/outdent (Tab/Shift-Tab),\n * input rules, and toolbar buttons.\n *\n * List items are modeled as flat blocks with a `listType` and `indent` attribute,\n * allowing simple nesting representation without deep tree structures.\n */\n\nimport { LIST_CSS } from '../../editor/styles/list.js';\nimport { isNodeOfType } from '../../model/AttrRegistry.js';\nimport { generateBlockId, getBlockText } from '../../model/Document.js';\nimport { createBlockElement } from '../../model/NodeSpec.js';\nimport { createCollapsedSelection, isCollapsed, isNodeSelection } from '../../model/Selection.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Attribute Registry Augmentation ---\n\nexport type ListType = 'bullet' | 'ordered' | 'checklist';\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\tlist_item: { listType: ListType; indent: number; checked: boolean };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface ListConfig {\n\t/** Which list types to enable. Defaults to all. */\n\treadonly types: readonly ListType[];\n\t/** Maximum indent depth. Defaults to 4. */\n\treadonly maxIndent: number;\n\t/** When true, a separator is rendered after the last list toolbar item. */\n\treadonly separatorAfter?: boolean;\n}\n\nconst DEFAULT_CONFIG: ListConfig = {\n\ttypes: ['bullet', 'ordered', 'checklist'],\n\tmaxIndent: 4,\n};\n\n// --- List Type Metadata ---\n\ninterface ListTypeDefinition {\n\treadonly type: ListType;\n\treadonly label: string;\n\treadonly icon: string;\n\treadonly inputPattern: RegExp;\n\treadonly inputPrefix: string;\n}\n\nconst BULLET_LIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z\"/></svg>';\nconst NUMBERED_LIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z\"/></svg>';\nconst CHECKLIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M22 7h-9v2h9V7zm0 8h-9v2h9v-2zM5.54 11L2 7.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 11zm0 8L2 15.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 19z\"/></svg>';\n\nconst LIST_TYPE_DEFINITIONS: readonly ListTypeDefinition[] = [\n\t{\n\t\ttype: 'bullet',\n\t\tlabel: 'Bullet List',\n\t\ticon: BULLET_LIST_ICON,\n\t\tinputPattern: /^[-*] $/,\n\t\tinputPrefix: '- ',\n\t},\n\t{\n\t\ttype: 'ordered',\n\t\tlabel: 'Numbered List',\n\t\ticon: NUMBERED_LIST_ICON,\n\t\tinputPattern: /^\\d+\\. $/,\n\t\tinputPrefix: '1. ',\n\t},\n\t{\n\t\ttype: 'checklist',\n\t\tlabel: 'Checklist',\n\t\ticon: CHECKLIST_ICON,\n\t\tinputPattern: /^\\[[ x]] $/,\n\t\tinputPrefix: '[ ] ',\n\t},\n];\n\n// --- Plugin ---\n\nexport class ListPlugin implements Plugin {\n\treadonly id = 'list';\n\treadonly name = 'List';\n\treadonly priority = 35;\n\n\tprivate readonly config: ListConfig;\n\n\tconstructor(config?: Partial<ListConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tcontext.registerStyleSheet(LIST_CSS);\n\t\tthis.registerNodeSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerInputRules(context);\n\t\tthis.registerToolbarItems(context);\n\t}\n\n\tprivate registerNodeSpec(context: PluginContext): void {\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'list_item',\n\t\t\tgroup: 'block',\n\t\t\tcontent: { allow: ['text'] },\n\t\t\tattrs: {\n\t\t\t\tlistType: { default: 'bullet' },\n\t\t\t\tindent: { default: 0 },\n\t\t\t\tchecked: { default: false },\n\t\t\t},\n\t\t\ttoDOM(node) {\n\t\t\t\tconst listType = node.attrs?.listType ?? 'bullet';\n\t\t\t\tconst indent = node.attrs?.indent ?? 0;\n\t\t\t\tconst checked = node.attrs?.checked ?? false;\n\n\t\t\t\tconst li = createBlockElement('li', node.id);\n\t\t\t\tli.setAttribute('role', 'listitem');\n\t\t\t\tli.setAttribute('data-list-type', listType);\n\t\t\t\tli.setAttribute('data-indent', String(indent));\n\t\t\t\tli.className = `notectl-list-item notectl-list-item--${listType}`;\n\n\t\t\t\tif (indent > 0) {\n\t\t\t\t\tli.style.marginLeft = `${indent * 24}px`;\n\t\t\t\t}\n\n\t\t\t\tif (listType === 'checklist') {\n\t\t\t\t\tli.setAttribute('data-checked', String(checked));\n\t\t\t\t\tli.setAttribute('aria-checked', String(checked));\n\t\t\t\t}\n\t\t\t\tli.setAttribute('aria-level', String(indent + 1));\n\n\t\t\t\treturn li;\n\t\t\t},\n\t\t\twrapper(node) {\n\t\t\t\tconst listType = node.attrs?.listType ?? 'bullet';\n\t\t\t\tconst tag = listType === 'ordered' ? 'ol' : 'ul';\n\t\t\t\treturn {\n\t\t\t\t\ttag,\n\t\t\t\t\tkey: `list-${listType}`,\n\t\t\t\t\tclassName: `notectl-list notectl-list--${listType}`,\n\t\t\t\t\tattrs: { role: 'list' },\n\t\t\t\t};\n\t\t\t},\n\t\t\ttoHTML(_node, content) {\n\t\t\t\treturn `<li>${content || '<br>'}</li>`;\n\t\t\t},\n\t\t\tparseHTML: [{ tag: 'li' }],\n\t\t\tsanitize: { tags: ['ul', 'ol', 'li'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tconst enabledTypes = this.getEnabledTypes();\n\n\t\tfor (const def of enabledTypes) {\n\t\t\tcontext.registerCommand(`toggleList:${def.type}`, () => {\n\t\t\t\treturn this.toggleList(context, def.type);\n\t\t\t});\n\t\t}\n\n\t\tcontext.registerCommand('indentListItem', () => {\n\t\t\treturn this.indent(context);\n\t\t});\n\n\t\tcontext.registerCommand('outdentListItem', () => {\n\t\t\treturn this.outdent(context);\n\t\t});\n\n\t\tif (this.config.types.includes('checklist')) {\n\t\t\tcontext.registerCommand('toggleChecklistItem', () => {\n\t\t\t\treturn this.toggleChecked(context);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\tEnter: () => this.handleEnter(context),\n\t\t\tBackspace: () => this.handleBackspace(context),\n\t\t\tTab: () => this.indent(context),\n\t\t\t'Shift-Tab': () => this.outdent(context),\n\t\t});\n\t}\n\n\tprivate registerInputRules(context: PluginContext): void {\n\t\tconst enabledTypes = this.getEnabledTypes();\n\n\t\tfor (const def of enabledTypes) {\n\t\t\tcontext.registerInputRule({\n\t\t\t\tpattern: def.inputPattern,\n\t\t\t\thandler: (state, match, start, _end) => {\n\t\t\t\t\tconst sel = state.selection;\n\t\t\t\t\tif (isNodeSelection(sel)) return null;\n\t\t\t\t\tif (!isCollapsed(sel)) return null;\n\n\t\t\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\t\t\tif (!block || block.type !== 'paragraph') return null;\n\n\t\t\t\t\tconst matchStr = match[0] ?? '';\n\t\t\t\t\tconst matchLen = matchStr.length;\n\t\t\t\t\tconst attrs: Record<string, string | number | boolean> = {\n\t\t\t\t\t\tlistType: def.type,\n\t\t\t\t\t\tindent: 0,\n\t\t\t\t\t};\n\t\t\t\t\tif (def.type === 'checklist') {\n\t\t\t\t\t\tattrs.checked = matchStr.includes('[x]');\n\t\t\t\t\t}\n\n\t\t\t\t\treturn state\n\t\t\t\t\t\t.transaction('input')\n\t\t\t\t\t\t.deleteTextAt(sel.anchor.blockId, start, start + matchLen)\n\t\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('list_item'), attrs)\n\t\t\t\t\t\t.setSelection(createCollapsedSelection(sel.anchor.blockId, 0))\n\t\t\t\t\t\t.build();\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerToolbarItems(context: PluginContext): void {\n\t\tconst enabledTypes = this.getEnabledTypes();\n\t\tconst lastType = enabledTypes.at(-1);\n\n\t\tfor (const def of enabledTypes) {\n\t\t\tcontext.registerToolbarItem({\n\t\t\t\tid: `list-${def.type}`,\n\t\t\t\tgroup: 'block',\n\t\t\t\ticon: def.icon,\n\t\t\t\tlabel: def.label,\n\t\t\t\tcommand: `toggleList:${def.type}`,\n\t\t\t\tpriority: def.type === 'bullet' ? 70 : def.type === 'ordered' ? 71 : 72,\n\t\t\t\tseparatorAfter: this.config.separatorAfter && def === lastType,\n\t\t\t\tisActive: (state) => this.isListActive(state, def.type),\n\t\t\t});\n\t\t}\n\t}\n\n\t// --- Command Implementations ---\n\n\tprivate toggleList(context: PluginContext, listType: ListType): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\t\tif (isNodeSelection(sel)) return false;\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return false;\n\n\t\t// If already this list type, convert back to paragraph\n\t\tif (block.type === 'list_item' && block.attrs?.listType === listType) {\n\t\t\tconst tr = state\n\t\t\t\t.transaction('command')\n\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('paragraph'))\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\t// Convert to list item\n\t\tconst attrs: Record<string, string | number | boolean> = {\n\t\t\tlistType,\n\t\t\tindent: isNodeOfType(block, 'list_item') ? block.attrs.indent : 0,\n\t\t};\n\t\tif (listType === 'checklist') {\n\t\t\tattrs.checked = false;\n\t\t}\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.setBlockType(sel.anchor.blockId, nodeType('list_item'), attrs)\n\t\t\t.setSelection(sel)\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate indent(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tif (isNodeSelection(state.selection)) return false;\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tif (!block || !isNodeOfType(block, 'list_item')) return false;\n\n\t\tif (block.attrs.indent >= this.config.maxIndent) return false;\n\n\t\treturn this.setIndent(context, state, block.attrs.indent + 1);\n\t}\n\n\tprivate outdent(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tif (isNodeSelection(state.selection)) return false;\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tif (!block || !isNodeOfType(block, 'list_item')) return false;\n\n\t\tif (block.attrs.indent <= 0) return false;\n\n\t\treturn this.setIndent(context, state, block.attrs.indent - 1);\n\t}\n\n\tprivate setIndent(context: PluginContext, state: EditorState, indent: number): boolean {\n\t\tconst sel = state.selection;\n\t\tif (isNodeSelection(sel)) return false;\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block) return false;\n\n\t\tconst attrs = { ...block.attrs, indent } as Record<string, string | number | boolean>;\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.setBlockType(sel.anchor.blockId, nodeType('list_item'), attrs)\n\t\t\t.setSelection(sel)\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate toggleChecked(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tif (isNodeSelection(state.selection)) return false;\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\tif (!block || block.type !== 'list_item' || block.attrs?.listType !== 'checklist') {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst checked = !block.attrs?.checked;\n\t\tconst attrs = { ...block.attrs, checked } as Record<string, string | number | boolean>;\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.setBlockType(state.selection.anchor.blockId, nodeType('list_item'), attrs)\n\t\t\t.setSelection(state.selection)\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Handles Backspace at the start of a list item.\n\t * Converts the list item back to a paragraph, preserving text.\n\t */\n\tprivate handleBackspace(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\t\tif (isNodeSelection(sel)) return false;\n\t\tif (!isCollapsed(sel)) return false;\n\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block || block.type !== 'list_item') return false;\n\t\tif (sel.anchor.offset !== 0) return false;\n\n\t\tconst tr = state\n\t\t\t.transaction('input')\n\t\t\t.setBlockType(sel.anchor.blockId, nodeType('paragraph'))\n\t\t\t.setSelection(sel)\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Handles Enter inside a list item.\n\t * Empty item → exit list (convert to paragraph).\n\t * Non-empty item → split and create a new list item with the same type.\n\t */\n\tprivate handleEnter(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\t\tif (isNodeSelection(sel)) return false;\n\t\tif (!isCollapsed(sel)) return false;\n\n\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\tif (!block || block.type !== 'list_item') return false;\n\n\t\tconst text = getBlockText(block);\n\n\t\tif (text === '') {\n\t\t\t// Empty list item → convert to paragraph (exit list)\n\t\t\tconst tr = state\n\t\t\t\t.transaction('input')\n\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('paragraph'))\n\t\t\t\t.setSelection(sel)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\t// Non-empty → split block and set new block to same list type\n\t\tconst newBlockId = generateBlockId();\n\t\tconst attrs: Record<string, string | number | boolean> = {\n\t\t\tlistType: isNodeOfType(block, 'list_item') ? block.attrs.listType : 'bullet',\n\t\t\tindent: isNodeOfType(block, 'list_item') ? block.attrs.indent : 0,\n\t\t};\n\t\tif (attrs.listType === 'checklist') {\n\t\t\tattrs.checked = false;\n\t\t}\n\n\t\tconst tr = state\n\t\t\t.transaction('input')\n\t\t\t.splitBlock(sel.anchor.blockId, sel.anchor.offset, newBlockId)\n\t\t\t.setBlockType(newBlockId, nodeType('list_item'), attrs)\n\t\t\t.setSelection(createCollapsedSelection(newBlockId, 0))\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t// --- Helpers ---\n\n\tprivate isListActive(state: EditorState, listType: ListType): boolean {\n\t\tif (isNodeSelection(state.selection)) return false;\n\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\treturn block?.type === 'list_item' && block.attrs?.listType === listType;\n\t}\n\n\tprivate getEnabledTypes(): readonly ListTypeDefinition[] {\n\t\treturn LIST_TYPE_DEFINITIONS.filter((def) => this.config.types.includes(def.type));\n\t}\n}\n"],"names":["DEFAULT_CONFIG","types","maxIndent","LIST_TYPE_DEFINITIONS","type","label","icon","inputPattern","inputPrefix","ListPlugin","id","name","priority","config","this","context","registerStyleSheet","registerNodeSpec","registerCommands","registerKeymaps","registerInputRules","registerToolbarItems","group","content","allow","attrs","listType","default","indent","checked","node","li","createBlockElement","setAttribute","String","className","style","marginLeft","tag","key","role","toHTML","_node","parseHTML","sanitize","tags","enabledTypes","getEnabledTypes","def","registerCommand","toggleList","outdent","includes","toggleChecked","registerKeymap","Enter","handleEnter","Backspace","handleBackspace","Tab","registerInputRule","pattern","handler","state","match","start","_end","sel","selection","isNodeSelection","isCollapsed","block","getBlock","anchor","blockId","matchStr","matchLen","length","transaction","deleteTextAt","setBlockType","nodeType","setSelection","createCollapsedSelection","build","lastType","at","registerToolbarItem","command","separatorAfter","isActive","isListActive","getState","tr","dispatch","isNodeOfType","setIndent","offset","getBlockText","newBlockId","generateBlockId","splitBlock","filter"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PrintOptions } from './PrintTypes.js';
|
|
2
|
+
/** Deep-clones the .notectl-content element from the editor container. */
|
|
3
|
+
export declare function cloneContent(container: HTMLElement): HTMLElement;
|
|
4
|
+
/** Sanitizes the cloned content for print: removes interactive attributes and selection styling. */
|
|
5
|
+
export declare function sanitize(clone: HTMLElement): void;
|
|
6
|
+
/** Removes excluded block types and applies page-break-before to configured block types. */
|
|
7
|
+
export declare function applyBlockFilters(clone: HTMLElement, options: PrintOptions): void;
|
|
8
|
+
/** Inserts header and footer elements into the cloned content. */
|
|
9
|
+
export declare function insertHeaderFooter(clone: HTMLElement, options: PrintOptions): void;
|
|
10
|
+
/** Orchestrates all content preparation steps. Returns a ready-to-print DOM element. */
|
|
11
|
+
export declare function prepare(container: HTMLElement, options: PrintOptions): HTMLElement;
|
|
12
|
+
//# sourceMappingURL=PrintContentPreparer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrintContentPreparer.d.ts","sourceRoot":"","sources":["../../../src/plugins/print/PrintContentPreparer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,SAAS,EAAE,WAAW,GAAG,WAAW,CAIhE;AAED,oGAAoG;AACpG,wBAAgB,QAAQ,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAejD;AAED,4FAA4F;AAC5F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAmBjF;AAOD,kEAAkE;AAClE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAclF;AAED,wFAAwF;AACxF,wBAAgB,OAAO,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,GAAG,WAAW,CAMlF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Plugin, PluginContext } from '../Plugin.js';
|
|
2
|
+
import { PrintPluginConfig } from './PrintTypes.js';
|
|
3
|
+
export declare class PrintPlugin implements Plugin {
|
|
4
|
+
readonly id = "print";
|
|
5
|
+
readonly name = "Print";
|
|
6
|
+
private readonly config;
|
|
7
|
+
private service;
|
|
8
|
+
constructor(config?: PrintPluginConfig);
|
|
9
|
+
init(context: PluginContext): void;
|
|
10
|
+
destroy(): void;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=PrintPlugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrintPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/print/PrintPlugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,KAAK,EAAgB,iBAAiB,EAAgB,MAAM,iBAAiB,CAAC;AAiBrF,qBAAa,WAAY,YAAW,MAAM;IACzC,QAAQ,CAAC,EAAE,WAAW;IACtB,QAAQ,CAAC,IAAI,WAAW;IAExB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,OAAO,CAA6B;gBAEhC,MAAM,CAAC,EAAE,iBAAiB;IAItC,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IA6ClC,OAAO,IAAI,IAAI;CAGf"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PluginEventBus } from '../Plugin.js';
|
|
2
|
+
import { PrintService } from './PrintTypes.js';
|
|
3
|
+
/** Builds a complete HTML document string from CSS, body content, and title. */
|
|
4
|
+
export declare function buildHTMLDocument(css: string, content: string, title: string, lang?: string): string;
|
|
5
|
+
/** Creates and returns the PrintService implementation. */
|
|
6
|
+
export declare function createPrintService(shadowRoot: ShadowRoot, host: HTMLElement, container: HTMLElement, eventBus: PluginEventBus): PrintService;
|
|
7
|
+
//# sourceMappingURL=PrintServiceImpl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrintServiceImpl.d.ts","sourceRoot":"","sources":["../../../src/plugins/print/PrintServiceImpl.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGnD,OAAO,EAMN,KAAK,YAAY,EACjB,MAAM,iBAAiB,CAAC;AAOzB,gFAAgF;AAChF,wBAAgB,iBAAiB,CAChC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,IAAI,SAAO,GACT,MAAM,CAaR;AAED,2DAA2D;AAC3D,wBAAgB,kBAAkB,CACjC,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,WAAW,EACtB,QAAQ,EAAE,cAAc,GACtB,YAAY,CA4Ed"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PrintOptions } from './PrintTypes.js';
|
|
2
|
+
/** Extracts CSS text from all adopted stylesheets on a ShadowRoot. */
|
|
3
|
+
export declare function extractAdoptedStyles(shadowRoot: ShadowRoot): string;
|
|
4
|
+
/** Snapshots --notectl-* CSS custom properties from the host element into a :root block. */
|
|
5
|
+
export declare function snapshotThemeTokens(host: HTMLElement): string;
|
|
6
|
+
/** Generates print-specific CSS rules based on PrintOptions. */
|
|
7
|
+
export declare function generatePrintCSS(options: PrintOptions): string;
|
|
8
|
+
/** Collects all CSS needed for print: adopted styles, theme tokens, print CSS, and custom CSS. */
|
|
9
|
+
export declare function collectAll(shadowRoot: ShadowRoot, host: HTMLElement, options: PrintOptions): string;
|
|
10
|
+
//# sourceMappingURL=PrintStyleCollector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrintStyleCollector.d.ts","sourceRoot":"","sources":["../../../src/plugins/print/PrintStyleCollector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,sEAAsE;AACtE,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAQnE;AAED,4FAA4F;AAC5F,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAgB7D;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CA4C9D;AAED,kGAAkG;AAClG,wBAAgB,UAAU,CACzB,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,WAAW,EACjB,OAAO,EAAE,YAAY,GACnB,MAAM,CAiBR"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { NodeTypeName } from '../../model/TypeBrands.js';
|
|
2
|
+
import { EventKey, ServiceKey } from '../Plugin.js';
|
|
3
|
+
export interface PrintOptions {
|
|
4
|
+
/** Page title shown in the browser print header. */
|
|
5
|
+
readonly title?: string;
|
|
6
|
+
/** Additional CSS appended to the print stylesheet. */
|
|
7
|
+
readonly customCSS?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Header HTML inserted once at the top of the print document.
|
|
10
|
+
* For repeating per-page headers, use toHTML() with server-side PDF generation.
|
|
11
|
+
*/
|
|
12
|
+
readonly header?: string | (() => string);
|
|
13
|
+
/**
|
|
14
|
+
* Footer HTML inserted once at the bottom of the print document.
|
|
15
|
+
* For repeating per-page footers, use toHTML() with server-side PDF generation.
|
|
16
|
+
*/
|
|
17
|
+
readonly footer?: string | (() => string);
|
|
18
|
+
/** Page margins as CSS value (e.g. '2cm'). */
|
|
19
|
+
readonly margin?: string;
|
|
20
|
+
/** Force page break before these block types. */
|
|
21
|
+
readonly pageBreakBefore?: readonly NodeTypeName[];
|
|
22
|
+
/** Exclude these block types from print output. */
|
|
23
|
+
readonly excludeBlockTypes?: readonly NodeTypeName[];
|
|
24
|
+
/** Print background colors and images. */
|
|
25
|
+
readonly printBackground?: boolean;
|
|
26
|
+
/** Page orientation. */
|
|
27
|
+
readonly orientation?: 'portrait' | 'landscape';
|
|
28
|
+
}
|
|
29
|
+
export interface PrintPluginConfig {
|
|
30
|
+
/** Default options applied to every print() call. */
|
|
31
|
+
readonly defaults?: PrintOptions;
|
|
32
|
+
/** Keyboard shortcut (default: 'Mod-P'). */
|
|
33
|
+
readonly keyBinding?: string;
|
|
34
|
+
/** Show toolbar button (default: true). */
|
|
35
|
+
readonly showToolbarItem?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface PrintService {
|
|
38
|
+
/** Prints the editor content with optional configuration. */
|
|
39
|
+
print(options?: PrintOptions): void;
|
|
40
|
+
/** Generates print-ready HTML as a complete document string. */
|
|
41
|
+
toHTML(options?: PrintOptions): string;
|
|
42
|
+
}
|
|
43
|
+
export declare const PRINT_SERVICE_KEY: ServiceKey<PrintService>;
|
|
44
|
+
export declare const BEFORE_PRINT: EventKey<BeforePrintEvent>;
|
|
45
|
+
export declare const AFTER_PRINT: EventKey<AfterPrintEvent>;
|
|
46
|
+
export interface BeforePrintEvent {
|
|
47
|
+
/** Options can be mutated — EventBus passes by reference. */
|
|
48
|
+
options: PrintOptions;
|
|
49
|
+
/** Set to true to cancel the print. */
|
|
50
|
+
cancelled: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface AfterPrintEvent {
|
|
53
|
+
/** The generated HTML (read-only). */
|
|
54
|
+
readonly html: string;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=PrintTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrintTypes.d.ts","sourceRoot":"","sources":["../../../src/plugins/print/PrintTypes.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAIpD,MAAM,WAAW,YAAY;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB,uDAAuD;IACvD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAE5B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAE1C;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IAE1C,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEzB,iDAAiD;IACjD,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAEnD,mDAAmD;IACnD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IAErD,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;IAEnC,wBAAwB;IACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,UAAU,GAAG,WAAW,CAAC;CAChD;AAID,MAAM,WAAW,iBAAiB;IACjC,qDAAqD;IACrD,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAC;IAEjC,4CAA4C;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAE7B,2CAA2C;IAC3C,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC;CACnC;AAID,MAAM,WAAW,YAAY;IAC5B,6DAA6D;IAC7D,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAEpC,gEAAgE;IAChE,MAAM,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;CACvC;AAID,eAAO,MAAM,iBAAiB,EAAE,UAAU,CAAC,YAAY,CAAyC,CAAC;AAEjG,eAAO,MAAM,YAAY,EAAE,QAAQ,CAAC,gBAAgB,CAEnD,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,eAAe,CAAgD,CAAC;AAInG,MAAM,WAAW,gBAAgB;IAChC,6DAA6D;IAC7D,OAAO,EAAE,YAAY,CAAC;IACtB,uCAAuC;IACvC,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC/B,sCAAsC;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB"}
|