@notectl/core 2.0.0 → 2.0.2
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 +12 -10
- package/dist/chunks/{AttrRegistry-B2AGfTE0.mjs → AttrRegistry-iNpjvcSG.mjs} +2 -2
- package/dist/chunks/{AttrRegistry-B2AGfTE0.mjs.map → AttrRegistry-iNpjvcSG.mjs.map} +1 -1
- package/dist/chunks/AttributedMarkCommands-BY1BSYWM.mjs +2 -0
- package/dist/chunks/AttributedMarkCommands-BY1BSYWM.mjs.map +1 -0
- package/dist/chunks/BlockInsertion-BJFhE0jA.mjs +2 -0
- package/dist/chunks/BlockInsertion-BJFhE0jA.mjs.map +1 -0
- package/dist/chunks/{ColorPickerPopup-DRzFvt7o.mjs → ColorPickerPopup-D6XjShhv.mjs} +2 -2
- package/dist/chunks/ColorPickerPopup-D6XjShhv.mjs.map +1 -0
- package/dist/chunks/CommandHelpers-M6mPS6Ww.mjs +2 -0
- package/dist/chunks/CommandHelpers-M6mPS6Ww.mjs.map +1 -0
- package/dist/chunks/Commands-D_gMCnVa.mjs +2 -0
- package/dist/chunks/Commands-D_gMCnVa.mjs.map +1 -0
- package/dist/chunks/Document-3pNX7ear.mjs +2 -0
- package/dist/chunks/Document-3pNX7ear.mjs.map +1 -0
- package/dist/chunks/DocumentParser-LvzDQOd1.mjs +2 -0
- package/dist/chunks/DocumentParser-LvzDQOd1.mjs.map +1 -0
- package/dist/chunks/DomUtils-CznMAZZg.mjs +2 -0
- package/dist/chunks/DomUtils-CznMAZZg.mjs.map +1 -0
- package/dist/chunks/HTMLUtils-Cxy99Ak2.mjs +2 -0
- package/dist/chunks/HTMLUtils-Cxy99Ak2.mjs.map +1 -0
- package/dist/chunks/HeadingPlugin-BmkeUXj8.mjs +2 -0
- package/dist/chunks/HeadingPlugin-BmkeUXj8.mjs.map +1 -0
- package/dist/chunks/MarkCommands-CeCa4WSC.mjs +2 -0
- package/dist/chunks/MarkCommands-CeCa4WSC.mjs.map +1 -0
- package/dist/chunks/NavigationQueries-11qe4j9x.mjs +2 -0
- package/dist/chunks/NavigationQueries-11qe4j9x.mjs.map +1 -0
- package/dist/chunks/NodeResolver-z0ReCR34.mjs +2 -0
- package/dist/chunks/NodeResolver-z0ReCR34.mjs.map +1 -0
- package/dist/chunks/NodeSelectionCommands-CXrOcPtG.mjs +2 -0
- package/dist/chunks/NodeSelectionCommands-CXrOcPtG.mjs.map +1 -0
- package/dist/chunks/NotectlEditor-BJD7-FFx.mjs +4 -0
- package/dist/chunks/NotectlEditor-BJD7-FFx.mjs.map +1 -0
- package/dist/chunks/PluginHelpers-CdPR0MuT.mjs +2 -0
- package/dist/chunks/PluginHelpers-CdPR0MuT.mjs.map +1 -0
- package/dist/chunks/PopupManager-0b_Q0m7K.mjs +2 -0
- package/dist/chunks/PopupManager-0b_Q0m7K.mjs.map +1 -0
- package/dist/chunks/PrintTypes-DukwDSWS.mjs +2 -0
- package/dist/chunks/{PrintTypes-ehbL7ipA.mjs.map → PrintTypes-DukwDSWS.mjs.map} +1 -1
- package/dist/chunks/{RangeIterator-CNI6smOg.mjs → RangeIterator-XFN5FaYf.mjs} +2 -2
- package/dist/chunks/{RangeIterator-CNI6smOg.mjs.map → RangeIterator-XFN5FaYf.mjs.map} +1 -1
- package/dist/chunks/{Selection-6-W6Flxc.mjs → Selection-DhbizDM4.mjs} +2 -2
- package/dist/chunks/{Selection-6-W6Flxc.mjs.map → Selection-DhbizDM4.mjs.map} +1 -1
- package/dist/chunks/SelectionTransactions-DzIZxcuN.mjs +2 -0
- package/dist/chunks/{SelectionTransactions-q71GEzgE.mjs.map → SelectionTransactions-DzIZxcuN.mjs.map} +1 -1
- package/dist/chunks/{TextDirectionLocale-DB_aqrMg.mjs → TextDirectionLocale-CKz0ZrH_.mjs} +2 -2
- package/dist/chunks/{TextDirectionLocale-DB_aqrMg.mjs.map → TextDirectionLocale-CKz0ZrH_.mjs.map} +1 -1
- package/dist/chunks/XmlPatterns-DxQXGjP8.mjs +2 -0
- package/dist/chunks/XmlPatterns-DxQXGjP8.mjs.map +1 -0
- package/dist/chunks/ar-b6VdnxAs.mjs +2 -0
- package/dist/chunks/ar-b6VdnxAs.mjs.map +1 -0
- package/dist/chunks/de-fXvs5vQT.mjs +2 -0
- package/dist/chunks/de-fXvs5vQT.mjs.map +1 -0
- package/dist/chunks/es-BTqy_aQ4.mjs +2 -0
- package/dist/chunks/es-BTqy_aQ4.mjs.map +1 -0
- package/dist/chunks/fr-VdiCNF4J.mjs +2 -0
- package/dist/chunks/fr-VdiCNF4J.mjs.map +1 -0
- package/dist/chunks/hi-BdtVhAzs.mjs +2 -0
- package/dist/chunks/hi-BdtVhAzs.mjs.map +1 -0
- package/dist/chunks/index-C-L4awHz.mjs +2 -0
- package/dist/chunks/index-C-L4awHz.mjs.map +1 -0
- package/dist/chunks/index-Cs9iqxhF.mjs +2 -0
- package/dist/chunks/index-Cs9iqxhF.mjs.map +1 -0
- package/dist/chunks/pt-K0BUlM9X.mjs +2 -0
- package/dist/chunks/pt-K0BUlM9X.mjs.map +1 -0
- package/dist/chunks/ru-Tzd5N37W.mjs +2 -0
- package/dist/chunks/ru-Tzd5N37W.mjs.map +1 -0
- package/dist/chunks/zh-Di3WqY4_.mjs +2 -0
- package/dist/chunks/zh-Di3WqY4_.mjs.map +1 -0
- package/dist/{input → commands}/BlockInsertion.d.ts +14 -1
- package/dist/commands/BlockInsertion.d.ts.map +1 -0
- package/dist/commands/CommandHelpers.d.ts +17 -2
- package/dist/commands/CommandHelpers.d.ts.map +1 -1
- package/dist/commands/Commands.d.ts.map +1 -1
- package/dist/commands/GapCursorCommands.d.ts.map +1 -1
- package/dist/commands/NodeSelectionCommands.d.ts +3 -8
- package/dist/commands/NodeSelectionCommands.d.ts.map +1 -1
- package/dist/commands/PasteCommand.d.ts.map +1 -1
- package/dist/editor/ContentSerializer.d.ts.map +1 -1
- package/dist/editor/EditorConfig.d.ts +50 -0
- package/dist/editor/EditorConfig.d.ts.map +1 -0
- package/dist/editor/EditorConfigController.d.ts +1 -1
- package/dist/editor/EditorConfigController.d.ts.map +1 -1
- package/dist/editor/EditorDOM.d.ts.map +1 -1
- package/dist/editor/EditorInitializer.d.ts +37 -0
- package/dist/editor/EditorInitializer.d.ts.map +1 -0
- package/dist/editor/EditorLifecycleCoordinator.d.ts +6 -1
- package/dist/editor/EditorLifecycleCoordinator.d.ts.map +1 -1
- package/dist/editor/EditorThemeController.d.ts.map +1 -1
- package/dist/editor/NotectlEditor.d.ts +13 -51
- package/dist/editor/NotectlEditor.d.ts.map +1 -1
- package/dist/editor/PluginBootstrapper.d.ts +1 -1
- package/dist/editor/PluginBootstrapper.d.ts.map +1 -1
- package/dist/editor/styles/code-block.d.ts +1 -1
- package/dist/editor/styles/code-block.d.ts.map +1 -1
- package/dist/editor/theme/ThemeEngine.d.ts.map +1 -1
- package/dist/editor/theme/ThemeTokens.d.ts +17 -1
- package/dist/editor/theme/ThemeTokens.d.ts.map +1 -1
- package/dist/full.d.ts +1 -0
- package/dist/full.d.ts.map +1 -1
- package/dist/full.mjs +1 -1
- package/dist/html.mjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/input/ClipboardHandler.d.ts +5 -0
- package/dist/input/ClipboardHandler.d.ts.map +1 -1
- package/dist/input/HTMLParser.d.ts +9 -5
- package/dist/input/HTMLParser.d.ts.map +1 -1
- package/dist/input/InputHandler.d.ts +1 -0
- package/dist/input/InputHandler.d.ts.map +1 -1
- package/dist/input/InputManager.d.ts +2 -0
- package/dist/input/InputManager.d.ts.map +1 -1
- package/dist/input/InternalClipboard.d.ts +2 -22
- package/dist/input/InternalClipboard.d.ts.map +1 -1
- package/dist/input/PasteHTMLHandler.d.ts +25 -0
- package/dist/input/PasteHTMLHandler.d.ts.map +1 -0
- package/dist/input/PasteHandler.d.ts +7 -25
- package/dist/input/PasteHandler.d.ts.map +1 -1
- package/dist/input/PasteRichBlockHandler.d.ts +23 -0
- package/dist/input/PasteRichBlockHandler.d.ts.map +1 -0
- package/dist/input/SelectionDocument.d.ts +10 -0
- package/dist/input/SelectionDocument.d.ts.map +1 -0
- package/dist/model/Document.d.ts.map +1 -1
- package/dist/model/HTMLUtils.d.ts +2 -0
- package/dist/model/HTMLUtils.d.ts.map +1 -1
- package/dist/model/PasteInterceptor.d.ts +21 -0
- package/dist/model/PasteInterceptor.d.ts.map +1 -0
- package/dist/model/RichBlockData.d.ts +34 -0
- package/dist/model/RichBlockData.d.ts.map +1 -0
- package/dist/model/SchemaRegistry.d.ts +2 -0
- package/dist/model/SchemaRegistry.d.ts.map +1 -1
- package/dist/notectl-core.mjs +1 -1
- package/dist/notectl-core.umd.js +1 -1
- package/dist/notectl-core.umd.js.map +1 -1
- package/dist/plugins/Plugin.d.ts +3 -0
- package/dist/plugins/Plugin.d.ts.map +1 -1
- package/dist/plugins/PluginContextFactory.d.ts +73 -0
- package/dist/plugins/PluginContextFactory.d.ts.map +1 -0
- package/dist/plugins/PluginManager.d.ts +12 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -1
- package/dist/plugins/alignment/AlignmentPlugin.d.ts.map +1 -1
- package/dist/plugins/alignment.mjs +1 -1
- package/dist/plugins/alignment.mjs.map +1 -1
- package/dist/plugins/blockquote/BlockquoteKeyboardHandlers.d.ts.map +1 -1
- package/dist/plugins/blockquote/BlockquotePlugin.d.ts.map +1 -1
- package/dist/plugins/blockquote.mjs +1 -1
- package/dist/plugins/blockquote.mjs.map +1 -1
- package/dist/plugins/caret-navigation/CaretNavigationPlugin.d.ts.map +1 -1
- package/dist/plugins/caret-navigation.mjs +1 -1
- package/dist/plugins/code-block/CodeBlockKeyboardHandlers.d.ts.map +1 -1
- package/dist/plugins/code-block/CodeBlockPlugin.d.ts +5 -0
- package/dist/plugins/code-block/CodeBlockPlugin.d.ts.map +1 -1
- package/dist/plugins/code-block/CodeBlockTypes.d.ts +7 -0
- package/dist/plugins/code-block/CodeBlockTypes.d.ts.map +1 -1
- package/dist/plugins/code-block/highlighter/RegexTokenizer.d.ts +14 -0
- package/dist/plugins/code-block/highlighter/RegexTokenizer.d.ts.map +1 -0
- package/dist/plugins/code-block/highlighter/TokenizerTypes.d.ts +15 -0
- package/dist/plugins/code-block/highlighter/TokenizerTypes.d.ts.map +1 -0
- package/dist/plugins/code-block/highlighter/languages/index.d.ts +3 -0
- package/dist/plugins/code-block/highlighter/languages/index.d.ts.map +1 -0
- package/dist/plugins/code-block/highlighter/languages/json.d.ts +3 -0
- package/dist/plugins/code-block/highlighter/languages/json.d.ts.map +1 -0
- package/dist/plugins/code-block/highlighter/languages/xml.d.ts +3 -0
- package/dist/plugins/code-block/highlighter/languages/xml.d.ts.map +1 -0
- package/dist/plugins/code-block/index.d.ts +5 -1
- package/dist/plugins/code-block/index.d.ts.map +1 -1
- package/dist/plugins/code-block.mjs +1 -1
- package/dist/plugins/code-block.mjs.map +1 -1
- package/dist/plugins/font/FontPlugin.d.ts.map +1 -1
- package/dist/plugins/font-size/FontSizePlugin.d.ts.map +1 -1
- package/dist/plugins/font-size.mjs +1 -1
- package/dist/plugins/font-size.mjs.map +1 -1
- package/dist/plugins/font.mjs +1 -1
- package/dist/plugins/font.mjs.map +1 -1
- package/dist/plugins/gap-cursor/GapCursorPlugin.d.ts.map +1 -1
- package/dist/plugins/gap-cursor.mjs +1 -1
- package/dist/plugins/hard-break.mjs +1 -1
- package/dist/plugins/heading/HeadingInputRules.d.ts.map +1 -1
- package/dist/plugins/heading/HeadingKeyboardHandlers.d.ts.map +1 -1
- package/dist/plugins/heading/HeadingPlugin.d.ts.map +1 -1
- package/dist/plugins/heading.mjs +1 -1
- package/dist/plugins/highlight/HighlightPlugin.d.ts.map +1 -1
- package/dist/plugins/highlight.mjs +1 -1
- package/dist/plugins/highlight.mjs.map +1 -1
- package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts.map +1 -1
- package/dist/plugins/horizontal-rule.mjs +1 -1
- package/dist/plugins/horizontal-rule.mjs.map +1 -1
- package/dist/plugins/image/ImageCommands.d.ts.map +1 -1
- package/dist/plugins/image/ImagePlugin.d.ts +0 -1
- package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
- package/dist/plugins/image/ImagePopup.d.ts +11 -0
- package/dist/plugins/image/ImagePopup.d.ts.map +1 -0
- package/dist/plugins/image.mjs +1 -1
- package/dist/plugins/image.mjs.map +1 -1
- package/dist/plugins/link/LinkPlugin.d.ts.map +1 -1
- package/dist/plugins/link.mjs +1 -1
- package/dist/plugins/link.mjs.map +1 -1
- package/dist/plugins/list/ListPlugin.d.ts.map +1 -1
- package/dist/plugins/list.mjs +1 -1
- package/dist/plugins/list.mjs.map +1 -1
- package/dist/plugins/print/PrintPlugin.d.ts.map +1 -1
- package/dist/plugins/print.mjs +1 -1
- package/dist/plugins/print.mjs.map +1 -1
- package/dist/plugins/shared/ColorMarkOperations.d.ts +1 -2
- package/dist/plugins/shared/ColorMarkOperations.d.ts.map +1 -1
- package/dist/plugins/shared/ColorPickerPopup.d.ts +1 -8
- package/dist/plugins/shared/ColorPickerPopup.d.ts.map +1 -1
- package/dist/plugins/shared/PluginHelpers.d.ts +8 -0
- package/dist/plugins/shared/PluginHelpers.d.ts.map +1 -1
- package/dist/plugins/shared/PopupManager.d.ts.map +1 -1
- package/dist/plugins/shared/XmlPatterns.d.ts +10 -0
- package/dist/plugins/shared/XmlPatterns.d.ts.map +1 -0
- package/dist/plugins/shared/index.d.ts +1 -0
- package/dist/plugins/shared/index.d.ts.map +1 -1
- package/dist/plugins/shared.mjs +1 -1
- package/dist/plugins/shared.mjs.map +1 -1
- package/dist/plugins/smart-paste/SmartPasteLocale.d.ts +7 -0
- package/dist/plugins/smart-paste/SmartPasteLocale.d.ts.map +1 -0
- package/dist/plugins/smart-paste/SmartPastePlugin.d.ts +19 -0
- package/dist/plugins/smart-paste/SmartPastePlugin.d.ts.map +1 -0
- package/dist/plugins/smart-paste/SmartPasteTypes.d.ts +24 -0
- package/dist/plugins/smart-paste/SmartPasteTypes.d.ts.map +1 -0
- package/dist/plugins/smart-paste/detectors/JsonDetector.d.ts +6 -0
- package/dist/plugins/smart-paste/detectors/JsonDetector.d.ts.map +1 -0
- package/dist/plugins/smart-paste/detectors/XmlDetector.d.ts +26 -0
- package/dist/plugins/smart-paste/detectors/XmlDetector.d.ts.map +1 -0
- package/dist/plugins/smart-paste/index.d.ts +7 -0
- package/dist/plugins/smart-paste/index.d.ts.map +1 -0
- package/dist/plugins/smart-paste/locales/ar.d.ts +4 -0
- package/dist/plugins/smart-paste/locales/ar.d.ts.map +1 -0
- package/dist/plugins/smart-paste/locales/de.d.ts +4 -0
- package/dist/plugins/smart-paste/locales/de.d.ts.map +1 -0
- package/dist/plugins/smart-paste/locales/es.d.ts +4 -0
- package/dist/plugins/smart-paste/locales/es.d.ts.map +1 -0
- package/dist/plugins/smart-paste/locales/fr.d.ts +4 -0
- package/dist/plugins/smart-paste/locales/fr.d.ts.map +1 -0
- package/dist/plugins/smart-paste/locales/hi.d.ts +4 -0
- package/dist/plugins/smart-paste/locales/hi.d.ts.map +1 -0
- package/dist/plugins/smart-paste/locales/pt.d.ts +4 -0
- package/dist/plugins/smart-paste/locales/pt.d.ts.map +1 -0
- package/dist/plugins/smart-paste/locales/ru.d.ts +4 -0
- package/dist/plugins/smart-paste/locales/ru.d.ts.map +1 -0
- package/dist/plugins/smart-paste/locales/zh.d.ts +4 -0
- package/dist/plugins/smart-paste/locales/zh.d.ts.map +1 -0
- package/dist/plugins/smart-paste.mjs +2 -0
- package/dist/plugins/smart-paste.mjs.map +1 -0
- package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts.map +1 -1
- package/dist/plugins/strikethrough.mjs +1 -1
- package/dist/plugins/strikethrough.mjs.map +1 -1
- package/dist/plugins/super-sub/SuperSubPlugin.d.ts.map +1 -1
- package/dist/plugins/super-sub.mjs +1 -1
- package/dist/plugins/super-sub.mjs.map +1 -1
- package/dist/plugins/table/TableCommands.d.ts +1 -0
- package/dist/plugins/table/TableCommands.d.ts.map +1 -1
- package/dist/plugins/table/TableContextMenu.d.ts.map +1 -1
- package/dist/plugins/table/TableNavigation.d.ts.map +1 -1
- package/dist/plugins/table/TablePlugin.d.ts.map +1 -1
- package/dist/plugins/table/TableSelection.d.ts.map +1 -1
- package/dist/plugins/table/index.d.ts +1 -0
- package/dist/plugins/table/index.d.ts.map +1 -1
- package/dist/plugins/table.mjs +1 -1
- package/dist/plugins/table.mjs.map +1 -1
- package/dist/plugins/text-color/TextColorPlugin.d.ts.map +1 -1
- package/dist/plugins/text-color.mjs +1 -1
- package/dist/plugins/text-color.mjs.map +1 -1
- package/dist/plugins/text-direction/TextDirectionCorePlugin.d.ts.map +1 -1
- package/dist/plugins/text-direction/TextDirectionPlugin.d.ts.map +1 -1
- package/dist/plugins/text-direction-advanced.mjs +1 -1
- package/dist/plugins/text-direction-advanced.mjs.map +1 -1
- package/dist/plugins/text-direction.mjs +1 -1
- package/dist/plugins/text-direction.mjs.map +1 -1
- package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts.map +1 -1
- package/dist/plugins/text-formatting.mjs +1 -1
- package/dist/plugins/text-formatting.mjs.map +1 -1
- package/dist/plugins/toolbar/ToolbarOverflowController.d.ts +2 -0
- package/dist/plugins/toolbar/ToolbarOverflowController.d.ts.map +1 -1
- package/dist/plugins/toolbar/ToolbarPlugin.d.ts.map +1 -1
- package/dist/plugins/toolbar.mjs +1 -1
- package/dist/plugins/toolbar.mjs.map +1 -1
- package/dist/presets/FullPreset.d.ts.map +1 -1
- package/dist/presets/PresetTypes.d.ts +2 -0
- package/dist/presets/PresetTypes.d.ts.map +1 -1
- package/dist/presets/full.mjs +1 -1
- package/dist/presets/full.mjs.map +1 -1
- package/dist/serialization/DocumentSerializer.d.ts.map +1 -1
- package/dist/state/InlineContentOps.d.ts.map +1 -1
- package/dist/state/StepInversion.d.ts +7 -0
- package/dist/state/StepInversion.d.ts.map +1 -0
- package/dist/state/Steps.d.ts +108 -0
- package/dist/state/Steps.d.ts.map +1 -0
- package/dist/state/Transaction.d.ts +5 -174
- package/dist/state/Transaction.d.ts.map +1 -1
- package/dist/state/TransactionBuilder.d.ts +69 -0
- package/dist/state/TransactionBuilder.d.ts.map +1 -0
- package/dist/test/TestUtils.d.ts.map +1 -1
- package/dist/view/CaretNavigation.d.ts.map +1 -1
- package/dist/view/DomUtils.d.ts +10 -1
- package/dist/view/DomUtils.d.ts.map +1 -1
- package/dist/view/EditorView.d.ts +10 -60
- package/dist/view/EditorView.d.ts.map +1 -1
- package/dist/view/EditorViewEvents.d.ts +54 -0
- package/dist/view/EditorViewEvents.d.ts.map +1 -0
- package/dist/view/EditorViewNavigation.d.ts +47 -0
- package/dist/view/EditorViewNavigation.d.ts.map +1 -0
- package/dist/view/SelectionSync.d.ts.map +1 -1
- package/dist/view/ViewMovementCommands.d.ts.map +1 -1
- package/package.json +12 -2
- package/dist/chunks/AttributedMarkCommands-BB7lzFct.mjs +0 -2
- package/dist/chunks/AttributedMarkCommands-BB7lzFct.mjs.map +0 -1
- package/dist/chunks/ColorPickerPopup-DRzFvt7o.mjs.map +0 -1
- package/dist/chunks/Commands-P9wS8qtN.mjs +0 -2
- package/dist/chunks/Commands-P9wS8qtN.mjs.map +0 -1
- package/dist/chunks/Document-BFYAonMF.mjs +0 -2
- package/dist/chunks/Document-BFYAonMF.mjs.map +0 -1
- package/dist/chunks/DocumentParser-DFcvVMGY.mjs +0 -2
- package/dist/chunks/DocumentParser-DFcvVMGY.mjs.map +0 -1
- package/dist/chunks/DomUtils-Cdz1eDKM.mjs +0 -2
- package/dist/chunks/DomUtils-Cdz1eDKM.mjs.map +0 -1
- package/dist/chunks/HTMLUtils-CCvQ5f83.mjs +0 -2
- package/dist/chunks/HTMLUtils-CCvQ5f83.mjs.map +0 -1
- package/dist/chunks/HeadingPlugin-DYy3IoT_.mjs +0 -2
- package/dist/chunks/HeadingPlugin-DYy3IoT_.mjs.map +0 -1
- package/dist/chunks/LocaleService-B6Z-wyAF.mjs +0 -2
- package/dist/chunks/LocaleService-B6Z-wyAF.mjs.map +0 -1
- package/dist/chunks/MarkCommands-B_erV7zz.mjs +0 -2
- package/dist/chunks/MarkCommands-B_erV7zz.mjs.map +0 -1
- package/dist/chunks/NavigationQueries-ogQuObz7.mjs +0 -2
- package/dist/chunks/NavigationQueries-ogQuObz7.mjs.map +0 -1
- package/dist/chunks/NotectlEditor-4NFnXLyD.mjs +0 -2
- package/dist/chunks/NotectlEditor-4NFnXLyD.mjs.map +0 -1
- package/dist/chunks/Plugin-OzM8Oxm_.mjs +0 -2
- package/dist/chunks/Plugin-OzM8Oxm_.mjs.map +0 -1
- package/dist/chunks/PluginHelpers-DjZt0pQi.mjs +0 -2
- package/dist/chunks/PluginHelpers-DjZt0pQi.mjs.map +0 -1
- package/dist/chunks/PopupManager-BM8IT6M7.mjs +0 -2
- package/dist/chunks/PopupManager-BM8IT6M7.mjs.map +0 -1
- package/dist/chunks/PrintTypes-ehbL7ipA.mjs +0 -2
- package/dist/chunks/SelectionTransactions-q71GEzgE.mjs +0 -2
- package/dist/chunks/index-C8xtb3SM.mjs +0 -2
- package/dist/chunks/index-C8xtb3SM.mjs.map +0 -1
- package/dist/chunks/index-DAoSt12h.mjs +0 -2
- package/dist/chunks/index-DAoSt12h.mjs.map +0 -1
- package/dist/input/BlockInsertion.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-formatting.mjs","sources":["../../src/plugins/text-formatting/TextFormattingLocale.ts","../../src/plugins/text-formatting/TextFormattingPlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the TextFormattingPlugin.\n */\n\n// --- Locale Interface ---\n\nexport interface TextFormattingLocale {\n\treadonly boldLabel: string;\n\treadonly italicLabel: string;\n\treadonly underlineLabel: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_EN: TextFormattingLocale = {\n\tboldLabel: 'Bold',\n\titalicLabel: 'Italic',\n\tunderlineLabel: 'Underline',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: Record<string, () => Promise<{ default: TextFormattingLocale }>> =\n\timport.meta.glob<{ default: TextFormattingLocale }>('./locales/*.ts', { eager: false });\n\nexport async function loadTextFormattingLocale(lang: string): Promise<TextFormattingLocale> {\n\tif (lang === 'en') return TEXT_FORMATTING_LOCALE_EN;\n\tconst loader = localeModules[`./locales/${lang}.ts`];\n\tif (!loader) return TEXT_FORMATTING_LOCALE_EN;\n\ttry {\n\t\tconst mod = await loader();\n\t\treturn mod.default;\n\t} catch {\n\t\treturn TEXT_FORMATTING_LOCALE_EN;\n\t}\n}\n","/**\n * TextFormattingPlugin: registers inline marks (bold, italic, underline)\n * with their MarkSpecs, toggle commands, keyboard shortcuts, and toolbar items.\n *\n * This plugin is data-driven — each mark type is defined declaratively and\n * all registrations (MarkSpec, command, keymap, toolbar item) are derived\n * from the same definition.\n *\n * Supports two separate config dimensions:\n * - Feature config (bold/italic/underline): controls whether the mark is\n * registered in the schema. When disabled, the keyboard shortcut does nothing.\n * - Toolbar config: controls whether the toolbar button is visible.\n * When a feature is disabled but toolbar is enabled, the button renders as disabled.\n */\n\nimport { isMarkActive, toggleMark } from '../../commands/Commands.js';\nimport { LocaleServiceKey } from '../../i18n/LocaleService.js';\nimport type { ParseRule } from '../../model/ParseRule.js';\nimport type { SanitizeConfig } from '../../model/SanitizeConfig.js';\nimport { markType as mkType } from '../../model/TypeBrands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport {\n\tTEXT_FORMATTING_LOCALE_EN,\n\ttype TextFormattingLocale,\n\tloadTextFormattingLocale,\n} from './TextFormattingLocale.js';\n\n// --- Configuration ---\n\n/** Controls toolbar button visibility per mark. */\nexport interface TextFormattingToolbarConfig {\n\treadonly bold?: boolean;\n\treadonly italic?: boolean;\n\treadonly underline?: boolean;\n}\n\n/** Controls which inline marks are enabled and which toolbar buttons are shown. */\nexport interface TextFormattingConfig {\n\treadonly bold: boolean;\n\treadonly italic: boolean;\n\treadonly underline: boolean;\n\treadonly toolbar?: TextFormattingToolbarConfig;\n\treadonly locale?: TextFormattingLocale;\n}\n\nconst DEFAULT_CONFIG: TextFormattingConfig = {\n\tbold: true,\n\titalic: true,\n\tunderline: true,\n};\n\n// --- Mark Definitions ---\n\ninterface MarkDefinition {\n\treadonly type: string;\n\treadonly configKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'locale'>;\n\treadonly rank: number;\n\treadonly tag: string;\n\treadonly icon: string;\n\treadonly keyBinding: string;\n\treadonly toHTMLString: (content: string) => string;\n\treadonly parseHTML: readonly ParseRule[];\n\treadonly sanitize: SanitizeConfig;\n}\n\nconst BOLD_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z\"/></svg>';\nconst ITALIC_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z\"/></svg>';\nconst UNDERLINE_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z\"/></svg>';\n\nconst MARK_DEFINITIONS: readonly MarkDefinition[] = [\n\t{\n\t\ttype: 'bold',\n\t\tconfigKey: 'bold',\n\t\trank: 0,\n\t\ttag: 'strong',\n\t\ticon: BOLD_ICON,\n\t\tkeyBinding: 'Mod-B',\n\t\ttoHTMLString: (content) => `<strong>${content}</strong>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'strong' },\n\t\t\t{\n\t\t\t\ttag: 'b',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst fw: string = el.style.fontWeight;\n\t\t\t\t\treturn fw === 'normal' || fw === '400' ? false : {};\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst fw: string = el.style.fontWeight;\n\t\t\t\t\tif (!fw) return false;\n\t\t\t\t\tif (fw === 'bold') return {};\n\t\t\t\t\tconst numeric: number = Number.parseInt(fw, 10);\n\t\t\t\t\treturn !Number.isNaN(numeric) && numeric >= 700 ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['strong', 'b'] },\n\t},\n\t{\n\t\ttype: 'italic',\n\t\tconfigKey: 'italic',\n\t\trank: 1,\n\t\ttag: 'em',\n\t\ticon: ITALIC_ICON,\n\t\tkeyBinding: 'Mod-I',\n\t\ttoHTMLString: (content) => `<em>${content}</em>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'em' },\n\t\t\t{ tag: 'i' },\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\treturn el.style.fontStyle === 'italic' ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['em', 'i'] },\n\t},\n\t{\n\t\ttype: 'underline',\n\t\tconfigKey: 'underline',\n\t\trank: 2,\n\t\ttag: 'u',\n\t\ticon: UNDERLINE_ICON,\n\t\tkeyBinding: 'Mod-U',\n\t\ttoHTMLString: (content) => `<u>${content}</u>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'u' },\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\treturn el.style.textDecoration.includes('underline') ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['u'] },\n\t},\n];\n\n// --- Plugin ---\n\nexport class TextFormattingPlugin implements Plugin {\n\treadonly id = 'text-formatting';\n\treadonly name = 'Text Formatting';\n\treadonly priority = 20;\n\n\tprivate readonly config: TextFormattingConfig;\n\tprivate locale!: TextFormattingLocale;\n\n\tconstructor(config?: Partial<TextFormattingConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tif (this.config.locale) {\n\t\t\tthis.locale = this.config.locale;\n\t\t} else {\n\t\t\tconst service = context.getService(LocaleServiceKey);\n\t\t\tconst lang: string = service?.getLocale() ?? 'en';\n\t\t\tthis.locale =\n\t\t\t\tlang === 'en' ? TEXT_FORMATTING_LOCALE_EN : await loadTextFormattingLocale(lang);\n\t\t}\n\n\t\tconst enabledMarks = MARK_DEFINITIONS.filter((def) => this.config[def.configKey]);\n\n\t\tfor (const def of enabledMarks) {\n\t\t\tthis.registerMark(context, def);\n\t\t}\n\n\t\tthis.registerKeymaps(context, enabledMarks);\n\n\t\t// Register disabled placeholder buttons for marks that are disabled\n\t\t// as features but explicitly requested in the toolbar config\n\t\tthis.registerDisabledToolbarItems(context);\n\t}\n\n\tprivate registerMark(context: PluginContext, def: MarkDefinition): void {\n\t\tconst commandName = toCommandName(def.type);\n\t\tconst toolbarVisible = this.isToolbarVisible(def.configKey);\n\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: def.type,\n\t\t\trank: def.rank,\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement(def.tag);\n\t\t\t},\n\t\t\ttoHTMLString: (_mark, content) => def.toHTMLString(content),\n\t\t\tparseHTML: def.parseHTML,\n\t\t\tsanitize: def.sanitize,\n\t\t});\n\n\t\tcontext.registerCommand(commandName, () => {\n\t\t\tconst tr = toggleMark(context.getState(), mkType(def.type));\n\t\t\tif (tr) {\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\n\t\tif (toolbarVisible) {\n\t\t\tconst label: string = this.getMarkLabel(def.type);\n\t\t\tcontext.registerToolbarItem({\n\t\t\t\tid: def.type,\n\t\t\t\tgroup: 'format',\n\t\t\t\ticon: def.icon,\n\t\t\t\tlabel,\n\t\t\t\ttooltip: `${label} (${formatShortcut(def.keyBinding)})`,\n\t\t\t\tcommand: commandName,\n\t\t\t\tisActive: (state) => isMarkActive(state, mkType(def.type)),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerKeymaps(context: PluginContext, marks: readonly MarkDefinition[]): void {\n\t\tconst keymap: Record<string, () => boolean> = {};\n\t\tfor (const def of marks) {\n\t\t\tconst commandName = toCommandName(def.type);\n\t\t\tkeymap[def.keyBinding] = () => context.executeCommand(commandName);\n\t\t}\n\t\tif (Object.keys(keymap).length > 0) {\n\t\t\tcontext.registerKeymap(keymap);\n\t\t}\n\t}\n\n\t/**\n\t * Registers disabled toolbar buttons for marks whose feature is disabled\n\t * but whose toolbar button is explicitly requested.\n\t */\n\tprivate registerDisabledToolbarItems(context: PluginContext): void {\n\t\tif (!this.config.toolbar) return;\n\n\t\tfor (const def of MARK_DEFINITIONS) {\n\t\t\tconst featureEnabled = this.config[def.configKey];\n\t\t\tconst toolbarVisible = this.config.toolbar[def.configKey] ?? true;\n\n\t\t\tif (!featureEnabled && toolbarVisible) {\n\t\t\t\tcontext.registerToolbarItem({\n\t\t\t\t\tid: def.type,\n\t\t\t\t\tgroup: 'format',\n\t\t\t\t\ticon: def.icon,\n\t\t\t\t\tlabel: this.getMarkLabel(def.type),\n\t\t\t\t\tcommand: toCommandName(def.type),\n\t\t\t\t\tisEnabled: () => false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getMarkLabel(type: string): string {\n\t\tconst key = `${type}Label` as keyof TextFormattingLocale;\n\t\treturn this.locale[key] as string;\n\t}\n\n\t/** Checks if a toolbar button should be visible for a given mark. */\n\tprivate isToolbarVisible(\n\t\tconfigKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'locale'>,\n\t): boolean {\n\t\tif (!this.config.toolbar) return true;\n\t\treturn this.config.toolbar[configKey] ?? true;\n\t}\n}\n\n/** Converts a mark type to its toggle command name (e.g. 'bold' → 'toggleBold'). */\nfunction toCommandName(markType: string): string {\n\treturn `toggle${markType.charAt(0).toUpperCase()}${markType.slice(1)}`;\n}\n"],"names":["TEXT_FORMATTING_LOCALE_EN","boldLabel","italicLabel","underlineLabel","localeModules","assign","import","async","loadTextFormattingLocale","lang","loader","default","DEFAULT_CONFIG","bold","italic","underline","MARK_DEFINITIONS","type","configKey","rank","tag","icon","keyBinding","toHTMLString","content","parseHTML","getAttrs","el","fw","style","fontWeight","numeric","Number","parseInt","isNaN","sanitize","tags","fontStyle","textDecoration","includes","TextFormattingPlugin","id","name","priority","config","locale","constructor","this","init","context","service","getService","LocaleServiceKey","getLocale","enabledMarks","filter","def","registerMark","registerKeymaps","registerDisabledToolbarItems","commandName","toCommandName","toolbarVisible","isToolbarVisible","registerMarkSpec","toDOM","document","createElement","_mark","registerCommand","tr","toggleMark","getState","mkType","dispatch","label","getMarkLabel","registerToolbarItem","group","tooltip","formatShortcut","command","isActive","state","isMarkActive","marks","keymap","executeCommand","Object","keys","length","registerKeymap","toolbar","featureEnabled","isEnabled","key","markType","charAt","toUpperCase","slice"],"mappings":"4OAcO,MAAMA,EAAkD,CAC9DC,UAAW,OACXC,YAAa,SACbC,eAAgB,aAKXC,wBACLC,OAAA,CAAA,kBAAA,IAAAC,OAAA,6BAAA,kBAAA,IAAAA,OAAA,6BAAA,kBAAA,IAAAA,OAAA,6BAAA,kBAAA,IAAAA,OAAA,6BAAA,kBAAA,IAAAA,OAAA,6BAAA,kBAAA,IAAAA,OAAA,6BAAA,kBAAA,IAAAA,OAAA,6BAAA,kBAAA,IAAAA,OAAA,+BAEDC,eAAsBC,EAAyBC,GAC9C,GAAa,OAATA,EAAe,OAAOT,EAC1B,MAAMU,EAASN,EAAc,aAAaK,QAC1C,IAAKC,EAAQ,OAAOV,EACpB,IAEC,aADkBU,KACPC,OACZ,CAAA,MACC,OAAOX,CACR,CACD,CCWA,MAAMY,EAAuC,CAC5CC,MAAM,EACNC,QAAQ,EACRC,WAAW,GAwBNC,EAA8C,CACnD,CACCC,KAAM,OACNC,UAAW,OACXC,KAAM,EACNC,IAAK,SACLC,KAZD,sTAaCC,WAAY,QACZC,aAAeC,GAAY,WAAWA,aACtCC,UAAW,CACV,CAAEL,IAAK,UACP,CACCA,IAAK,IACLM,SAAWC,IACV,MAAMC,EAAaD,EAAGE,MAAMC,WAC5B,MAAc,WAAPF,GAA0B,QAAPA,GAAuB,CAAA,IAGnD,CACCR,IAAK,OACLM,SAAWC,IACV,MAAMC,EAAaD,EAAGE,MAAMC,WAC5B,IAAKF,EAAI,OAAO,EAChB,GAAW,SAAPA,EAAe,MAAO,CAAA,EAC1B,MAAMG,EAAkBC,OAAOC,SAASL,EAAI,IAC5C,OAAQI,OAAOE,MAAMH,IAAYA,GAAW,KAAM,CAAA,KAIrDI,SAAU,CAAEC,KAAM,CAAC,SAAU,OAE9B,CACCnB,KAAM,SACNC,UAAW,SACXC,KAAM,EACNC,IAAK,KACLC,KAxCD,iIAyCCC,WAAY,QACZC,aAAeC,GAAY,OAAOA,SAClCC,UAAW,CACV,CAAEL,IAAK,MACP,CAAEA,IAAK,KACP,CACCA,IAAK,OACLM,SAAWC,GACoB,WAAvBA,EAAGE,MAAMQ,WAAyB,CAAA,IAI5CF,SAAU,CAAEC,KAAM,CAAC,KAAM,OAE1B,CACCnB,KAAM,YACNC,UAAW,YACXC,KAAM,EACNC,IAAK,IACLC,KA1DD,oMA2DCC,WAAY,QACZC,aAAeC,GAAY,MAAMA,QACjCC,UAAW,CACV,CAAEL,IAAK,KACP,CACCA,IAAK,OACLM,SAAWC,KACHA,EAAGE,MAAMS,eAAeC,SAAS,cAAe,CAAA,IAI1DJ,SAAU,CAAEC,KAAM,CAAC,QAMd,MAAMI,EACHC,GAAK,kBACLC,KAAO,kBACPC,SAAW,GAEHC,OACTC,OAER,WAAAC,CAAYF,GACXG,KAAKH,OAAS,IAAKhC,KAAmBgC,EACvC,CAEA,UAAMI,CAAKC,GACV,GAAIF,KAAKH,OAAOC,OACfE,KAAKF,OAASE,KAAKH,OAAOC,WACpB,CACN,MAAMK,EAAUD,EAAQE,WAAWC,GAC7B3C,EAAeyC,GAASG,aAAe,KAC7CN,KAAKF,OACK,OAATpC,EAAgBT,QAAkCQ,EAAyBC,EAC7E,CAEA,MAAM6C,EAAetC,EAAiBuC,OAAQC,GAAQT,KAAKH,OAAOY,EAAItC,YAEtE,IAAA,MAAWsC,KAAOF,EACjBP,KAAKU,aAAaR,EAASO,GAG5BT,KAAKW,gBAAgBT,EAASK,GAI9BP,KAAKY,6BAA6BV,EACnC,CAEQ,YAAAQ,CAAaR,EAAwBO,GAC5C,MAAMI,EAAcC,EAAcL,EAAIvC,MAChC6C,EAAiBf,KAAKgB,iBAAiBP,EAAItC,WAsBjD,GApBA+B,EAAQe,iBAAiB,CACxB/C,KAAMuC,EAAIvC,KACVE,KAAMqC,EAAIrC,KACV8C,MAAA,IACQC,SAASC,cAAcX,EAAIpC,KAEnCG,aAAc,CAAC6C,EAAO5C,IAAYgC,EAAIjC,aAAaC,GACnDC,UAAW+B,EAAI/B,UACfU,SAAUqB,EAAIrB,WAGfc,EAAQoB,gBAAgBT,EAAa,KACpC,MAAMU,EAAKC,EAAWtB,EAAQuB,WAAYC,EAAOjB,EAAIvC,OACrD,QAAIqD,IACHrB,EAAQyB,SAASJ,IACV,KAKLR,EAAgB,CACnB,MAAMa,EAAgB5B,KAAK6B,aAAapB,EAAIvC,MAC5CgC,EAAQ4B,oBAAoB,CAC3BpC,GAAIe,EAAIvC,KACR6D,MAAO,SACPzD,KAAMmC,EAAInC,KACVsD,QACAI,QAAS,GAAGJ,MAAUK,EAAexB,EAAIlC,eACzC2D,QAASrB,EACTsB,SAAWC,GAAUC,EAAaD,EAAOV,EAAOjB,EAAIvC,QAEtD,CACD,CAEQ,eAAAyC,CAAgBT,EAAwBoC,GAC/C,MAAMC,EAAwC,CAAA,EAC9C,IAAA,MAAW9B,KAAO6B,EAAO,CACxB,MAAMzB,EAAcC,EAAcL,EAAIvC,MACtCqE,EAAO9B,EAAIlC,YAAc,IAAM2B,EAAQsC,eAAe3B,EACvD,CACI4B,OAAOC,KAAKH,GAAQI,OAAS,GAChCzC,EAAQ0C,eAAeL,EAEzB,CAMQ,4BAAA3B,CAA6BV,GACpC,GAAKF,KAAKH,OAAOgD,QAEjB,IAAA,MAAWpC,KAAOxC,EAAkB,CACnC,MAAM6E,EAAiB9C,KAAKH,OAAOY,EAAItC,WACjC4C,EAAiBf,KAAKH,OAAOgD,QAAQpC,EAAItC,aAAc,GAExD2E,GAAkB/B,GACtBb,EAAQ4B,oBAAoB,CAC3BpC,GAAIe,EAAIvC,KACR6D,MAAO,SACPzD,KAAMmC,EAAInC,KACVsD,MAAO5B,KAAK6B,aAAapB,EAAIvC,MAC7BgE,QAASpB,EAAcL,EAAIvC,MAC3B6E,UAAW,KAAM,GAGpB,CACD,CAEQ,YAAAlB,CAAa3D,GACpB,MAAM8E,EAAM,GAAG9E,SACf,OAAO8B,KAAKF,OAAOkD,EACpB,CAGQ,gBAAAhC,CACP7C,GAEA,OAAK6B,KAAKH,OAAOgD,UACV7C,KAAKH,OAAOgD,QAAQ1E,KAAc,EAC1C,EAID,SAAS2C,EAAcmC,GACtB,MAAO,SAASA,EAASC,OAAO,GAAGC,gBAAgBF,EAASG,MAAM,IACnE"}
|
|
1
|
+
{"version":3,"file":"text-formatting.mjs","sources":["../../src/plugins/text-formatting/TextFormattingLocale.ts","../../src/plugins/text-formatting/TextFormattingPlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the TextFormattingPlugin.\n */\n\n// --- Locale Interface ---\n\nexport interface TextFormattingLocale {\n\treadonly boldLabel: string;\n\treadonly italicLabel: string;\n\treadonly underlineLabel: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_EN: TextFormattingLocale = {\n\tboldLabel: 'Bold',\n\titalicLabel: 'Italic',\n\tunderlineLabel: 'Underline',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: Record<string, () => Promise<{ default: TextFormattingLocale }>> =\n\timport.meta.glob<{ default: TextFormattingLocale }>('./locales/*.ts', { eager: false });\n\nexport async function loadTextFormattingLocale(lang: string): Promise<TextFormattingLocale> {\n\tif (lang === 'en') return TEXT_FORMATTING_LOCALE_EN;\n\tconst loader = localeModules[`./locales/${lang}.ts`];\n\tif (!loader) return TEXT_FORMATTING_LOCALE_EN;\n\ttry {\n\t\tconst mod = await loader();\n\t\treturn mod.default;\n\t} catch {\n\t\treturn TEXT_FORMATTING_LOCALE_EN;\n\t}\n}\n","/**\n * TextFormattingPlugin: registers inline marks (bold, italic, underline)\n * with their MarkSpecs, toggle commands, keyboard shortcuts, and toolbar items.\n *\n * This plugin is data-driven — each mark type is defined declaratively and\n * all registrations (MarkSpec, command, keymap, toolbar item) are derived\n * from the same definition.\n *\n * Supports two separate config dimensions:\n * - Feature config (bold/italic/underline): controls whether the mark is\n * registered in the schema. When disabled, the keyboard shortcut does nothing.\n * - Toolbar config: controls whether the toolbar button is visible.\n * When a feature is disabled but toolbar is enabled, the button renders as disabled.\n */\n\nimport { isMarkActive, toggleMark } from '../../commands/Commands.js';\nimport type { ParseRule } from '../../model/ParseRule.js';\nimport type { SanitizeConfig } from '../../model/SanitizeConfig.js';\nimport { markType as mkType } from '../../model/TypeBrands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { resolveLocale, toCommandName } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport {\n\tTEXT_FORMATTING_LOCALE_EN,\n\ttype TextFormattingLocale,\n\tloadTextFormattingLocale,\n} from './TextFormattingLocale.js';\n\n// --- Configuration ---\n\n/** Controls toolbar button visibility per mark. */\nexport interface TextFormattingToolbarConfig {\n\treadonly bold?: boolean;\n\treadonly italic?: boolean;\n\treadonly underline?: boolean;\n}\n\n/** Controls which inline marks are enabled and which toolbar buttons are shown. */\nexport interface TextFormattingConfig {\n\treadonly bold: boolean;\n\treadonly italic: boolean;\n\treadonly underline: boolean;\n\treadonly toolbar?: TextFormattingToolbarConfig;\n\treadonly locale?: TextFormattingLocale;\n}\n\nconst DEFAULT_CONFIG: TextFormattingConfig = {\n\tbold: true,\n\titalic: true,\n\tunderline: true,\n};\n\n// --- Mark Definitions ---\n\ninterface MarkDefinition {\n\treadonly type: string;\n\treadonly configKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'locale'>;\n\treadonly rank: number;\n\treadonly tag: string;\n\treadonly icon: string;\n\treadonly keyBinding: string;\n\treadonly toHTMLString: (content: string) => string;\n\treadonly parseHTML: readonly ParseRule[];\n\treadonly sanitize: SanitizeConfig;\n}\n\nconst BOLD_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z\"/></svg>';\nconst ITALIC_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z\"/></svg>';\nconst UNDERLINE_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z\"/></svg>';\n\nconst MARK_DEFINITIONS: readonly MarkDefinition[] = [\n\t{\n\t\ttype: 'bold',\n\t\tconfigKey: 'bold',\n\t\trank: 0,\n\t\ttag: 'strong',\n\t\ticon: BOLD_ICON,\n\t\tkeyBinding: 'Mod-B',\n\t\ttoHTMLString: (content) => `<strong>${content}</strong>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'strong' },\n\t\t\t{\n\t\t\t\ttag: 'b',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst fw: string = el.style.fontWeight;\n\t\t\t\t\treturn fw === 'normal' || fw === '400' ? false : {};\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst fw: string = el.style.fontWeight;\n\t\t\t\t\tif (!fw) return false;\n\t\t\t\t\tif (fw === 'bold') return {};\n\t\t\t\t\tconst numeric: number = Number.parseInt(fw, 10);\n\t\t\t\t\treturn !Number.isNaN(numeric) && numeric >= 700 ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['strong', 'b'] },\n\t},\n\t{\n\t\ttype: 'italic',\n\t\tconfigKey: 'italic',\n\t\trank: 1,\n\t\ttag: 'em',\n\t\ticon: ITALIC_ICON,\n\t\tkeyBinding: 'Mod-I',\n\t\ttoHTMLString: (content) => `<em>${content}</em>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'em' },\n\t\t\t{ tag: 'i' },\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\treturn el.style.fontStyle === 'italic' ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['em', 'i'] },\n\t},\n\t{\n\t\ttype: 'underline',\n\t\tconfigKey: 'underline',\n\t\trank: 2,\n\t\ttag: 'u',\n\t\ticon: UNDERLINE_ICON,\n\t\tkeyBinding: 'Mod-U',\n\t\ttoHTMLString: (content) => `<u>${content}</u>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'u' },\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\treturn el.style.textDecoration.includes('underline') ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['u'] },\n\t},\n];\n\n// --- Plugin ---\n\nexport class TextFormattingPlugin implements Plugin {\n\treadonly id = 'text-formatting';\n\treadonly name = 'Text Formatting';\n\treadonly priority = 20;\n\n\tprivate readonly config: TextFormattingConfig;\n\tprivate locale!: TextFormattingLocale;\n\n\tconstructor(config?: Partial<TextFormattingConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tTEXT_FORMATTING_LOCALE_EN,\n\t\t\tloadTextFormattingLocale,\n\t\t);\n\n\t\tconst enabledMarks = MARK_DEFINITIONS.filter((def) => this.config[def.configKey]);\n\n\t\tfor (const def of enabledMarks) {\n\t\t\tthis.registerMark(context, def);\n\t\t}\n\n\t\tthis.registerKeymaps(context, enabledMarks);\n\n\t\t// Register disabled placeholder buttons for marks that are disabled\n\t\t// as features but explicitly requested in the toolbar config\n\t\tthis.registerDisabledToolbarItems(context);\n\t}\n\n\tprivate registerMark(context: PluginContext, def: MarkDefinition): void {\n\t\tconst commandName = toCommandName(def.type);\n\t\tconst toolbarVisible = this.isToolbarVisible(def.configKey);\n\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: def.type,\n\t\t\trank: def.rank,\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement(def.tag);\n\t\t\t},\n\t\t\ttoHTMLString: (_mark, content) => def.toHTMLString(content),\n\t\t\tparseHTML: def.parseHTML,\n\t\t\tsanitize: def.sanitize,\n\t\t});\n\n\t\tcontext.registerCommand(commandName, () => {\n\t\t\tconst tr = toggleMark(context.getState(), mkType(def.type));\n\t\t\tif (tr) {\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\n\t\tif (toolbarVisible) {\n\t\t\tconst label: string = this.getMarkLabel(def.type);\n\t\t\tcontext.registerToolbarItem({\n\t\t\t\tid: def.type,\n\t\t\t\tgroup: 'format',\n\t\t\t\ticon: def.icon,\n\t\t\t\tlabel,\n\t\t\t\ttooltip: `${label} (${formatShortcut(def.keyBinding)})`,\n\t\t\t\tcommand: commandName,\n\t\t\t\tisActive: (state) => isMarkActive(state, mkType(def.type)),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerKeymaps(context: PluginContext, marks: readonly MarkDefinition[]): void {\n\t\tconst keymap: Record<string, () => boolean> = {};\n\t\tfor (const def of marks) {\n\t\t\tconst commandName = toCommandName(def.type);\n\t\t\tkeymap[def.keyBinding] = () => context.executeCommand(commandName);\n\t\t}\n\t\tif (Object.keys(keymap).length > 0) {\n\t\t\tcontext.registerKeymap(keymap);\n\t\t}\n\t}\n\n\t/**\n\t * Registers disabled toolbar buttons for marks whose feature is disabled\n\t * but whose toolbar button is explicitly requested.\n\t */\n\tprivate registerDisabledToolbarItems(context: PluginContext): void {\n\t\tif (!this.config.toolbar) return;\n\n\t\tfor (const def of MARK_DEFINITIONS) {\n\t\t\tconst featureEnabled = this.config[def.configKey];\n\t\t\tconst toolbarVisible = this.config.toolbar[def.configKey] ?? true;\n\n\t\t\tif (!featureEnabled && toolbarVisible) {\n\t\t\t\tcontext.registerToolbarItem({\n\t\t\t\t\tid: def.type,\n\t\t\t\t\tgroup: 'format',\n\t\t\t\t\ticon: def.icon,\n\t\t\t\t\tlabel: this.getMarkLabel(def.type),\n\t\t\t\t\tcommand: toCommandName(def.type),\n\t\t\t\t\tisEnabled: () => false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getMarkLabel(type: string): string {\n\t\tconst key = `${type}Label` as keyof TextFormattingLocale;\n\t\treturn this.locale[key] as string;\n\t}\n\n\t/** Checks if a toolbar button should be visible for a given mark. */\n\tprivate isToolbarVisible(\n\t\tconfigKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'locale'>,\n\t): boolean {\n\t\tif (!this.config.toolbar) return true;\n\t\treturn this.config.toolbar[configKey] ?? true;\n\t}\n}\n"],"names":["TEXT_FORMATTING_LOCALE_EN","boldLabel","italicLabel","underlineLabel","localeModules","assign","import","async","loadTextFormattingLocale","lang","loader","default","DEFAULT_CONFIG","bold","italic","underline","MARK_DEFINITIONS","type","configKey","rank","tag","icon","keyBinding","toHTMLString","content","parseHTML","getAttrs","el","fw","style","fontWeight","numeric","Number","parseInt","isNaN","sanitize","tags","fontStyle","textDecoration","includes","TextFormattingPlugin","id","name","priority","config","locale","constructor","this","init","context","resolveLocale","enabledMarks","filter","def","registerMark","registerKeymaps","registerDisabledToolbarItems","commandName","toCommandName","toolbarVisible","isToolbarVisible","registerMarkSpec","toDOM","document","createElement","_mark","registerCommand","tr","toggleMark","getState","mkType","dispatch","label","getMarkLabel","registerToolbarItem","group","tooltip","formatShortcut","command","isActive","state","isMarkActive","marks","keymap","executeCommand","Object","keys","length","registerKeymap","toolbar","featureEnabled","isEnabled","key"],"mappings":"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"}
|
|
@@ -28,6 +28,8 @@ export declare class ToolbarOverflowController {
|
|
|
28
28
|
private overflowEntries;
|
|
29
29
|
private resizeObserver;
|
|
30
30
|
private closeHandler;
|
|
31
|
+
private closeHandlerTimer;
|
|
32
|
+
private closeHandlerAttached;
|
|
31
33
|
constructor(config: OverflowControllerConfig);
|
|
32
34
|
/** Called after renderItems() — stores button references and recalculates. */
|
|
33
35
|
update(buttons: readonly {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolbarOverflowController.d.ts","sourceRoot":"","sources":["../../../src/plugins/toolbar/ToolbarOverflowController.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AASpD,KAAK,gBAAgB,GAAG,CACvB,cAAc,EAAE,SAAS,iBAAiB,EAAE,EAC5C,cAAc,EAAE,iBAAiB,GAAG,IAAI,KACpC,IAAI,CAAC;AAEV,KAAK,eAAe,GAAG,CAAC,cAAc,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;AAEtF,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;IAChD,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACrC;AAcD,qBAAa,yBAAyB;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IAEnD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,YAAY,CAA0C;
|
|
1
|
+
{"version":3,"file":"ToolbarOverflowController.d.ts","sourceRoot":"","sources":["../../../src/plugins/toolbar/ToolbarOverflowController.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAE9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AASpD,KAAK,gBAAgB,GAAG,CACvB,cAAc,EAAE,SAAS,iBAAiB,EAAE,EAC5C,cAAc,EAAE,iBAAiB,GAAG,IAAI,KACpC,IAAI,CAAC;AAEV,KAAK,eAAe,GAAG,CAAC,cAAc,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;AAEtF,MAAM,WAAW,wBAAwB;IACxC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,gBAAgB,EAAE,MAAM,OAAO,GAAG,IAAI,CAAC;IAChD,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;CACrC;AAcD,qBAAa,yBAAyB;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;IACxC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAuB;IACxD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IAEnD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,YAAY,CAA0C;IAC9D,OAAO,CAAC,iBAAiB,CAA8C;IACvE,OAAO,CAAC,oBAAoB,CAAS;gBAEzB,MAAM,EAAE,wBAAwB;IAa5C,8EAA8E;IAC9E,MAAM,CAAC,OAAO,EAAE,SAAS;QAAE,OAAO,EAAE,iBAAiB,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE,EAAE,GAAG,IAAI;IAKnF,6EAA6E;IAC7E,WAAW,IAAI,IAAI;IA8DnB,8EAA8E;IAC9E,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAuC1C,mEAAmE;IACnE,OAAO,IAAI,IAAI;IAYf,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,wBAAwB;IAQhC,OAAO,CAAC,oBAAoB;IAsB5B,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,YAAY;IA+CpB,OAAO,CAAC,mBAAmB;IA4C3B,OAAO,CAAC,gBAAgB;IA0BxB,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,qBAAqB;IA8C7B,OAAO,CAAC,sBAAsB;IAe9B,OAAO,CAAC,YAAY;CAMpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolbarPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/toolbar/ToolbarPlugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"ToolbarPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/toolbar/ToolbarPlugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAYxE,OAAO,EAEN,KAAK,uBAAuB,IAAI,2BAA2B,EAC3D,MAAM,8BAA8B,CAAC;AAQtC,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,2BAA2B,CAAC;CAChD;AAID,MAAM,WAAW,iBAAiB;IACjC,sEAAsE;IACtE,OAAO,IAAI,IAAI,CAAC;IAChB,+CAA+C;IAC/C,UAAU,IAAI,IAAI,CAAC;CACnB;AAED,eAAO,MAAM,iBAAiB,+BAA+C,CAAC;AAU9E,qBAAa,aAAc,YAAW,MAAM;IAC3C,QAAQ,CAAC,EAAE,aAAa;IACxB,QAAQ,CAAC,IAAI,aAAa;IAC1B,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,OAAO,CAA8B;IAC7C,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,OAAO,CAAuB;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqB;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,OAAO,CAAC,gBAAgB,CAA8B;IACtD,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,eAAe,CAAuC;IAC9D,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,kBAAkB,CAA0C;IACpE,OAAO,CAAC,eAAe,CAA2B;IAClD,OAAO,CAAC,MAAM,CAAiB;gBAEnB,YAAY,CAAC,EAAE,mBAAmB;IAKxC,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBjD,6CAA6C;IAC7C,mBAAmB,IAAI,2BAA2B;IAIlD,iDAAiD;IACjD,mBAAmB,CAAC,QAAQ,EAAE,2BAA2B,GAAG,IAAI;IAQhE,OAAO,IAAI,IAAI;IAIf,OAAO,IAAI,IAAI;IAkBf,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI;IAIpF,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAMzC,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAavC,OAAO,CAAC,oBAAoB;IAqB5B,mHAAmH;IACnH,OAAO,CAAC,qBAAqB;IAgC7B,OAAO,CAAC,WAAW;IA8BnB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,cAAc;IAQtB,oEAAoE;IACpE,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,gBAAgB;IAWxB,OAAO,CAAC,oBAAoB;IAuC5B,4EAA4E;IAC5E,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,mBAAmB;IAkC3B,OAAO,CAAC,kBAAkB;IAoC1B,OAAO,CAAC,YAAY;IAyDpB,OAAO,CAAC,kBAAkB;CA2B1B"}
|
package/dist/plugins/toolbar.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as t}from"../chunks/LocaleService-B6Z-wyAF.mjs";import{b as e}from"../chunks/Platform-CU6itXZo.mjs";import{S as o}from"../chunks/Plugin-OzM8Oxm_.mjs";import{f as n,n as r,a as i}from"../chunks/KeyboardNav-DsYhKKuV.mjs";import{P as l,a as s}from"../chunks/PopupManager-BM8IT6M7.mjs";import{s as a,a as c}from"../chunks/StyleRuntime-BmsLoEa8.mjs";import{a as d}from"../chunks/PopupPositioning-DtvqMSop.mjs";class p{_toolbarItems=/* @__PURE__ */new Map;_toolbarItemPluginMap=/* @__PURE__ */new Map;registerToolbarItem(t,e){if(this._toolbarItems.has(t.id))throw new Error(`ToolbarItem with id "${t.id}" is already registered.`);if(this._toolbarItems.set(t.id,t),e){const o=this._toolbarItemPluginMap.get(e)??[];o.push(t.id),this._toolbarItemPluginMap.set(e,o)}}getToolbarItemsByPlugin(t){const e=this._toolbarItemPluginMap.get(t)??[],o=[];for(const n of e){const t=this._toolbarItems.get(n);t&&o.push(t)}return o}getToolbarItem(t){return this._toolbarItems.get(t)}getToolbarItems(){return[...this._toolbarItems.values()]}removeToolbarItem(t){this._toolbarItems.delete(t);for(const[e,o]of this._toolbarItemPluginMap){const n=o.indexOf(t);if(-1!==n){o.splice(n,1),0===o.length&&this._toolbarItemPluginMap.delete(e);break}}}clear(){this._toolbarItems.clear(),this._toolbarItemPluginMap.clear()}}function u(t){for(let e=0;e<t.length;e++)if(!t[e]?.disabled)return e;return-1}const h={formattingOptionsAria:"Formatting options",moreToolsAria:"More tools",gridPickerLabel:(t,e)=>`${t} x ${e}`},b=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("../chunks/ar-D7PS3e2g.mjs"),"./locales/de.ts":()=>import("../chunks/de-BZWSyJTG.mjs"),"./locales/es.ts":()=>import("../chunks/es-Co4AJr8Y.mjs"),"./locales/fr.ts":()=>import("../chunks/fr-CEkk4UyZ.mjs"),"./locales/hi.ts":()=>import("../chunks/hi-CPuhj7IA.mjs"),"./locales/pt.ts":()=>import("../chunks/pt-CQRzEocL.mjs"),"./locales/ru.ts":()=>import("../chunks/ru-ClEM6OKY.mjs"),"./locales/zh.ts":()=>import("../chunks/zh-DCQZ6gss.mjs")});async function m(t){if("en"===t)return h;const e=b[`./locales/${t}.ts`];if(!e)return h;try{return(await e()).default}catch{return h}}const f={BurgerMenu:"burger-menu",Flow:"flow",None:"none"},v="notectl-toolbar-btn--overflow-hidden",g="notectl-toolbar-separator--overflow-hidden";class w{toolbar;context;onOverflowChange;onItemActivated;getActiveElement;ariaLabel;popupManager;entries=[];overflowButton=null;overflowDropdown=null;overflowHandle=null;overflowEntries=[];resizeObserver=null;closeHandler=null;constructor(t){this.toolbar=t.toolbar,this.ariaLabel=t.ariaLabel,this.context=t.context,this.onOverflowChange=t.onOverflowChange,this.onItemActivated=t.onItemActivated,this.getActiveElement=t.getActiveElement,this.popupManager=t.popupManager??null,this.resizeObserver=new ResizeObserver(()=>this.recalculate()),this.resizeObserver.observe(this.toolbar)}update(t){this.entries=t.map(t=>({element:t.element,item:t.item})),this.recalculate()}recalculate(){if(0===this.entries.length)return;this.closeDropdown(),this.resetVisibility(),this.ensureOverflowButton(),this.setOverflowButtonVisible(!1);const t=this.measureAvailableWidth(),e=Array.from(this.toolbar.children),o=this.measureChildWidths(e),n=t-34-2;let r=0,i=!1;const l=[];for(const s of e){if(s===this.overflowButton)continue;if(s.classList.contains("notectl-toolbar-separator")){if(i){s.classList.add(g);continue}const t=(o.get(s)??0)+2;r+t>n?(i=!0,s.classList.add(g)):r+=t;continue}const t=this.entries.find(t=>t.element===s);if(!t)continue;if(i){t.element.classList.add(v),l.push(t);continue}const e=(o.get(s)??0)+2;r+e>n?(i=!0,t.element.classList.add(v),l.push(t)):r+=e}this.overflowEntries=l,this.hideTrailingSeparators(),this.setOverflowButtonVisible(l.length>0),this.notifyChange()}updateItemStates(t){if(!this.overflowDropdown)return;const e=Array.from(this.overflowDropdown.querySelectorAll(".notectl-dropdown__item"));for(const o of e){const e=o.getAttribute("data-toolbar-item"),n=this.overflowEntries.find(t=>t.item.id===e);if(!n)continue;const r=n.item.isActive?.(t)??!1,i=n.item.isEnabled?.(t)??!0;if(o.classList.toggle("notectl-dropdown__item--active",r),o.disabled=!i,"combobox"===n.item.popupType){const e=o.querySelector(".notectl-dropdown__item-label");e&&(e.textContent=n.item.getLabel(t))}if(n.item.getIcon){const e=n.item.getIcon(t),r=o.querySelector(".notectl-dropdown__item-icon");r&&r.innerHTML!==e&&(r.innerHTML=e)}}}destroy(){this.resizeObserver?.disconnect(),this.resizeObserver=null,this.closeDropdown(),this.overflowButton?.remove(),this.overflowButton=null,this.entries=[],this.overflowEntries=[]}measureChildWidths(t){const e=/* @__PURE__ */new Map;for(const o of t)o!==this.overflowButton&&e.set(o,o.offsetWidth);return e}measureAvailableWidth(){const t=getComputedStyle(this.toolbar),e=Number.parseFloat(t.paddingLeft)||0,o=Number.parseFloat(t.paddingRight)||0;return this.toolbar.clientWidth-e-o}resetVisibility(){for(const e of this.entries)e.element.classList.remove(v);const t=Array.from(this.toolbar.querySelectorAll(".notectl-toolbar-separator"));for(const e of t)e.classList.remove(g)}setOverflowButtonVisible(t){this.overflowButton&&(this.overflowButton.classList.toggle("notectl-toolbar-overflow-btn--hidden",!t),t||this.overflowButton.removeAttribute("tabindex"))}ensureOverflowButton(){if(this.overflowButton)return;const t=document.createElement("button");t.type="button",t.className="notectl-toolbar-overflow-btn",t.setAttribute("aria-label",this.ariaLabel),t.setAttribute("aria-haspopup","true"),t.setAttribute("aria-expanded","false"),t.innerHTML='<svg viewBox="0 0 16 16" width="16" height="16"><circle cx="3" cy="8" r="1.5" fill="currentColor"/><circle cx="8" cy="8" r="1.5" fill="currentColor"/><circle cx="13" cy="8" r="1.5" fill="currentColor"/></svg>',t.addEventListener("mousedown",t=>{t.preventDefault(),this.toggleDropdown()}),this.toolbar.appendChild(t),this.overflowButton=t}toggleDropdown(){this.overflowDropdown?this.closeDropdown():this.openDropdown()}openDropdown(){if(!this.overflowButton||0===this.overflowEntries.length)return;const t=document.createElement("div");t.className="notectl-toolbar-popup notectl-dropdown",t.setAttribute("role","menu"),this.renderDropdownItems(t,this.context.getState()),this.popupManager?(this.overflowHandle=this.popupManager.open({anchor:this.overflowButton,className:"notectl-toolbar-popup notectl-dropdown",ariaRole:"menu",position:"below-end",referenceNode:this.overflowButton,restoreFocusTo:this.overflowButton,onClose:()=>{this.overflowHandle=null,this.overflowDropdown=null,this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false")},content:t=>{this.renderDropdownItems(t,this.context.getState()),this.overflowDropdown=t,t.addEventListener("keydown",t=>this.handleDropdownKeydown(t))}}),this.overflowButton.setAttribute("aria-expanded","true")):(this.positionDropdown(t),d(t,this.overflowButton),this.overflowDropdown=t,this.overflowButton.setAttribute("aria-expanded","true"),requestAnimationFrame(()=>{const e=t.querySelector('[role="menuitem"]');e?.focus()}),t.addEventListener("keydown",t=>this.handleDropdownKeydown(t)),this.registerCloseHandler())}renderDropdownItems(t,e){let o=null;for(const n of this.overflowEntries){if(null!==o&&n.item.group!==o){const e=document.createElement("div");e.className="notectl-dropdown__separator",e.setAttribute("role","separator"),t.appendChild(e)}o=n.item.group;const r=document.createElement("button");r.type="button",r.className="notectl-dropdown__item",r.setAttribute("role","menuitem"),r.setAttribute("tabindex","-1"),r.setAttribute("data-toolbar-item",n.item.id);const i=document.createElement("span");i.className="notectl-dropdown__item-icon","combobox"!==n.item.popupType&&(i.innerHTML=n.item.icon),r.appendChild(i);const l=document.createElement("span");l.className="notectl-dropdown__item-label",l.textContent="combobox"===n.item.popupType?n.item.getLabel(e):n.item.tooltip??n.item.label,r.appendChild(l),r.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),this.activateOverflowItem(n)}),t.appendChild(r)}}positionDropdown(t){if(!this.overflowButton)return;const o=this.overflowButton.getBoundingClientRect();if(e(this.toolbar))a(t,{position:"fixed",top:`${o.bottom+2}px`,left:`${o.left}px`,right:"auto",zIndex:"10000"});else{const e=window.innerWidth-o.right;a(t,{position:"fixed",top:`${o.bottom+2}px`,right:`${e}px`,left:"auto",zIndex:"10000"})}}registerCloseHandler(){this.closeHandler=t=>{const e=t.composedPath();this.overflowDropdown&&!e.includes(this.overflowDropdown)&&this.overflowButton&&!e.includes(this.overflowButton)&&this.closeDropdown()},setTimeout(()=>{this.closeHandler&&document.addEventListener("mousedown",this.closeHandler)},0)}closeDropdown(){if(this.overflowHandle){const t=this.overflowHandle;return this.overflowHandle=null,this.overflowDropdown=null,t.close(),void(this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false"))}this.overflowDropdown&&(this.overflowDropdown.remove(),this.overflowDropdown=null),this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false"),this.closeHandler&&(document.removeEventListener("mousedown",this.closeHandler),this.closeHandler=null)}activateOverflowItem(t){this.closeDropdown(),t.item.popupType&&this.overflowButton?this.onItemActivated(this.overflowButton,t.item):this.context.executeCommand(t.item.command)}handleDropdownKeydown(t){if(!this.overflowDropdown)return;if("Escape"===t.key||"Tab"===t.key)return t.preventDefault(),t.stopPropagation(),this.closeDropdown(),void this.overflowButton?.focus();const e=Array.from(this.overflowDropdown.querySelectorAll('[role="menuitem"]')),o=e.indexOf(this.getActiveElement());switch(t.key){case"ArrowDown":{t.preventDefault();const r=n(e,o,1);e[r]?.focus();break}case"ArrowUp":{t.preventDefault();const r=n(e,o,-1);e[r]?.focus();break}case"Enter":case" ":{t.preventDefault();const n=e[o];if(!n)break;const r=n.getAttribute("data-toolbar-item"),i=this.overflowEntries.find(t=>t.item.id===r);i&&this.activateOverflowItem(i);break}}}hideTrailingSeparators(){const t=Array.from(this.toolbar.children);for(let e=t.length-1;e>=0;e--){const o=t[e];if(o&&o!==this.overflowButton)if(o.classList.contains("notectl-toolbar-separator"))o.classList.contains(g)||o.classList.add(g);else if(!o.classList.contains(v))break}}notifyChange(){const t=this.entries.filter(t=>!t.element.classList.contains(v)).map(t=>t.element);this.onOverflowChange(t,this.overflowEntries.length>0?this.overflowButton:null)}}function x(t,e,o){const n=t.querySelectorAll(".notectl-grid-picker__cell");for(const r of n){const t=Number(r.getAttribute("data-row")),n=Number(r.getAttribute("data-col"));r.classList.toggle("notectl-grid-picker__cell--highlighted",t<=e&&n<=o)}}function y(){const t=document.createElement("span");return t.className="notectl-toolbar-separator",t.setAttribute("role","separator"),t}class E{activePopup=null;activePopupButton=null;activeHandle=null;getActiveElement;locale;popupManager=null;constructor(t,e=h){this.getActiveElement=t,this.locale=e}setPopupManager(t){this.popupManager=t}isOpen(){return null!==this.activePopup}toggle(t,e,o){this.activePopup?this.close():this.openViaManager(t,e,o)}close(){if(this.activeHandle){const t=this.activeHandle;return this.activeHandle=null,this.clearButtonState(),void t.close()}this.clearButtonState(),this.activePopup&&(this.activePopup.remove(),this.activePopup=null)}closeAndRestoreFocus(){const t=this.activePopupButton;this.close(),t?.focus()}destroy(){this.close()}openViaManager(t,e,o){this.popupManager&&(this.activePopupButton=t,t.classList.add("notectl-toolbar-btn--popup-open"),t.setAttribute("aria-expanded","true"),this.activeHandle=this.popupManager.open({anchor:t,className:"notectl-toolbar-popup",referenceNode:t,restoreFocusTo:t,position:"below-start",onClose:()=>{this.activeHandle=null,this.clearButtonState(),this.activePopup=null},content:(t,n)=>{this.activePopup=t,this.renderPopupContent(t,e,o,n),t.addEventListener("keydown",t=>this.handlePopupKeydown(t))}}))}renderPopupContent(t,e,o,n){const r=()=>{n({restoreFocusTo:null}),o.getContainer().focus()};switch(e.popupType){case"gridPicker":!function(t,e,o,n=h){t.className+=" notectl-grid-picker";const r=document.createElement("div");r.className="notectl-grid-picker__grid",r.setAttribute("role","grid"),a(r,{display:"grid",gridTemplateColumns:`repeat(${e.maxCols}, 1fr)`,gap:"2px",padding:"8px"});const i=document.createElement("div");i.className="notectl-grid-picker__label",i.textContent=n.gridPickerLabel(1,1),a(i,{textAlign:"center",padding:"4px",fontSize:"12px"}),i.setAttribute("aria-live","polite");for(let l=1;l<=e.maxRows;l++)for(let t=1;t<=e.maxCols;t++){const s=document.createElement("div");s.className="notectl-grid-picker__cell",s.setAttribute("role","gridcell"),s.setAttribute("tabindex","-1"),s.setAttribute("aria-label",n.gridPickerLabel(l,t)),a(s,{width:"20px",height:"20px",border:"1px solid #ccc",cursor:"pointer"}),s.setAttribute("data-row",String(l)),s.setAttribute("data-col",String(t)),s.addEventListener("mouseenter",()=>{x(r,l,t),i.textContent=n.gridPickerLabel(l,t)}),s.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),s.addEventListener("click",()=>{e.onSelect(l,t),o()}),r.appendChild(s)}t.appendChild(r),t.appendChild(i)}(t,e.popupConfig,r,this.locale);break;case"dropdown":!function(t,e,n,r){t.classList.add("notectl-dropdown"),t.setAttribute("role","menu");for(const i of e.items){const e=document.createElement("button");if(e.type="button",e.className="notectl-dropdown__item",e.setAttribute("role","menuitem"),e.setAttribute("tabindex","-1"),i.icon){const t=document.createElement("span");t.className="notectl-dropdown__item-icon",t.innerHTML=i.icon,e.appendChild(t)}const n=document.createElement("span");n.className="notectl-dropdown__item-label",n.textContent=i.label,e.appendChild(n),e.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),e.addEventListener("click",()=>{var t;t=i.command,o.executeCommand(t),r()}),t.appendChild(e)}}(t,e.popupConfig,0,r);break;case"custom":case"combobox":e.renderPopup(t,o,n)}}clearButtonState(){this.activePopupButton&&(this.activePopupButton.classList.remove("notectl-toolbar-btn--popup-open"),this.activePopupButton.setAttribute("aria-expanded","false"),this.activePopupButton=null)}handlePopupKeydown(t){if(!this.activePopup)return;if("Escape"===t.key)return t.preventDefault(),t.stopPropagation(),void this.closeAndRestoreFocus();if("Tab"===t.key)return t.preventDefault(),void this.closeAndRestoreFocus();const e=this.activePopup.querySelectorAll('[role="menuitem"]');e.length>0?this.handleDropdownKeydown(t,e):null!==this.activePopup.querySelector(".notectl-grid-picker__cell")?this.handleGridKeydown(t):this.handleCustomPopupKeydown(t)}handleDropdownKeydown(t,e){const o=Array.from(e),r=o.indexOf(this.getActiveElement());switch(t.key){case"ArrowDown":{t.preventDefault();const e=n(o,r,1);o[e]?.focus();break}case"ArrowUp":{t.preventDefault();const e=n(o,r,-1);o[e]?.focus();break}case"Enter":case" ":{t.preventDefault();const e=o[r];e&&e.click();break}}}handleGridKeydown(t){const o=this.getActiveElement(),n=Number(o?.getAttribute("data-row")??1),i=Number(o?.getAttribute("data-col")??1),l=this.activePopup?.querySelector(".notectl-grid-picker__grid")??null;if(!l)return;const s=l.querySelector(".notectl-grid-picker__cell:last-child"),a=Number(s?.getAttribute("data-col")??1),c=Number(s?.getAttribute("data-row")??1);if(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(t.key)){t.preventDefault();const[o,s]=r(n,i,c,a,t.key,!!this.activePopup&&e(this.activePopup)),d=l.querySelector(`.notectl-grid-picker__cell[data-row="${o}"][data-col="${s}"]`);d?.focus(),x(l,o,s);const p=this.activePopup?.querySelector(".notectl-grid-picker__label")??null;p&&(p.textContent=this.locale.gridPickerLabel(o,s))}"Enter"!==t.key&&" "!==t.key||(t.preventDefault(),o?.click())}handleCustomPopupKeydown(t){if(!this.activePopup)return;const e=Array.from(this.activePopup.querySelectorAll("button"));if(0===e.length)return;const o=this.getActiveElement(),r=e.indexOf(o);switch(t.key){case"ArrowDown":{t.preventDefault();const o=n(e,r,1);e[o]?.focus();break}case"ArrowUp":{t.preventDefault();const o=n(e,r,-1);e[o]?.focus();break}case"Enter":case" ":t.preventDefault(),o&&o.dispatchEvent(new MouseEvent("mousedown",{bubbles:!0,cancelable:!0}))}}}class A{element;timer=null;target=null;isPopupActive;static TOOLTIP_ID="notectl-toolbar-tooltip";constructor(t){this.isPopupActive=t,this.element=document.createElement("div"),this.element.className="notectl-toolbar-tooltip",this.element.id=A.TOOLTIP_ID,this.element.setAttribute("role","tooltip"),c(this.element,"display","none")}show(t){if(this.hide(),this.isPopupActive()||t.disabled)return;const e=t.getAttribute("data-tooltip");e&&(this.target=t,this.timer=setTimeout(()=>{if(this.isPopupActive())return;this.element.textContent=e,c(this.element,"display","");const o=t.getRootNode();o instanceof ShadowRoot&&!this.element.parentNode?o.appendChild(this.element):o instanceof ShadowRoot||this.element.parentNode||document.body.appendChild(this.element),t.setAttribute("aria-describedby",A.TOOLTIP_ID);const n=t.getBoundingClientRect();a(this.element,{position:"fixed",top:`${n.bottom+6}px`,left:`${n.left+n.width/2}px`,transform:"translateX(-50%)"})},500))}hide(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.target&&(this.target.removeAttribute("aria-describedby"),this.target=null),c(this.element,"display","none")}destroy(){this.hide(),this.element.remove()}}const k=new o("toolbar");class _{id="toolbar";name="Toolbar";priority=10;context=null;toolbarElement=null;buttons=[];hiddenItems=/* @__PURE__ */new Set;layoutConfig;overflowBehavior;focusedIndex=0;tooltip=null;popupController=null;popupManager=null;overflowController=null;visibleElements=[];locale;constructor(t){this.layoutConfig=t??null,this.overflowBehavior=t?.overflow??f.BurgerMenu}async init(e){const o=e.getService(t),n=o?.getLocale()??"en";this.locale="en"===n?h:await m(n),e.registerStyleSheet('\n/* Toolbar */\n.notectl-plugin-container--top {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: nowrap;\n\tborder-bottom: 1px solid var(--notectl-border);\n\tbackground: var(--notectl-toolbar-bg, var(--notectl-surface-raised));\n\tmin-height: 40px;\n}\n\n.notectl-toolbar {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: nowrap;\n\toverflow: hidden;\n\tflex: 1;\n\tmin-width: 0;\n\tgap: 2px;\n\tpadding: 4px 8px;\n}\n\n.notectl-toolbar[hidden] {\n\tdisplay: none;\n}\n\n.notectl-toolbar-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid transparent;\n\tborder-radius: 4px;\n\tbackground: transparent;\n\tcursor: pointer;\n\tcolor: var(--notectl-fg);\n\tfont-size: 14px;\n\tline-height: 1;\n\tpadding: 0;\n\tflex-shrink: 0;\n\ttransition: background 0.1s, border-color 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t\tborder-color: var(--notectl-border);\n\t}\n}\n\n.notectl-toolbar-btn--active {\n\tbackground: var(--notectl-active-bg);\n\tborder-color: var(--notectl-primary-muted);\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-toolbar-btn:focus-visible {\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n\toutline: none;\n}\n\n.notectl-toolbar-btn:disabled {\n\topacity: 0.4;\n\tcursor: not-allowed;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn:disabled:hover {\n\t\tbackground: transparent;\n\t\tborder-color: transparent;\n\t}\n}\n\n.notectl-toolbar-btn__icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpointer-events: none;\n}\n\n.notectl-toolbar-btn__icon svg {\n\tdisplay: block;\n\twidth: 18px;\n\theight: 18px;\n\tfill: currentColor;\n}\n\n/* Tooltip (rendered as fixed-position element in shadow root) */\n.notectl-toolbar-tooltip {\n\tposition: fixed;\n\tpadding: 4px 8px;\n\tborder-radius: 4px;\n\tbackground: var(--notectl-tooltip-bg);\n\tcolor: var(--notectl-tooltip-fg);\n\tfont-size: 11px;\n\tfont-weight: 500;\n\twhite-space: nowrap;\n\tpointer-events: none;\n\tz-index: 10001;\n\tline-height: 1.4;\n\tletter-spacing: 0.01em;\n\tfont-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;\n}\n\n.notectl-toolbar-separator {\n\tdisplay: inline-block;\n\twidth: 1px;\n\theight: 20px;\n\tbackground: var(--notectl-border);\n\tmargin: 0 4px;\n\tvertical-align: middle;\n}\n\n/* Toolbar Popups */\n.notectl-toolbar-popup {\n\tbackground: var(--notectl-surface-overlay);\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 6px;\n\tbox-shadow: 0 4px 12px var(--notectl-shadow);\n\toverflow: hidden;\n}\n\n/* Grid Picker */\n.notectl-grid-picker__cell:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n\n.notectl-grid-picker__cell--highlighted {\n\tbackground: var(--notectl-primary-muted);\n\tborder-color: var(--notectl-primary);\n}\n\n/* Dropdown */\n.notectl-dropdown {\n\tmin-width: 160px;\n\tpadding: 4px 0;\n}\n\n.notectl-dropdown__item {\n\tdisplay: flex;\n\talign-items: center;\n\twidth: 100%;\n\tpadding: 8px 12px;\n\ttext-align: start;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: var(--notectl-fg);\n\tline-height: 1.4;\n\tfont-family: inherit;\n\twhite-space: nowrap;\n}\n\n@media (hover: hover) {\n\t.notectl-dropdown__item:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-dropdown__item:focus-visible {\n\tbackground: var(--notectl-hover-bg);\n\toutline: none;\n}\n\n.notectl-dropdown__item-icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\tfont-weight: 600;\n\tcolor: var(--notectl-fg-muted);\n\tflex-shrink: 0;\n}\n\n.notectl-dropdown__item-label {\n\tflex: 1;\n}\n\n/* Overflow behavior: flow mode — toolbar wraps to additional rows */\n.notectl-toolbar[data-overflow="flow"] {\n\tflex-wrap: wrap;\n\toverflow: visible;\n}\n\n/* Overflow behavior: none — toolbar clips without any responsive behavior */\n.notectl-toolbar[data-overflow="none"] {\n\tflex-wrap: nowrap;\n\toverflow: hidden;\n}\n\n/* Overflow: hidden items (burger-menu mode) */\n.notectl-toolbar-btn--overflow-hidden,\n.notectl-toolbar-separator--overflow-hidden {\n\tdisplay: none;\n}\n\n/* Overflow "more" button */\n.notectl-toolbar-overflow-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid transparent;\n\tborder-radius: 4px;\n\tbackground: transparent;\n\tcursor: pointer;\n\tcolor: var(--notectl-fg);\n\tfont-size: 16px;\n\tline-height: 1;\n\tpadding: 0;\n\tflex-shrink: 0;\n\tmargin-inline-start: auto;\n\ttransition: background 0.1s, border-color 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-overflow-btn:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t\tborder-color: var(--notectl-border);\n\t}\n}\n\n.notectl-toolbar-overflow-btn--hidden {\n\tdisplay: none;\n}\n\n.notectl-toolbar-overflow-btn:focus-visible {\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n\toutline: none;\n}\n\n/* Dropdown item states shared by all dropdown menus (including overflow) */\n.notectl-dropdown__item:disabled {\n\topacity: 0.4;\n\tcursor: not-allowed;\n}\n\n@media (hover: hover) {\n\t.notectl-dropdown__item:disabled:hover {\n\t\tbackground: none;\n\t}\n}\n\n.notectl-dropdown__item--active {\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-dropdown__item-icon svg {\n\tdisplay: block;\n\twidth: 16px;\n\theight: 16px;\n\tfill: currentColor;\n}\n\n.notectl-dropdown__separator {\n\theight: 1px;\n\tbackground: var(--notectl-border);\n\tmargin: 4px 0;\n}\n\n/* Combobox-style toolbar buttons (shared base for font, fontSize, heading, etc.) */\n.notectl-toolbar-btn[role="combobox"] {\n\twidth: auto;\n\tpadding: 0 8px;\n\tgap: 4px;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-bg);\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn[role="combobox"]:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t\tborder-color: var(--notectl-fg-muted);\n\t}\n}\n\n.notectl-toolbar-btn[role="combobox"].notectl-toolbar-btn--active {\n\tbackground: var(--notectl-bg);\n\tborder-color: var(--notectl-primary-muted);\n}\n\n.notectl-toolbar-combobox__label {\n\tflex: 1;\n\tfont-size: 13px;\n\tfont-weight: 500;\n\tcolor: var(--notectl-fg);\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\ttext-align: start;\n\tline-height: 30px;\n}\n\n.notectl-toolbar-combobox__arrow {\n\tflex-shrink: 0;\n\tfont-size: 11px;\n\tcolor: var(--notectl-fg-muted);\n\tline-height: 30px;\n}\n\n/* Link Popup */\n.notectl-link-popup {\n\tpadding: 8px;\n\tmin-width: 200px;\n}\n\n.notectl-link-popup__input {\n\twidth: 100%;\n\tpadding: 4px;\n\tbox-sizing: border-box;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tfont-size: 13px;\n\tcolor: var(--notectl-fg);\n\tbackground: var(--notectl-bg);\n}\n\n.notectl-link-popup__input:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n\n.notectl-link-popup__button {\n\twidth: 100%;\n\tpadding: 6px 12px;\n\tcursor: pointer;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-bg);\n\tcolor: var(--notectl-fg);\n\tfont-size: 13px;\n}\n\n.notectl-link-popup__button--apply {\n\tmargin-top: 4px;\n}\n\n@media (hover: hover) {\n\t.notectl-link-popup__button:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-link-popup__button:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n'),this.context=e,this.popupManager=new l(e.getContainer()),e.registerService(s,this.popupManager),this.popupController=new E(()=>this.getActiveElement(),this.locale),this.popupController.setPopupManager(this.popupManager),this.tooltip=new A(()=>this.popupController?.isOpen()??!1),e.registerService(k,{refresh:()=>this.updateButtonStates(e.getState()),closePopup:()=>this.popupController?.close()}),this.createToolbarElement()}getOverflowBehavior(){return this.overflowBehavior}setOverflowBehavior(t){t!==this.overflowBehavior&&(this.overflowBehavior=t,this.applyOverflowBehavior(),this.renderItems())}onReady(){this.renderItems()}destroy(){this.overflowController?.destroy(),this.overflowController=null,this.popupController?.destroy(),this.popupController=null,this.popupManager?.destroy(),this.popupManager=null,this.tooltip?.destroy(),this.tooltip=null,this.toolbarElement&&(this.toolbarElement.remove(),this.toolbarElement=null),this.buttons=[],this.visibleElements=[],this.context=null}onStateChange(t,e,o){this.updateButtonStates(e)}onReadOnlyChange(t){this.toolbarElement&&(this.toolbarElement.hidden=t)}onConfigure(t){for(const[e,o]of Object.entries(t))!1===o?this.hiddenItems.add(e):this.hiddenItems.delete(e);this.renderItems()}createToolbarElement(){if(!this.context)return;this.toolbarElement&&this.toolbarElement.remove(),this.buttons=[];const t=this.context.getPluginContainer("top");this.toolbarElement=document.createElement("div"),this.toolbarElement.setAttribute("role","toolbar"),this.toolbarElement.setAttribute("aria-label",this.locale.formattingOptionsAria),this.toolbarElement.setAttribute("data-notectl-no-print",""),this.toolbarElement.className="notectl-toolbar",this.toolbarElement.addEventListener("keydown",t=>this.handleToolbarKeydown(t)),this.applyOverflowBehavior(),t.appendChild(this.toolbarElement)}applyOverflowBehavior(){this.toolbarElement&&this.context&&(this.overflowController?.destroy(),this.overflowController=null,this.toolbarElement.setAttribute("data-overflow",this.overflowBehavior),this.overflowBehavior===f.BurgerMenu?this.overflowController=new w({toolbar:this.toolbarElement,ariaLabel:this.locale.moreToolsAria,context:this.context,popupManager:this.popupManager??void 0,onOverflowChange:(t,e)=>{this.visibleElements=e?[...t,e]:[...t],this.initRovingTabindex()},onItemActivated:(t,e)=>{this.activateButton(t,e)},getActiveElement:()=>this.getActiveElement()}):this.visibleElements=[])}renderItems(){if(this.context&&this.toolbarElement){for(const t of this.buttons)t.element.remove();this.buttons=[];for(const t of this.toolbarElement.querySelectorAll(".notectl-toolbar-separator"))t.remove();this.layoutConfig?this.renderItemsByLayout():this.renderItemsByGroup(),this.buttons.length>0&&!this.toolbarElement.parentElement&&this.context.getPluginContainer("top").appendChild(this.toolbarElement),this.overflowController?.update(this.buttons),this.initRovingTabindex(),this.updateButtonStates(this.context.getState())}}getTabElements(){return this.visibleElements.length>0?this.visibleElements:this.buttons.map(t=>t.element)}initRovingTabindex(){const t=this.getTabElements(),e=u(t);this.focusedIndex=e>=0?e:0,i(t,this.focusedIndex)}setRovingFocus(t){const e=this.getTabElements();t<0||t>=e.length||(this.focusedIndex=t,i(e,t),e[t]?.focus())}getActiveElement(){const t=this.toolbarElement?.getRootNode();return t instanceof ShadowRoot?t.activeElement:document.activeElement}syncFocusedIndex(){const t=this.getActiveElement(),e=this.getTabElements().findIndex(e=>e===t);e>=0&&(this.focusedIndex=e)}handleToolbarKeydown(t){const o=this.getTabElements();var n;if(0!==o.length)switch(this.syncFocusedIndex(),t.key){case"ArrowRight":case"ArrowLeft":{t.preventDefault();const r=(n=!!this.toolbarElement&&e(this.toolbarElement),"ArrowRight"===t.key?n?-1:1:n?1:-1),i=function(t,e,o){const n=t.length;if(0===n)return-1;let r=e;for(let i=0;i<n;i++)if(r=(r+o+n)%n,!t[r]?.disabled)return r;return e}(o,this.focusedIndex,r);this.setRovingFocus(i);break}case"Home":{t.preventDefault();const e=u(o);e>=0&&this.setRovingFocus(e);break}case"End":{t.preventDefault();const e=function(t){for(let e=t.length-1;e>=0;e--)if(!t[e]?.disabled)return e;return-1}(o);e>=0&&this.setRovingFocus(e);break}case"Enter":case" ":{t.preventDefault();const e=o[this.focusedIndex],n=this.buttons.find(t=>t.element===e);n&&this.activateButton(n.element,n.item);break}}}activateButton(t,e){this.tooltip?.hide(),e.popupType&&this.context?this.popupController?.toggle(t,e,this.context):this.context?.executeCommand(e.command)}renderItemsByLayout(){if(!this.context||!this.toolbarElement||!this.layoutConfig)return;const t=this.context.getToolbarRegistry();let e=!0;for(const o of this.layoutConfig.groups){const n=[];for(const e of o){const o=t.getToolbarItemsByPlugin(e).filter(t=>!this.hiddenItems.has(t.id));n.push(...o)}if(0!==n.length){e||this.toolbarElement.appendChild(y()),e=!1;for(const t of n){const e=this.createButton(t);this.toolbarElement.appendChild(e.element),this.buttons.push(e)}}}0===this.buttons.length&&this.toolbarElement.remove()}renderItemsByGroup(){if(!this.context||!this.toolbarElement)return;const t=this.context.getToolbarRegistry().getToolbarItems().filter(t=>!this.hiddenItems.has(t.id));if(0===t.length)return void this.toolbarElement.remove();const e=/* @__PURE__ */new Map;for(const n of t){const t=e.get(n.group)??[];t.push(n),e.set(n.group,t)}let o=!0;for(const[,n]of e){o||this.toolbarElement.appendChild(y()),o=!1;for(const t of n){const e=this.createButton(t);this.toolbarElement.appendChild(e.element),this.buttons.push(e)}}}createButton(t){const e=document.createElement("button");e.type="button",e.className=`notectl-toolbar-btn notectl-toolbar-btn--${t.id}`,e.setAttribute("aria-pressed","false"),e.setAttribute("aria-label",t.label),e.setAttribute("data-toolbar-item",t.id),e.setAttribute("data-tooltip",t.tooltip??t.label);let o=null;if("combobox"===t.popupType){e.setAttribute("role","combobox"),e.setAttribute("aria-haspopup","listbox"),e.setAttribute("aria-expanded","false");const n=document.createElement("span");n.className="notectl-toolbar-combobox__label";const r=this.context?.getState();r&&(n.textContent=t.getLabel(r)),e.appendChild(n),o=n;const i=document.createElement("span");i.className="notectl-toolbar-combobox__arrow",i.setAttribute("aria-hidden","true"),i.textContent="▾",e.appendChild(i)}else{t.popupType&&(e.setAttribute("aria-haspopup","true"),e.setAttribute("aria-expanded","false"));const o=document.createElement("span");o.className="notectl-toolbar-btn__icon",o.innerHTML=t.icon,e.appendChild(o)}return e.addEventListener("mousedown",o=>{o.preventDefault(),this.activateButton(e,t)}),e.addEventListener("mouseenter",()=>this.tooltip?.show(e)),e.addEventListener("mouseleave",()=>this.tooltip?.hide()),e.addEventListener("focus",()=>this.tooltip?.show(e)),e.addEventListener("blur",()=>this.tooltip?.hide()),{element:e,item:t,comboLabelEl:o}}updateButtonStates(t){for(const e of this.buttons){const o=e.item.isActive?.(t)??!1,n=e.item.isEnabled?.(t)??!0;if(e.element.setAttribute("aria-pressed",String(o)),e.element.classList.toggle("notectl-toolbar-btn--active",o),e.element.disabled=!n,n?e.element.removeAttribute("aria-disabled"):e.element.setAttribute("aria-disabled","true"),e.comboLabelEl&&"combobox"===e.item.popupType&&(e.comboLabelEl.textContent=e.item.getLabel(t)),e.item.getIcon){const o=e.item.getIcon(t),n=e.element.querySelector(".notectl-toolbar-btn__icon");n&&n.innerHTML!==o&&(n.innerHTML=o)}}this.overflowController?.updateItemStates(t)}}export{h as TOOLBAR_LOCALE_EN,f as ToolbarOverflowBehavior,_ as ToolbarPlugin,p as ToolbarRegistry,k as ToolbarServiceKey,m as loadToolbarLocale};
|
|
1
|
+
import{b as t}from"../chunks/Platform-CU6itXZo.mjs";import{S as e,r as o}from"../chunks/PluginHelpers-CdPR0MuT.mjs";import{f as n,n as r,a as i}from"../chunks/KeyboardNav-DsYhKKuV.mjs";import{P as l,a as s}from"../chunks/PopupManager-0b_Q0m7K.mjs";import{s as a,a as c}from"../chunks/StyleRuntime-BmsLoEa8.mjs";import{a as d}from"../chunks/PopupPositioning-DtvqMSop.mjs";class p{_toolbarItems=/* @__PURE__ */new Map;_toolbarItemPluginMap=/* @__PURE__ */new Map;registerToolbarItem(t,e){if(this._toolbarItems.has(t.id))throw new Error(`ToolbarItem with id "${t.id}" is already registered.`);if(this._toolbarItems.set(t.id,t),e){const o=this._toolbarItemPluginMap.get(e)??[];o.push(t.id),this._toolbarItemPluginMap.set(e,o)}}getToolbarItemsByPlugin(t){const e=this._toolbarItemPluginMap.get(t)??[],o=[];for(const n of e){const t=this._toolbarItems.get(n);t&&o.push(t)}return o}getToolbarItem(t){return this._toolbarItems.get(t)}getToolbarItems(){return[...this._toolbarItems.values()]}removeToolbarItem(t){this._toolbarItems.delete(t);for(const[e,o]of this._toolbarItemPluginMap){const n=o.indexOf(t);if(-1!==n){o.splice(n,1),0===o.length&&this._toolbarItemPluginMap.delete(e);break}}}clear(){this._toolbarItems.clear(),this._toolbarItemPluginMap.clear()}}function u(t){for(let e=0;e<t.length;e++)if(!t[e]?.disabled)return e;return-1}const h={formattingOptionsAria:"Formatting options",moreToolsAria:"More tools",gridPickerLabel:(t,e)=>`${t} x ${e}`},b=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("../chunks/ar-D7PS3e2g.mjs"),"./locales/de.ts":()=>import("../chunks/de-BZWSyJTG.mjs"),"./locales/es.ts":()=>import("../chunks/es-Co4AJr8Y.mjs"),"./locales/fr.ts":()=>import("../chunks/fr-CEkk4UyZ.mjs"),"./locales/hi.ts":()=>import("../chunks/hi-CPuhj7IA.mjs"),"./locales/pt.ts":()=>import("../chunks/pt-CQRzEocL.mjs"),"./locales/ru.ts":()=>import("../chunks/ru-ClEM6OKY.mjs"),"./locales/zh.ts":()=>import("../chunks/zh-DCQZ6gss.mjs")});async function m(t){if("en"===t)return h;const e=b[`./locales/${t}.ts`];if(!e)return h;try{return(await e()).default}catch{return h}}const f={BurgerMenu:"burger-menu",Flow:"flow",None:"none"},v="notectl-toolbar-btn--overflow-hidden",g="notectl-toolbar-separator--overflow-hidden";class w{toolbar;context;onOverflowChange;onItemActivated;getActiveElement;ariaLabel;popupManager;entries=[];overflowButton=null;overflowDropdown=null;overflowHandle=null;overflowEntries=[];resizeObserver=null;closeHandler=null;closeHandlerTimer=null;closeHandlerAttached=!1;constructor(t){this.toolbar=t.toolbar,this.ariaLabel=t.ariaLabel,this.context=t.context,this.onOverflowChange=t.onOverflowChange,this.onItemActivated=t.onItemActivated,this.getActiveElement=t.getActiveElement,this.popupManager=t.popupManager??null,this.resizeObserver=new ResizeObserver(()=>this.recalculate()),this.resizeObserver.observe(this.toolbar)}update(t){this.entries=t.map(t=>({element:t.element,item:t.item})),this.recalculate()}recalculate(){if(0===this.entries.length)return;this.closeDropdown(),this.resetVisibility(),this.ensureOverflowButton(),this.setOverflowButtonVisible(!1);const t=this.measureAvailableWidth(),e=Array.from(this.toolbar.children),o=this.measureChildWidths(e),n=t-34-2;let r=0,i=!1;const l=[];for(const s of e){if(s===this.overflowButton)continue;if(s.classList.contains("notectl-toolbar-separator")){if(i){s.classList.add(g);continue}const t=(o.get(s)??0)+2;r+t>n?(i=!0,s.classList.add(g)):r+=t;continue}const t=this.entries.find(t=>t.element===s);if(!t)continue;if(i){t.element.classList.add(v),l.push(t);continue}const e=(o.get(s)??0)+2;r+e>n?(i=!0,t.element.classList.add(v),l.push(t)):r+=e}this.overflowEntries=l,this.hideTrailingSeparators(),this.setOverflowButtonVisible(l.length>0),this.notifyChange()}updateItemStates(t){if(!this.overflowDropdown)return;const e=Array.from(this.overflowDropdown.querySelectorAll(".notectl-dropdown__item"));for(const o of e){const e=o.getAttribute("data-toolbar-item"),n=this.overflowEntries.find(t=>t.item.id===e);if(!n)continue;const r=n.item.isActive?.(t)??!1,i=n.item.isEnabled?.(t)??!0;if(o.classList.toggle("notectl-dropdown__item--active",r),o.disabled=!i,"combobox"===n.item.popupType){const e=o.querySelector(".notectl-dropdown__item-label");e&&(e.textContent=n.item.getLabel(t))}if(n.item.getIcon){const e=n.item.getIcon(t),r=o.querySelector(".notectl-dropdown__item-icon");r&&r.innerHTML!==e&&(r.innerHTML=e)}}}destroy(){this.resizeObserver?.disconnect(),this.resizeObserver=null,this.closeDropdown(),this.overflowButton?.remove(),this.overflowButton=null,this.entries=[],this.overflowEntries=[]}measureChildWidths(t){const e=/* @__PURE__ */new Map;for(const o of t)o!==this.overflowButton&&e.set(o,o.offsetWidth);return e}measureAvailableWidth(){const t=getComputedStyle(this.toolbar),e=Number.parseFloat(t.paddingLeft)||0,o=Number.parseFloat(t.paddingRight)||0;return this.toolbar.clientWidth-e-o}resetVisibility(){for(const e of this.entries)e.element.classList.remove(v);const t=Array.from(this.toolbar.querySelectorAll(".notectl-toolbar-separator"));for(const e of t)e.classList.remove(g)}setOverflowButtonVisible(t){this.overflowButton&&(this.overflowButton.classList.toggle("notectl-toolbar-overflow-btn--hidden",!t),t||this.overflowButton.removeAttribute("tabindex"))}ensureOverflowButton(){if(this.overflowButton)return;const t=document.createElement("button");t.type="button",t.className="notectl-toolbar-overflow-btn",t.setAttribute("aria-label",this.ariaLabel),t.setAttribute("aria-haspopup","true"),t.setAttribute("aria-expanded","false"),t.innerHTML='<svg viewBox="0 0 16 16" width="16" height="16"><circle cx="3" cy="8" r="1.5" fill="currentColor"/><circle cx="8" cy="8" r="1.5" fill="currentColor"/><circle cx="13" cy="8" r="1.5" fill="currentColor"/></svg>',t.addEventListener("mousedown",t=>{t.preventDefault(),this.toggleDropdown()}),this.toolbar.appendChild(t),this.overflowButton=t}toggleDropdown(){this.overflowDropdown?this.closeDropdown():this.openDropdown()}openDropdown(){if(!this.overflowButton||0===this.overflowEntries.length)return;const t=document.createElement("div");t.className="notectl-toolbar-popup notectl-dropdown",t.setAttribute("role","menu"),this.renderDropdownItems(t,this.context.getState()),this.popupManager?(this.overflowHandle=this.popupManager.open({anchor:this.overflowButton,className:"notectl-toolbar-popup notectl-dropdown",ariaRole:"menu",position:"below-end",referenceNode:this.overflowButton,restoreFocusTo:this.overflowButton,onClose:()=>{this.overflowHandle=null,this.overflowDropdown=null,this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false")},content:t=>{this.renderDropdownItems(t,this.context.getState()),this.overflowDropdown=t,t.addEventListener("keydown",t=>this.handleDropdownKeydown(t))}}),this.overflowButton.setAttribute("aria-expanded","true")):(this.positionDropdown(t),d(t,this.overflowButton),this.overflowDropdown=t,this.overflowButton.setAttribute("aria-expanded","true"),requestAnimationFrame(()=>{const e=t.querySelector('[role="menuitem"]');e?.focus()}),t.addEventListener("keydown",t=>this.handleDropdownKeydown(t)),this.registerCloseHandler())}renderDropdownItems(t,e){let o=null;for(const n of this.overflowEntries){if(null!==o&&n.item.group!==o){const e=document.createElement("div");e.className="notectl-dropdown__separator",e.setAttribute("role","separator"),t.appendChild(e)}o=n.item.group;const r=document.createElement("button");r.type="button",r.className="notectl-dropdown__item",r.setAttribute("role","menuitem"),r.setAttribute("tabindex","-1"),r.setAttribute("data-toolbar-item",n.item.id);const i=document.createElement("span");i.className="notectl-dropdown__item-icon","combobox"!==n.item.popupType&&(i.innerHTML=n.item.icon),r.appendChild(i);const l=document.createElement("span");l.className="notectl-dropdown__item-label",l.textContent="combobox"===n.item.popupType?n.item.getLabel(e):n.item.tooltip??n.item.label,r.appendChild(l),r.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),this.activateOverflowItem(n)}),t.appendChild(r)}}positionDropdown(e){if(!this.overflowButton)return;const o=this.overflowButton.getBoundingClientRect();if(t(this.toolbar))a(e,{position:"fixed",top:`${o.bottom+2}px`,left:`${o.left}px`,right:"auto",zIndex:"10000"});else{const t=window.innerWidth-o.right;a(e,{position:"fixed",top:`${o.bottom+2}px`,right:`${t}px`,left:"auto",zIndex:"10000"})}}registerCloseHandler(){this.closeHandler=t=>{const e=t.composedPath();this.overflowDropdown&&!e.includes(this.overflowDropdown)&&this.overflowButton&&!e.includes(this.overflowButton)&&this.closeDropdown()},this.closeHandlerTimer=setTimeout(()=>{this.closeHandlerTimer=null,this.closeHandler&&this.overflowDropdown&&(document.addEventListener("mousedown",this.closeHandler),this.closeHandlerAttached=!0)},0)}closeDropdown(){if(this.overflowHandle){const t=this.overflowHandle;return this.overflowHandle=null,this.overflowDropdown=null,t.close(),void(this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false"))}this.overflowDropdown&&(this.overflowDropdown.remove(),this.overflowDropdown=null),this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false"),this.closeHandler&&(null!==this.closeHandlerTimer&&(clearTimeout(this.closeHandlerTimer),this.closeHandlerTimer=null),this.closeHandlerAttached&&(document.removeEventListener("mousedown",this.closeHandler),this.closeHandlerAttached=!1),this.closeHandler=null)}activateOverflowItem(t){this.closeDropdown(),t.item.popupType&&this.overflowButton?this.onItemActivated(this.overflowButton,t.item):this.context.executeCommand(t.item.command)}handleDropdownKeydown(t){if(!this.overflowDropdown)return;if("Escape"===t.key||"Tab"===t.key)return t.preventDefault(),t.stopPropagation(),this.closeDropdown(),void this.overflowButton?.focus();const e=Array.from(this.overflowDropdown.querySelectorAll('[role="menuitem"]')),o=e.indexOf(this.getActiveElement());switch(t.key){case"ArrowDown":{t.preventDefault();const r=n(e,o,1);e[r]?.focus();break}case"ArrowUp":{t.preventDefault();const r=n(e,o,-1);e[r]?.focus();break}case"Enter":case" ":{t.preventDefault();const n=e[o];if(!n)break;const r=n.getAttribute("data-toolbar-item"),i=this.overflowEntries.find(t=>t.item.id===r);i&&this.activateOverflowItem(i);break}}}hideTrailingSeparators(){const t=Array.from(this.toolbar.children);for(let e=t.length-1;e>=0;e--){const o=t[e];if(o&&o!==this.overflowButton)if(o.classList.contains("notectl-toolbar-separator"))o.classList.contains(g)||o.classList.add(g);else if(!o.classList.contains(v))break}}notifyChange(){const t=this.entries.filter(t=>!t.element.classList.contains(v)).map(t=>t.element);this.onOverflowChange(t,this.overflowEntries.length>0?this.overflowButton:null)}}function x(t,e,o){const n=t.querySelectorAll(".notectl-grid-picker__cell");for(const r of n){const t=Number(r.getAttribute("data-row")),n=Number(r.getAttribute("data-col"));r.classList.toggle("notectl-grid-picker__cell--highlighted",t<=e&&n<=o)}}function y(){const t=document.createElement("span");return t.className="notectl-toolbar-separator",t.setAttribute("role","separator"),t}class E{activePopup=null;activePopupButton=null;activeHandle=null;getActiveElement;locale;popupManager=null;constructor(t,e=h){this.getActiveElement=t,this.locale=e}setPopupManager(t){this.popupManager=t}isOpen(){return null!==this.activePopup}toggle(t,e,o){this.activePopup?this.close():this.openViaManager(t,e,o)}close(){if(this.activeHandle){const t=this.activeHandle;return this.activeHandle=null,this.clearButtonState(),void t.close()}this.clearButtonState(),this.activePopup&&(this.activePopup.remove(),this.activePopup=null)}closeAndRestoreFocus(){const t=this.activePopupButton;this.close(),t?.focus()}destroy(){this.close()}openViaManager(t,e,o){this.popupManager&&(this.activePopupButton=t,t.classList.add("notectl-toolbar-btn--popup-open"),t.setAttribute("aria-expanded","true"),this.activeHandle=this.popupManager.open({anchor:t,className:"notectl-toolbar-popup",referenceNode:t,restoreFocusTo:t,position:"below-start",onClose:()=>{this.activeHandle=null,this.clearButtonState(),this.activePopup=null},content:(t,n)=>{this.activePopup=t,this.renderPopupContent(t,e,o,n),t.addEventListener("keydown",t=>this.handlePopupKeydown(t))}}))}renderPopupContent(t,e,o,n){const r=()=>{n({restoreFocusTo:null}),o.getContainer().focus()};switch(e.popupType){case"gridPicker":!function(t,e,o,n=h){t.className+=" notectl-grid-picker";const r=document.createElement("div");r.className="notectl-grid-picker__grid",r.setAttribute("role","grid"),a(r,{display:"grid",gridTemplateColumns:`repeat(${e.maxCols}, 1fr)`,gap:"2px",padding:"8px"});const i=document.createElement("div");i.className="notectl-grid-picker__label",i.textContent=n.gridPickerLabel(1,1),a(i,{textAlign:"center",padding:"4px",fontSize:"12px"}),i.setAttribute("aria-live","polite");for(let l=1;l<=e.maxRows;l++)for(let t=1;t<=e.maxCols;t++){const s=document.createElement("div");s.className="notectl-grid-picker__cell",s.setAttribute("role","gridcell"),s.setAttribute("tabindex","-1"),s.setAttribute("aria-label",n.gridPickerLabel(l,t)),a(s,{width:"20px",height:"20px",border:"1px solid #ccc",cursor:"pointer"}),s.setAttribute("data-row",String(l)),s.setAttribute("data-col",String(t)),s.addEventListener("mouseenter",()=>{x(r,l,t),i.textContent=n.gridPickerLabel(l,t)}),s.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),s.addEventListener("click",()=>{e.onSelect(l,t),o()}),r.appendChild(s)}t.appendChild(r),t.appendChild(i)}(t,e.popupConfig,r,this.locale);break;case"dropdown":!function(t,e,n,r){t.classList.add("notectl-dropdown"),t.setAttribute("role","menu");for(const i of e.items){const e=document.createElement("button");if(e.type="button",e.className="notectl-dropdown__item",e.setAttribute("role","menuitem"),e.setAttribute("tabindex","-1"),i.icon){const t=document.createElement("span");t.className="notectl-dropdown__item-icon",t.innerHTML=i.icon,e.appendChild(t)}const n=document.createElement("span");n.className="notectl-dropdown__item-label",n.textContent=i.label,e.appendChild(n),e.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),e.addEventListener("click",()=>{var t;t=i.command,o.executeCommand(t),r()}),t.appendChild(e)}}(t,e.popupConfig,0,r);break;case"custom":case"combobox":e.renderPopup(t,o,n)}}clearButtonState(){this.activePopupButton&&(this.activePopupButton.classList.remove("notectl-toolbar-btn--popup-open"),this.activePopupButton.setAttribute("aria-expanded","false"),this.activePopupButton=null)}handlePopupKeydown(t){if(!this.activePopup)return;if("Escape"===t.key)return t.preventDefault(),t.stopPropagation(),void this.closeAndRestoreFocus();if("Tab"===t.key)return t.preventDefault(),void this.closeAndRestoreFocus();const e=this.activePopup.querySelectorAll('[role="menuitem"]');e.length>0?this.handleDropdownKeydown(t,e):null!==this.activePopup.querySelector(".notectl-grid-picker__cell")?this.handleGridKeydown(t):this.handleCustomPopupKeydown(t)}handleDropdownKeydown(t,e){const o=Array.from(e),r=o.indexOf(this.getActiveElement());switch(t.key){case"ArrowDown":{t.preventDefault();const e=n(o,r,1);o[e]?.focus();break}case"ArrowUp":{t.preventDefault();const e=n(o,r,-1);o[e]?.focus();break}case"Enter":case" ":{t.preventDefault();const e=o[r];e&&e.click();break}}}handleGridKeydown(e){const o=this.getActiveElement(),n=Number(o?.getAttribute("data-row")??1),i=Number(o?.getAttribute("data-col")??1),l=this.activePopup?.querySelector(".notectl-grid-picker__grid")??null;if(!l)return;const s=l.querySelector(".notectl-grid-picker__cell:last-child"),a=Number(s?.getAttribute("data-col")??1),c=Number(s?.getAttribute("data-row")??1);if(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(e.key)){e.preventDefault();const[o,s]=r(n,i,c,a,e.key,!!this.activePopup&&t(this.activePopup)),d=l.querySelector(`.notectl-grid-picker__cell[data-row="${o}"][data-col="${s}"]`);d?.focus(),x(l,o,s);const p=this.activePopup?.querySelector(".notectl-grid-picker__label")??null;p&&(p.textContent=this.locale.gridPickerLabel(o,s))}"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),o?.click())}handleCustomPopupKeydown(t){if(!this.activePopup)return;const e=Array.from(this.activePopup.querySelectorAll("button"));if(0===e.length)return;const o=this.getActiveElement(),r=e.indexOf(o);switch(t.key){case"ArrowDown":{t.preventDefault();const o=n(e,r,1);e[o]?.focus();break}case"ArrowUp":{t.preventDefault();const o=n(e,r,-1);e[o]?.focus();break}case"Enter":case" ":t.preventDefault(),o&&o.dispatchEvent(new MouseEvent("mousedown",{bubbles:!0,cancelable:!0}))}}}class A{element;timer=null;target=null;isPopupActive;static TOOLTIP_ID="notectl-toolbar-tooltip";constructor(t){this.isPopupActive=t,this.element=document.createElement("div"),this.element.className="notectl-toolbar-tooltip",this.element.id=A.TOOLTIP_ID,this.element.setAttribute("role","tooltip"),c(this.element,"display","none")}show(t){if(this.hide(),this.isPopupActive()||t.disabled)return;const e=t.getAttribute("data-tooltip");e&&(this.target=t,this.timer=setTimeout(()=>{if(this.isPopupActive())return;this.element.textContent=e,c(this.element,"display","");const o=t.getRootNode();o instanceof ShadowRoot&&!this.element.parentNode?o.appendChild(this.element):o instanceof ShadowRoot||this.element.parentNode||document.body.appendChild(this.element),t.setAttribute("aria-describedby",A.TOOLTIP_ID);const n=t.getBoundingClientRect();a(this.element,{position:"fixed",top:`${n.bottom+6}px`,left:`${n.left+n.width/2}px`,transform:"translateX(-50%)"})},500))}hide(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.target&&(this.target.removeAttribute("aria-describedby"),this.target=null),c(this.element,"display","none")}destroy(){this.hide(),this.element.remove()}}const k=new e("toolbar");class _{id="toolbar";name="Toolbar";priority=10;context=null;toolbarElement=null;buttons=[];hiddenItems=/* @__PURE__ */new Set;layoutConfig;overflowBehavior;focusedIndex=0;tooltip=null;popupController=null;popupManager=null;overflowController=null;visibleElements=[];locale;constructor(t){this.layoutConfig=t??null,this.overflowBehavior=t?.overflow??f.BurgerMenu}async init(t){this.locale=await o(t,void 0,h,m),t.registerStyleSheet('\n/* Toolbar */\n.notectl-plugin-container--top {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: nowrap;\n\tborder-bottom: 1px solid var(--notectl-border);\n\tbackground: var(--notectl-toolbar-bg, var(--notectl-surface-raised));\n\tmin-height: 40px;\n}\n\n.notectl-toolbar {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: nowrap;\n\toverflow: hidden;\n\tflex: 1;\n\tmin-width: 0;\n\tgap: 2px;\n\tpadding: 4px 8px;\n}\n\n.notectl-toolbar[hidden] {\n\tdisplay: none;\n}\n\n.notectl-toolbar-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid transparent;\n\tborder-radius: 4px;\n\tbackground: transparent;\n\tcursor: pointer;\n\tcolor: var(--notectl-fg);\n\tfont-size: 14px;\n\tline-height: 1;\n\tpadding: 0;\n\tflex-shrink: 0;\n\ttransition: background 0.1s, border-color 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t\tborder-color: var(--notectl-border);\n\t}\n}\n\n.notectl-toolbar-btn--active {\n\tbackground: var(--notectl-active-bg);\n\tborder-color: var(--notectl-primary-muted);\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-toolbar-btn:focus-visible {\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n\toutline: none;\n}\n\n.notectl-toolbar-btn:disabled {\n\topacity: 0.4;\n\tcursor: not-allowed;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn:disabled:hover {\n\t\tbackground: transparent;\n\t\tborder-color: transparent;\n\t}\n}\n\n.notectl-toolbar-btn__icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpointer-events: none;\n}\n\n.notectl-toolbar-btn__icon svg {\n\tdisplay: block;\n\twidth: 18px;\n\theight: 18px;\n\tfill: currentColor;\n}\n\n/* Tooltip (rendered as fixed-position element in shadow root) */\n.notectl-toolbar-tooltip {\n\tposition: fixed;\n\tpadding: 4px 8px;\n\tborder-radius: 4px;\n\tbackground: var(--notectl-tooltip-bg);\n\tcolor: var(--notectl-tooltip-fg);\n\tfont-size: 11px;\n\tfont-weight: 500;\n\twhite-space: nowrap;\n\tpointer-events: none;\n\tz-index: 10001;\n\tline-height: 1.4;\n\tletter-spacing: 0.01em;\n\tfont-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;\n}\n\n.notectl-toolbar-separator {\n\tdisplay: inline-block;\n\twidth: 1px;\n\theight: 20px;\n\tbackground: var(--notectl-border);\n\tmargin: 0 4px;\n\tvertical-align: middle;\n}\n\n/* Toolbar Popups */\n.notectl-toolbar-popup {\n\tbackground: var(--notectl-surface-overlay);\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 6px;\n\tbox-shadow: 0 4px 12px var(--notectl-shadow);\n\toverflow: hidden;\n}\n\n/* Grid Picker */\n.notectl-grid-picker__cell:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n\n.notectl-grid-picker__cell--highlighted {\n\tbackground: var(--notectl-primary-muted);\n\tborder-color: var(--notectl-primary);\n}\n\n/* Dropdown */\n.notectl-dropdown {\n\tmin-width: 160px;\n\tpadding: 4px 0;\n}\n\n.notectl-dropdown__item {\n\tdisplay: flex;\n\talign-items: center;\n\twidth: 100%;\n\tpadding: 8px 12px;\n\ttext-align: start;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: var(--notectl-fg);\n\tline-height: 1.4;\n\tfont-family: inherit;\n\twhite-space: nowrap;\n}\n\n@media (hover: hover) {\n\t.notectl-dropdown__item:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-dropdown__item:focus-visible {\n\tbackground: var(--notectl-hover-bg);\n\toutline: none;\n}\n\n.notectl-dropdown__item-icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\tfont-weight: 600;\n\tcolor: var(--notectl-fg-muted);\n\tflex-shrink: 0;\n}\n\n.notectl-dropdown__item-label {\n\tflex: 1;\n}\n\n/* Overflow behavior: flow mode — toolbar wraps to additional rows */\n.notectl-toolbar[data-overflow="flow"] {\n\tflex-wrap: wrap;\n\toverflow: visible;\n}\n\n/* Overflow behavior: none — toolbar clips without any responsive behavior */\n.notectl-toolbar[data-overflow="none"] {\n\tflex-wrap: nowrap;\n\toverflow: hidden;\n}\n\n/* Overflow: hidden items (burger-menu mode) */\n.notectl-toolbar-btn--overflow-hidden,\n.notectl-toolbar-separator--overflow-hidden {\n\tdisplay: none;\n}\n\n/* Overflow "more" button */\n.notectl-toolbar-overflow-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid transparent;\n\tborder-radius: 4px;\n\tbackground: transparent;\n\tcursor: pointer;\n\tcolor: var(--notectl-fg);\n\tfont-size: 16px;\n\tline-height: 1;\n\tpadding: 0;\n\tflex-shrink: 0;\n\tmargin-inline-start: auto;\n\ttransition: background 0.1s, border-color 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-overflow-btn:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t\tborder-color: var(--notectl-border);\n\t}\n}\n\n.notectl-toolbar-overflow-btn--hidden {\n\tdisplay: none;\n}\n\n.notectl-toolbar-overflow-btn:focus-visible {\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n\toutline: none;\n}\n\n/* Dropdown item states shared by all dropdown menus (including overflow) */\n.notectl-dropdown__item:disabled {\n\topacity: 0.4;\n\tcursor: not-allowed;\n}\n\n@media (hover: hover) {\n\t.notectl-dropdown__item:disabled:hover {\n\t\tbackground: none;\n\t}\n}\n\n.notectl-dropdown__item--active {\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-dropdown__item-icon svg {\n\tdisplay: block;\n\twidth: 16px;\n\theight: 16px;\n\tfill: currentColor;\n}\n\n.notectl-dropdown__separator {\n\theight: 1px;\n\tbackground: var(--notectl-border);\n\tmargin: 4px 0;\n}\n\n/* Combobox-style toolbar buttons (shared base for font, fontSize, heading, etc.) */\n.notectl-toolbar-btn[role="combobox"] {\n\twidth: auto;\n\tpadding: 0 8px;\n\tgap: 4px;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-bg);\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn[role="combobox"]:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t\tborder-color: var(--notectl-fg-muted);\n\t}\n}\n\n.notectl-toolbar-btn[role="combobox"].notectl-toolbar-btn--active {\n\tbackground: var(--notectl-bg);\n\tborder-color: var(--notectl-primary-muted);\n}\n\n.notectl-toolbar-combobox__label {\n\tflex: 1;\n\tfont-size: 13px;\n\tfont-weight: 500;\n\tcolor: var(--notectl-fg);\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\ttext-align: start;\n\tline-height: 30px;\n}\n\n.notectl-toolbar-combobox__arrow {\n\tflex-shrink: 0;\n\tfont-size: 11px;\n\tcolor: var(--notectl-fg-muted);\n\tline-height: 30px;\n}\n\n/* Link Popup */\n.notectl-link-popup {\n\tpadding: 8px;\n\tmin-width: 200px;\n}\n\n.notectl-link-popup__input {\n\twidth: 100%;\n\tpadding: 4px;\n\tbox-sizing: border-box;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tfont-size: 13px;\n\tcolor: var(--notectl-fg);\n\tbackground: var(--notectl-bg);\n}\n\n.notectl-link-popup__input:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n\n.notectl-link-popup__button {\n\twidth: 100%;\n\tpadding: 6px 12px;\n\tcursor: pointer;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-bg);\n\tcolor: var(--notectl-fg);\n\tfont-size: 13px;\n}\n\n.notectl-link-popup__button--apply {\n\tmargin-top: 4px;\n}\n\n@media (hover: hover) {\n\t.notectl-link-popup__button:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-link-popup__button:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n'),this.context=t,this.popupManager=new l(t.getContainer()),t.registerService(s,this.popupManager),this.popupController=new E(()=>this.getActiveElement(),this.locale),this.popupController.setPopupManager(this.popupManager),this.tooltip=new A(()=>this.popupController?.isOpen()??!1),t.registerService(k,{refresh:()=>this.updateButtonStates(t.getState()),closePopup:()=>this.popupController?.close()}),this.createToolbarElement()}getOverflowBehavior(){return this.overflowBehavior}setOverflowBehavior(t){t!==this.overflowBehavior&&(this.overflowBehavior=t,this.applyOverflowBehavior(),this.renderItems())}onReady(){this.renderItems()}destroy(){this.overflowController?.destroy(),this.overflowController=null,this.popupController?.destroy(),this.popupController=null,this.popupManager?.destroy(),this.popupManager=null,this.tooltip?.destroy(),this.tooltip=null,this.toolbarElement&&(this.toolbarElement.remove(),this.toolbarElement=null),this.buttons=[],this.visibleElements=[],this.context=null}onStateChange(t,e,o){this.updateButtonStates(e)}onReadOnlyChange(t){this.toolbarElement&&(this.toolbarElement.hidden=t)}onConfigure(t){for(const[e,o]of Object.entries(t))!1===o?this.hiddenItems.add(e):this.hiddenItems.delete(e);this.renderItems()}createToolbarElement(){if(!this.context)return;this.toolbarElement&&this.toolbarElement.remove(),this.buttons=[];const t=this.context.getPluginContainer("top");this.toolbarElement=document.createElement("div"),this.toolbarElement.setAttribute("role","toolbar"),this.toolbarElement.setAttribute("aria-label",this.locale.formattingOptionsAria),this.toolbarElement.setAttribute("data-notectl-no-print",""),this.toolbarElement.className="notectl-toolbar",this.toolbarElement.addEventListener("keydown",t=>this.handleToolbarKeydown(t)),this.applyOverflowBehavior(),t.appendChild(this.toolbarElement)}applyOverflowBehavior(){this.toolbarElement&&this.context&&(this.overflowController?.destroy(),this.overflowController=null,this.toolbarElement.setAttribute("data-overflow",this.overflowBehavior),this.overflowBehavior===f.BurgerMenu?this.overflowController=new w({toolbar:this.toolbarElement,ariaLabel:this.locale.moreToolsAria,context:this.context,popupManager:this.popupManager??void 0,onOverflowChange:(t,e)=>{this.visibleElements=e?[...t,e]:[...t],this.initRovingTabindex()},onItemActivated:(t,e)=>{this.activateButton(t,e)},getActiveElement:()=>this.getActiveElement()}):this.visibleElements=[])}renderItems(){if(this.context&&this.toolbarElement){for(const t of this.buttons)t.element.remove();this.buttons=[];for(const t of this.toolbarElement.querySelectorAll(".notectl-toolbar-separator"))t.remove();this.layoutConfig?this.renderItemsByLayout():this.renderItemsByGroup(),this.buttons.length>0&&!this.toolbarElement.parentElement&&this.context.getPluginContainer("top").appendChild(this.toolbarElement),this.overflowController?.update(this.buttons),this.initRovingTabindex(),this.updateButtonStates(this.context.getState())}}getTabElements(){return this.visibleElements.length>0?this.visibleElements:this.buttons.map(t=>t.element)}initRovingTabindex(){const t=this.getTabElements(),e=u(t);this.focusedIndex=e>=0?e:0,i(t,this.focusedIndex)}setRovingFocus(t){const e=this.getTabElements();t<0||t>=e.length||(this.focusedIndex=t,i(e,t),e[t]?.focus())}getActiveElement(){const t=this.toolbarElement?.getRootNode();return t instanceof ShadowRoot?t.activeElement:document.activeElement}syncFocusedIndex(){const t=this.getActiveElement(),e=this.getTabElements().findIndex(e=>e===t);e>=0&&(this.focusedIndex=e)}handleToolbarKeydown(e){const o=this.getTabElements();var n;if(0!==o.length)switch(this.syncFocusedIndex(),e.key){case"ArrowRight":case"ArrowLeft":{e.preventDefault();const r=(n=!!this.toolbarElement&&t(this.toolbarElement),"ArrowRight"===e.key?n?-1:1:n?1:-1),i=function(t,e,o){const n=t.length;if(0===n)return-1;let r=e;for(let i=0;i<n;i++)if(r=(r+o+n)%n,!t[r]?.disabled)return r;return e}(o,this.focusedIndex,r);this.setRovingFocus(i);break}case"Home":{e.preventDefault();const t=u(o);t>=0&&this.setRovingFocus(t);break}case"End":{e.preventDefault();const t=function(t){for(let e=t.length-1;e>=0;e--)if(!t[e]?.disabled)return e;return-1}(o);t>=0&&this.setRovingFocus(t);break}case"Enter":case" ":{e.preventDefault();const t=o[this.focusedIndex],n=this.buttons.find(e=>e.element===t);n&&this.activateButton(n.element,n.item);break}}}activateButton(t,e){this.tooltip?.hide(),e.popupType&&this.context?this.popupController?.toggle(t,e,this.context):this.context?.executeCommand(e.command)}renderItemsByLayout(){if(!this.context||!this.toolbarElement||!this.layoutConfig)return;const t=this.context.getToolbarRegistry();let e=!0;for(const o of this.layoutConfig.groups){const n=[];for(const e of o){const o=t.getToolbarItemsByPlugin(e).filter(t=>!this.hiddenItems.has(t.id));n.push(...o)}if(0!==n.length){e||this.toolbarElement.appendChild(y()),e=!1;for(const t of n){const e=this.createButton(t);this.toolbarElement.appendChild(e.element),this.buttons.push(e)}}}0===this.buttons.length&&this.toolbarElement.remove()}renderItemsByGroup(){if(!this.context||!this.toolbarElement)return;const t=this.context.getToolbarRegistry().getToolbarItems().filter(t=>!this.hiddenItems.has(t.id));if(0===t.length)return void this.toolbarElement.remove();const e=/* @__PURE__ */new Map;for(const n of t){const t=e.get(n.group)??[];t.push(n),e.set(n.group,t)}let o=!0;for(const[,n]of e){o||this.toolbarElement.appendChild(y()),o=!1;for(const t of n){const e=this.createButton(t);this.toolbarElement.appendChild(e.element),this.buttons.push(e)}}}createButton(t){const e=document.createElement("button");e.type="button",e.className=`notectl-toolbar-btn notectl-toolbar-btn--${t.id}`,e.setAttribute("aria-pressed","false"),e.setAttribute("aria-label",t.label),e.setAttribute("data-toolbar-item",t.id),e.setAttribute("data-tooltip",t.tooltip??t.label);let o=null;if("combobox"===t.popupType){e.setAttribute("role","combobox"),e.setAttribute("aria-haspopup","listbox"),e.setAttribute("aria-expanded","false");const n=document.createElement("span");n.className="notectl-toolbar-combobox__label";const r=this.context?.getState();r&&(n.textContent=t.getLabel(r)),e.appendChild(n),o=n;const i=document.createElement("span");i.className="notectl-toolbar-combobox__arrow",i.setAttribute("aria-hidden","true"),i.textContent="▾",e.appendChild(i)}else{t.popupType&&(e.setAttribute("aria-haspopup","true"),e.setAttribute("aria-expanded","false"));const o=document.createElement("span");o.className="notectl-toolbar-btn__icon",o.innerHTML=t.icon,e.appendChild(o)}return e.addEventListener("mousedown",o=>{o.preventDefault(),this.activateButton(e,t)}),e.addEventListener("mouseenter",()=>this.tooltip?.show(e)),e.addEventListener("mouseleave",()=>this.tooltip?.hide()),e.addEventListener("focus",()=>this.tooltip?.show(e)),e.addEventListener("blur",()=>this.tooltip?.hide()),{element:e,item:t,comboLabelEl:o}}updateButtonStates(t){for(const e of this.buttons){const o=e.item.isActive?.(t)??!1,n=e.item.isEnabled?.(t)??!0;if(e.element.setAttribute("aria-pressed",String(o)),e.element.classList.toggle("notectl-toolbar-btn--active",o),e.element.disabled=!n,n?e.element.removeAttribute("aria-disabled"):e.element.setAttribute("aria-disabled","true"),e.comboLabelEl&&"combobox"===e.item.popupType&&(e.comboLabelEl.textContent=e.item.getLabel(t)),e.item.getIcon){const o=e.item.getIcon(t),n=e.element.querySelector(".notectl-toolbar-btn__icon");n&&n.innerHTML!==o&&(n.innerHTML=o)}}this.overflowController?.updateItemStates(t)}}export{h as TOOLBAR_LOCALE_EN,f as ToolbarOverflowBehavior,_ as ToolbarPlugin,p as ToolbarRegistry,k as ToolbarServiceKey,m as loadToolbarLocale};
|
|
2
2
|
//# sourceMappingURL=toolbar.mjs.map
|