@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":"TextColorPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-color/TextColorPlugin.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"TextColorPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-color/TextColorPlugin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK1D,OAAO,EAEN,KAAK,eAAe,EAEpB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,QAAQ,6BAA6B,CAAC;IAC5C,UAAU,gBAAgB;QACzB,SAAS,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KAC7B;CACD;AAID,MAAM,WAAW,eAAe;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;CAClC;AAsFD,qBAAa,eAAgB,YAAW,MAAM;IAC7C,QAAQ,CAAC,EAAE,eAAe;IAC1B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,MAAM,CAAmB;gBAErB,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAKvC,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjD,OAAO,CAAC,gBAAgB;IAuCxB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,mBAAmB;CAkC3B"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{C as e}from"../chunks/color-picker-Byjl_xr9.mjs";import{a as t}from"../chunks/
|
|
1
|
+
import{C as e}from"../chunks/color-picker-Byjl_xr9.mjs";import{a as t}from"../chunks/HTMLUtils-Cxy99Ak2.mjs";import{a as o}from"../chunks/StyleRuntime-BmsLoEa8.mjs";import{r,i as s,b as c}from"../chunks/ColorPickerPopup-D6XjShhv.mjs";import{r as a,i as l}from"../chunks/ColorValidation-DCSKq9B2.mjs";import{r as i}from"../chunks/PluginHelpers-CdPR0MuT.mjs";const f={label:"Text Color",tooltip:"Text Color",resetLabel:"Default",ariaLabelPrefix:"Text color"},n=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("../chunks/ar-CL3QL0tw.mjs"),"./locales/de.ts":()=>import("../chunks/de-D1OAXtxJ.mjs"),"./locales/es.ts":()=>import("../chunks/es-CBk43isB.mjs"),"./locales/fr.ts":()=>import("../chunks/fr-gurfH-7T.mjs"),"./locales/hi.ts":()=>import("../chunks/hi-DtlvSQkD.mjs"),"./locales/pt.ts":()=>import("../chunks/pt-C-Vp7Rxj.mjs"),"./locales/ru.ts":()=>import("../chunks/ru-B3O7WXNM.mjs"),"./locales/zh.ts":()=>import("../chunks/zh-BfeWdPIz.mjs")});async function m(e){if("en"===e)return f;const t=n[`./locales/${e}.ts`];if(!t)return f;try{return(await t()).default}catch{return f}}const p=["#000000","#434343","#666666","#999999","#b7b7b7","#cccccc","#d9d9d9","#efefef","#f3f3f3","#ffffff","#980000","#ff0000","#ff9900","#ffff00","#00ff00","#00ffff","#4a86e8","#0000ff","#9900ff","#ff00ff","#e6b8af","#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#c9daf8","#cfe2f3","#d9d2e9","#ead1dc","#dd7e6b","#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#a4c2f4","#9fc5e8","#b4a7d6","#d5a6bd","#cc4125","#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6d9eeb","#6fa8dc","#8e7cc3","#c27ba0","#a61c00","#cc0000","#e69138","#f1c232","#6aa84f","#45818e","#3c78d8","#3d85c6","#674ea7","#a64d79","#85200c","#990000","#b45f06","#bf9000","#38761d","#134f5c","#1155cc","#0b5394","#351c75","#741b47"];class d{id="textColor";name="Text Color";priority=23;config;colors;locale;constructor(e){this.config={...e},this.colors=a(e?.colors,p,"TextColorPlugin")}async init(t){this.locale=await i(t,this.config.locale,f,m),t.registerStyleSheet(e),this.registerMarkSpec(t),this.registerCommands(t),this.registerToolbarItem(t)}registerMarkSpec(e){e.registerMarkSpec({type:"textColor",rank:5,attrs:{color:{default:""}},toDOM(e){const t=document.createElement("span"),r=e.attrs?.color??"";return o(t,"color",r),t},toHTMLString:(e,o,r)=>{const s=String(e.attrs?.color??"");if(!s||!l(s))return o;const c=`color: ${t(s)}`;return`<span${r?.styleAttr(c)??` style="${c}"`}>${o}</span>`},toHTMLStyle:e=>{const o=String(e.attrs?.color??"");return o&&l(o)?`color: ${t(o)}`:null},parseHTML:[{tag:"span",getAttrs:e=>{const t=e.style.color;return!(!t||!l(t))&&{color:t}}}],sanitize:{tags:["span"]}})}registerCommands(e){e.registerCommand("removeTextColor",()=>r(e,e.getState(),"textColor"))}registerToolbarItem(e){const t=['<svg xmlns="http://www.w3.org/2000/svg"',' viewBox="0 0 24 24">','<path d="M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z"/>','<rect x="3" y="19.5" width="18" height="3"',' rx="0.5" fill="#e53935"/>',"</svg>"].join("");e.registerToolbarItem({id:"textColor",group:"format",icon:t,label:this.locale.label,tooltip:this.locale.tooltip,command:"removeTextColor",popupType:"custom",renderPopup:(e,t,o)=>{c(e,t,{markType:"textColor",colors:this.colors,columns:10,resetLabel:this.locale.resetLabel,resetCommand:"removeTextColor",ariaLabelPrefix:this.locale.ariaLabelPrefix,onClose:o})},isActive:e=>s(e,"textColor")})}}export{f as TEXT_COLOR_LOCALE_EN,d as TextColorPlugin,m as loadTextColorLocale};
|
|
2
2
|
//# sourceMappingURL=text-color.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-color.mjs","sources":["../../src/plugins/text-color/TextColorLocale.ts","../../src/plugins/text-color/TextColorPlugin.ts"],"sourcesContent":["/** Locale interface and default English locale for the TextColorPlugin. */\n\n// --- Locale Interface ---\n\nexport interface TextColorLocale {\n\treadonly label: string;\n\treadonly tooltip: string;\n\treadonly resetLabel: string;\n\treadonly ariaLabelPrefix: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_COLOR_LOCALE_EN: TextColorLocale = {\n\tlabel: 'Text Color',\n\ttooltip: 'Text Color',\n\tresetLabel: 'Default',\n\tariaLabelPrefix: 'Text color',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: Record<string, () => Promise<{ default: TextColorLocale }>> =\n\timport.meta.glob<{ default: TextColorLocale }>('./locales/*.ts', { eager: false });\n\nexport async function loadTextColorLocale(lang: string): Promise<TextColorLocale> {\n\tif (lang === 'en') return TEXT_COLOR_LOCALE_EN;\n\tconst loader = localeModules[`./locales/${lang}.ts`];\n\tif (!loader) return TEXT_COLOR_LOCALE_EN;\n\ttry {\n\t\tconst mod = await loader();\n\t\treturn mod.default;\n\t} catch {\n\t\treturn TEXT_COLOR_LOCALE_EN;\n\t}\n}\n","/**\n * TextColorPlugin: registers a text color mark with attrs,\n * toolbar button with a color picker popup, and removeTextColor command.\n */\n\nimport { COLOR_PICKER_CSS } from '../../editor/styles/color-picker.js';\nimport { LocaleServiceKey } from '../../i18n/LocaleService.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport type { HTMLExportContext } from '../../model/NodeSpec.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport { setStyleProperty } from '../../style/StyleRuntime.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { isColorMarkActive, removeColorMark } from '../shared/ColorMarkOperations.js';\nimport { renderColorPickerPopup } from '../shared/ColorPickerPopup.js';\nimport { isValidCSSColor, resolveColors } from '../shared/ColorValidation.js';\nimport {\n\tTEXT_COLOR_LOCALE_EN,\n\ttype TextColorLocale,\n\tloadTextColorLocale,\n} from './TextColorLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\ttextColor: { color: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface TextColorConfig {\n\t/**\n\t * Restricts the color picker to a specific set of hex colors.\n\t * Each value must be a valid hex color code (`#RGB` or `#RRGGBB`).\n\t * Duplicates are removed automatically (case-insensitive).\n\t * When omitted, the full default palette is shown.\n\t */\n\treadonly colors?: readonly string[];\n\treadonly locale?: TextColorLocale;\n}\n\n// --- Color Palette (Google Docs style: 10 columns x 7 rows) ---\n\nconst COLOR_PALETTE: readonly string[] = [\n\t// Row 1 — dark\n\t'#000000',\n\t'#434343',\n\t'#666666',\n\t'#999999',\n\t'#b7b7b7',\n\t'#cccccc',\n\t'#d9d9d9',\n\t'#efefef',\n\t'#f3f3f3',\n\t'#ffffff',\n\t// Row 2 — vivid\n\t'#980000',\n\t'#ff0000',\n\t'#ff9900',\n\t'#ffff00',\n\t'#00ff00',\n\t'#00ffff',\n\t'#4a86e8',\n\t'#0000ff',\n\t'#9900ff',\n\t'#ff00ff',\n\t// Row 3 — light 3\n\t'#e6b8af',\n\t'#f4cccc',\n\t'#fce5cd',\n\t'#fff2cc',\n\t'#d9ead3',\n\t'#d0e0e3',\n\t'#c9daf8',\n\t'#cfe2f3',\n\t'#d9d2e9',\n\t'#ead1dc',\n\t// Row 4 — light 2\n\t'#dd7e6b',\n\t'#ea9999',\n\t'#f9cb9c',\n\t'#ffe599',\n\t'#b6d7a8',\n\t'#a2c4c9',\n\t'#a4c2f4',\n\t'#9fc5e8',\n\t'#b4a7d6',\n\t'#d5a6bd',\n\t// Row 5 — light 1\n\t'#cc4125',\n\t'#e06666',\n\t'#f6b26b',\n\t'#ffd966',\n\t'#93c47d',\n\t'#76a5af',\n\t'#6d9eeb',\n\t'#6fa8dc',\n\t'#8e7cc3',\n\t'#c27ba0',\n\t// Row 6 — dark 1\n\t'#a61c00',\n\t'#cc0000',\n\t'#e69138',\n\t'#f1c232',\n\t'#6aa84f',\n\t'#45818e',\n\t'#3c78d8',\n\t'#3d85c6',\n\t'#674ea7',\n\t'#a64d79',\n\t// Row 7 — dark 2\n\t'#85200c',\n\t'#990000',\n\t'#b45f06',\n\t'#bf9000',\n\t'#38761d',\n\t'#134f5c',\n\t'#1155cc',\n\t'#0b5394',\n\t'#351c75',\n\t'#741b47',\n];\n\n// --- Plugin ---\n\nexport class TextColorPlugin implements Plugin {\n\treadonly id = 'textColor';\n\treadonly name = 'Text Color';\n\treadonly priority = 23;\n\n\tprivate readonly config: TextColorConfig;\n\tprivate readonly colors: readonly string[];\n\tprivate locale!: TextColorLocale;\n\n\tconstructor(config?: Partial<TextColorConfig>) {\n\t\tthis.config = { ...config };\n\t\tthis.colors = resolveColors(config?.colors, COLOR_PALETTE, 'TextColorPlugin');\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 = lang === 'en' ? TEXT_COLOR_LOCALE_EN : await loadTextColorLocale(lang);\n\t\t}\n\n\t\tcontext.registerStyleSheet(COLOR_PICKER_CSS);\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'textColor',\n\t\t\trank: 5,\n\t\t\tattrs: {\n\t\t\t\tcolor: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tconst color = mark.attrs?.color ?? '';\n\t\t\t\tsetStyleProperty(span, 'color', color);\n\t\t\t\treturn span;\n\t\t\t},\n\t\t\ttoHTMLString: (mark, content, ctx?: HTMLExportContext) => {\n\t\t\t\tconst color: string = String(mark.attrs?.color ?? '');\n\t\t\t\tif (!color || !isValidCSSColor(color)) return content;\n\t\t\t\tconst decl: string = `color: ${escapeHTML(color)}`;\n\t\t\t\tconst attr: string = ctx?.styleAttr(decl) ?? ` style=\"${decl}\"`;\n\t\t\t\treturn `<span${attr}>${content}</span>`;\n\t\t\t},\n\t\t\ttoHTMLStyle: (mark) => {\n\t\t\t\tconst color: string = String(mark.attrs?.color ?? '');\n\t\t\t\tif (!color || !isValidCSSColor(color)) return null;\n\t\t\t\treturn `color: ${escapeHTML(color)}`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'span',\n\t\t\t\t\tgetAttrs: (el) => {\n\t\t\t\t\t\tconst color: string = el.style.color;\n\t\t\t\t\t\tif (!color || !isValidCSSColor(color)) return false;\n\t\t\t\t\t\treturn { color };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['span'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('removeTextColor', () => {\n\t\t\treturn removeColorMark(context, context.getState(), 'textColor');\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst pathD =\n\t\t\t'M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2z' + 'm-1.38 9L12 5.67 14.38 12H9.62z';\n\t\tconst icon: string = [\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\"',\n\t\t\t' viewBox=\"0 0 24 24\">',\n\t\t\t`<path d=\"${pathD}\"/>`,\n\t\t\t'<rect x=\"3\" y=\"19.5\" width=\"18\" height=\"3\"',\n\t\t\t' rx=\"0.5\" fill=\"#e53935\"/>',\n\t\t\t'</svg>',\n\t\t].join('');\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'textColor',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: this.locale.label,\n\t\t\ttooltip: this.locale.tooltip,\n\t\t\tcommand: 'removeTextColor',\n\t\t\tpopupType: 'custom',\n\t\t\trenderPopup: (container, ctx, onClose) => {\n\t\t\t\trenderColorPickerPopup(container, ctx, {\n\t\t\t\t\tmarkType: 'textColor',\n\t\t\t\t\tcolors: this.colors,\n\t\t\t\t\tcolumns: 10,\n\t\t\t\t\tresetLabel: this.locale.resetLabel,\n\t\t\t\t\tresetCommand: 'removeTextColor',\n\t\t\t\t\tariaLabelPrefix: this.locale.ariaLabelPrefix,\n\t\t\t\t\tonClose,\n\t\t\t\t});\n\t\t\t},\n\t\t\tisActive: (state: EditorState) => isColorMarkActive(state, 'textColor'),\n\t\t});\n\t}\n}\n"],"names":["TEXT_COLOR_LOCALE_EN","label","tooltip","resetLabel","ariaLabelPrefix","localeModules","assign","import","async","loadTextColorLocale","lang","loader","default","COLOR_PALETTE","TextColorPlugin","id","name","priority","config","colors","locale","constructor","this","resolveColors","init","context","service","getService","LocaleServiceKey","getLocale","registerStyleSheet","COLOR_PICKER_CSS","registerMarkSpec","registerCommands","registerToolbarItem","type","rank","attrs","color","toDOM","mark","span","document","createElement","setStyleProperty","toHTMLString","content","ctx","String","isValidCSSColor","decl","escapeHTML","styleAttr","toHTMLStyle","parseHTML","tag","getAttrs","el","style","sanitize","tags","registerCommand","removeColorMark","getState","icon","join","group","command","popupType","renderPopup","container","onClose","renderColorPickerPopup","markType","columns","resetCommand","isActive","state","isColorMarkActive"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"text-color.mjs","sources":["../../src/plugins/text-color/TextColorLocale.ts","../../src/plugins/text-color/TextColorPlugin.ts"],"sourcesContent":["/** Locale interface and default English locale for the TextColorPlugin. */\n\n// --- Locale Interface ---\n\nexport interface TextColorLocale {\n\treadonly label: string;\n\treadonly tooltip: string;\n\treadonly resetLabel: string;\n\treadonly ariaLabelPrefix: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_COLOR_LOCALE_EN: TextColorLocale = {\n\tlabel: 'Text Color',\n\ttooltip: 'Text Color',\n\tresetLabel: 'Default',\n\tariaLabelPrefix: 'Text color',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: Record<string, () => Promise<{ default: TextColorLocale }>> =\n\timport.meta.glob<{ default: TextColorLocale }>('./locales/*.ts', { eager: false });\n\nexport async function loadTextColorLocale(lang: string): Promise<TextColorLocale> {\n\tif (lang === 'en') return TEXT_COLOR_LOCALE_EN;\n\tconst loader = localeModules[`./locales/${lang}.ts`];\n\tif (!loader) return TEXT_COLOR_LOCALE_EN;\n\ttry {\n\t\tconst mod = await loader();\n\t\treturn mod.default;\n\t} catch {\n\t\treturn TEXT_COLOR_LOCALE_EN;\n\t}\n}\n","/**\n * TextColorPlugin: registers a text color mark with attrs,\n * toolbar button with a color picker popup, and removeTextColor command.\n */\n\nimport { COLOR_PICKER_CSS } from '../../editor/styles/color-picker.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport type { HTMLExportContext } from '../../model/NodeSpec.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport { setStyleProperty } from '../../style/StyleRuntime.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { isColorMarkActive, removeColorMark } from '../shared/ColorMarkOperations.js';\nimport { renderColorPickerPopup } from '../shared/ColorPickerPopup.js';\nimport { isValidCSSColor, resolveColors } from '../shared/ColorValidation.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport {\n\tTEXT_COLOR_LOCALE_EN,\n\ttype TextColorLocale,\n\tloadTextColorLocale,\n} from './TextColorLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\ttextColor: { color: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface TextColorConfig {\n\t/**\n\t * Restricts the color picker to a specific set of hex colors.\n\t * Each value must be a valid hex color code (`#RGB` or `#RRGGBB`).\n\t * Duplicates are removed automatically (case-insensitive).\n\t * When omitted, the full default palette is shown.\n\t */\n\treadonly colors?: readonly string[];\n\treadonly locale?: TextColorLocale;\n}\n\n// --- Color Palette (Google Docs style: 10 columns x 7 rows) ---\n\nconst COLOR_PALETTE: readonly string[] = [\n\t// Row 1 — dark\n\t'#000000',\n\t'#434343',\n\t'#666666',\n\t'#999999',\n\t'#b7b7b7',\n\t'#cccccc',\n\t'#d9d9d9',\n\t'#efefef',\n\t'#f3f3f3',\n\t'#ffffff',\n\t// Row 2 — vivid\n\t'#980000',\n\t'#ff0000',\n\t'#ff9900',\n\t'#ffff00',\n\t'#00ff00',\n\t'#00ffff',\n\t'#4a86e8',\n\t'#0000ff',\n\t'#9900ff',\n\t'#ff00ff',\n\t// Row 3 — light 3\n\t'#e6b8af',\n\t'#f4cccc',\n\t'#fce5cd',\n\t'#fff2cc',\n\t'#d9ead3',\n\t'#d0e0e3',\n\t'#c9daf8',\n\t'#cfe2f3',\n\t'#d9d2e9',\n\t'#ead1dc',\n\t// Row 4 — light 2\n\t'#dd7e6b',\n\t'#ea9999',\n\t'#f9cb9c',\n\t'#ffe599',\n\t'#b6d7a8',\n\t'#a2c4c9',\n\t'#a4c2f4',\n\t'#9fc5e8',\n\t'#b4a7d6',\n\t'#d5a6bd',\n\t// Row 5 — light 1\n\t'#cc4125',\n\t'#e06666',\n\t'#f6b26b',\n\t'#ffd966',\n\t'#93c47d',\n\t'#76a5af',\n\t'#6d9eeb',\n\t'#6fa8dc',\n\t'#8e7cc3',\n\t'#c27ba0',\n\t// Row 6 — dark 1\n\t'#a61c00',\n\t'#cc0000',\n\t'#e69138',\n\t'#f1c232',\n\t'#6aa84f',\n\t'#45818e',\n\t'#3c78d8',\n\t'#3d85c6',\n\t'#674ea7',\n\t'#a64d79',\n\t// Row 7 — dark 2\n\t'#85200c',\n\t'#990000',\n\t'#b45f06',\n\t'#bf9000',\n\t'#38761d',\n\t'#134f5c',\n\t'#1155cc',\n\t'#0b5394',\n\t'#351c75',\n\t'#741b47',\n];\n\n// --- Plugin ---\n\nexport class TextColorPlugin implements Plugin {\n\treadonly id = 'textColor';\n\treadonly name = 'Text Color';\n\treadonly priority = 23;\n\n\tprivate readonly config: TextColorConfig;\n\tprivate readonly colors: readonly string[];\n\tprivate locale!: TextColorLocale;\n\n\tconstructor(config?: Partial<TextColorConfig>) {\n\t\tthis.config = { ...config };\n\t\tthis.colors = resolveColors(config?.colors, COLOR_PALETTE, 'TextColorPlugin');\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_COLOR_LOCALE_EN,\n\t\t\tloadTextColorLocale,\n\t\t);\n\n\t\tcontext.registerStyleSheet(COLOR_PICKER_CSS);\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'textColor',\n\t\t\trank: 5,\n\t\t\tattrs: {\n\t\t\t\tcolor: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tconst color = mark.attrs?.color ?? '';\n\t\t\t\tsetStyleProperty(span, 'color', color);\n\t\t\t\treturn span;\n\t\t\t},\n\t\t\ttoHTMLString: (mark, content, ctx?: HTMLExportContext) => {\n\t\t\t\tconst color: string = String(mark.attrs?.color ?? '');\n\t\t\t\tif (!color || !isValidCSSColor(color)) return content;\n\t\t\t\tconst decl: string = `color: ${escapeHTML(color)}`;\n\t\t\t\tconst attr: string = ctx?.styleAttr(decl) ?? ` style=\"${decl}\"`;\n\t\t\t\treturn `<span${attr}>${content}</span>`;\n\t\t\t},\n\t\t\ttoHTMLStyle: (mark) => {\n\t\t\t\tconst color: string = String(mark.attrs?.color ?? '');\n\t\t\t\tif (!color || !isValidCSSColor(color)) return null;\n\t\t\t\treturn `color: ${escapeHTML(color)}`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'span',\n\t\t\t\t\tgetAttrs: (el) => {\n\t\t\t\t\t\tconst color: string = el.style.color;\n\t\t\t\t\t\tif (!color || !isValidCSSColor(color)) return false;\n\t\t\t\t\t\treturn { color };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['span'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('removeTextColor', () => {\n\t\t\treturn removeColorMark(context, context.getState(), 'textColor');\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst pathD =\n\t\t\t'M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2z' + 'm-1.38 9L12 5.67 14.38 12H9.62z';\n\t\tconst icon: string = [\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\"',\n\t\t\t' viewBox=\"0 0 24 24\">',\n\t\t\t`<path d=\"${pathD}\"/>`,\n\t\t\t'<rect x=\"3\" y=\"19.5\" width=\"18\" height=\"3\"',\n\t\t\t' rx=\"0.5\" fill=\"#e53935\"/>',\n\t\t\t'</svg>',\n\t\t].join('');\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'textColor',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: this.locale.label,\n\t\t\ttooltip: this.locale.tooltip,\n\t\t\tcommand: 'removeTextColor',\n\t\t\tpopupType: 'custom',\n\t\t\trenderPopup: (container, ctx, onClose) => {\n\t\t\t\trenderColorPickerPopup(container, ctx, {\n\t\t\t\t\tmarkType: 'textColor',\n\t\t\t\t\tcolors: this.colors,\n\t\t\t\t\tcolumns: 10,\n\t\t\t\t\tresetLabel: this.locale.resetLabel,\n\t\t\t\t\tresetCommand: 'removeTextColor',\n\t\t\t\t\tariaLabelPrefix: this.locale.ariaLabelPrefix,\n\t\t\t\t\tonClose,\n\t\t\t\t});\n\t\t\t},\n\t\t\tisActive: (state: EditorState) => isColorMarkActive(state, 'textColor'),\n\t\t});\n\t}\n}\n"],"names":["TEXT_COLOR_LOCALE_EN","label","tooltip","resetLabel","ariaLabelPrefix","localeModules","assign","import","async","loadTextColorLocale","lang","loader","default","COLOR_PALETTE","TextColorPlugin","id","name","priority","config","colors","locale","constructor","this","resolveColors","init","context","resolveLocale","registerStyleSheet","COLOR_PICKER_CSS","registerMarkSpec","registerCommands","registerToolbarItem","type","rank","attrs","color","toDOM","mark","span","document","createElement","setStyleProperty","toHTMLString","content","ctx","String","isValidCSSColor","decl","escapeHTML","styleAttr","toHTMLStyle","parseHTML","tag","getAttrs","el","style","sanitize","tags","registerCommand","removeColorMark","getState","icon","join","group","command","popupType","renderPopup","container","onClose","renderColorPickerPopup","markType","columns","resetCommand","isActive","state","isColorMarkActive"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextDirectionCorePlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-direction/TextDirectionCorePlugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TextDirectionCorePlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-direction/TextDirectionCorePlugin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK1D,OAAO,EAEN,KAAK,mBAAmB,EAExB,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IACnC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;CACtC;AAcD,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAInE,CAAC;AAIF;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,MAAM;IACrD,QAAQ,CAAC,EAAE,oBAAoB;IAC/B,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,eAAe,CAAsC;gBAEjD,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAI3C,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjD,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,cAAc;IA2BtB,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,YAAY;CAIpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextDirectionPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-direction/TextDirectionPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"TextDirectionPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-direction/TextDirectionPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK1D,OAAO,EAEN,KAAK,mBAAmB,EAExB,MAAM,0BAA0B,CAAC;AASlC,OAAO,QAAQ,6BAA6B,CAAC;IAC5C,UAAU,gBAAgB;QACzB,GAAG,EAAE;YAAE,GAAG,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;SAAE,CAAC;KACrC;CACD;AAID,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IACnC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;CACtC;AAgBD,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAInE,CAAC;AASF,qBAAa,mBAAoB,YAAW,MAAM;IACjD,QAAQ,CAAC,EAAE,oBAAoB;IAC/B,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,eAAe,CAAsC;gBAEjD,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAI3C,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BjD,OAAO,IAAI,IAAI;IAOf;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,gBAAgB;IA4DxB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,yBAAyB;IAyBjC,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,YAAY;IA0BpB;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,YAAY;IAOpB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,SAAS;CAOjB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{i as t,a as e,r as i}from"../chunks/AttributedMarkCommands-
|
|
1
|
+
import{i as t,a as e,r as i}from"../chunks/AttributedMarkCommands-BY1BSYWM.mjs";import{a as o}from"../chunks/HTMLUtils-Cxy99Ak2.mjs";import{j as r,i as n,h as s}from"../chunks/Selection-DhbizDM4.mjs";import{m as a}from"../chunks/TypeBrands-Bp_Z_o5Y.mjs";import{a as l}from"../chunks/Platform-CU6itXZo.mjs";import{r as c,g as d}from"../chunks/PluginHelpers-CdPR0MuT.mjs";import{f as u}from"../chunks/ShortcutFormatting-BLKS0Gys.mjs";import{d as h,f as m,g,S as p,l as f,T as b}from"../chunks/TextDirectionLocale-CKz0ZrH_.mjs";import{i as v,b as T}from"../chunks/Document-3pNX7ear.mjs";function y(t,e,i){const o=t.getNodePath(e.id);if(o)return{type:"setNodeAttr",path:o,attrs:{...e.attrs,dir:i},previousAttrs:e.attrs}}function B(t,e,i,o){const r=e.getBlock(t.blockId);if(!r||!i.has(r.type))return;const n=v(r);if("auto"!==g(r)&&n.length>0)return;const s=T(r,t.offset),a=n.slice(0,s)+t.text+n.slice(s),l=h(a);if(!l)return;const c=y(e,r,l);c&&o.push(c)}function D(t,e,i,o){const r=e.getBlock(t.blockId);if(!r||!i.has(r.type))return;const n=g(r);if("auto"===n)return;const s=v(r),a=T(r,t.from),l=T(r,t.to),c=s.slice(0,a)+s.slice(l);if(0===c.length){const t=y(e,r,"auto");return void(t&&o.push(t))}const d=h(c);if(!d||d===n)return;const u=y(e,r,d);u&&o.push(u)}const w={directableTypes:["paragraph","heading","title","subtitle","table_cell","blockquote","list_item"]},k={ltr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z"/></svg>',rtl:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z"/></svg>',auto:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z"/></svg>'},S=["ltr","rtl","auto"];class x{id="text-direction";name="Text Direction";priority=91;config;locale;directableTypes;shiftDirHandler=null;constructor(t){this.config={...w,...t}}async init(t){this.locale=await c(t,this.config.locale,b,f),this.directableTypes=new Set(this.config.directableTypes),this.patchNodeSpecs(t),this.registerBdiMark(t),this.registerCommands(t),this.registerKeymaps(t),this.registerToolbarItem(t),this.registerInlineToolbarItem(t),function(t,e){t.registerMiddleware((t,i,o)=>{let r=!1;const n=t.steps.map(t=>{if("setBlockType"!==t.type)return t;if(!e.has(t.nodeType))return t;const i=t.previousAttrs?.dir;return i&&"auto"!==i?(r=!0,{...t,attrs:{...t.attrs,dir:i}}):t});o(r?{...t,steps:n}:t)},{name:"text-direction:preserve-dir"})}(t,this.directableTypes),function(t,e){t.registerMiddleware((t,i,o)=>{const r=[];for(const n of t.steps)"insertText"===n.type?B(n,i,e,r):"deleteText"===n.type&&D(n,i,e,r);o(r.length>0?{...t,steps:[...t.steps,...r]}:t)},{name:"text-direction:auto-detect"})}(t,this.directableTypes),function(t,e){t.registerMiddleware((t,i,o)=>{let r=!1;const n=t.steps.map(t=>{if("insertNode"!==t.type)return t;if(!e.has(t.node.type))return t;if("auto"!==String(t.node.attrs?.dir??"auto"))return t;const o=v(t.node);if(o.length>0){const e=h(o);if(e)return r=!0,{...t,node:{...t.node,attrs:{...t.node.attrs,dir:e}}}}const n=m(i,t.parentPath,t.index);return n&&"auto"!==n?(r=!0,{...t,node:{...t.node,attrs:{...t.node.attrs,dir:n}}}):t});o(r?{...t,steps:n}:t)},{name:"text-direction:inherit-dir"})}(t,this.directableTypes),l()||(this.shiftDirHandler=new p(t),this.shiftDirHandler.attach(t.getContainer()))}destroy(){this.shiftDirHandler?.detach(),this.shiftDirHandler=null}patchNodeSpecs(t){const e=t.getSchemaRegistry();for(const i of this.config.directableTypes){const t=e.getNodeSpec(i);if(!t)continue;if(t.attrs?.dir)continue;const o=t.toDOM;e.removeNodeSpec(i),e.registerNodeSpec({...t,attrs:{...t.attrs,dir:{default:"auto"}},toDOM(e){const i=o.call(t,e);return L(i,e),i}})}}registerBdiMark(t){t.registerMarkSpec({type:"bdi",rank:10,attrs:{dir:{default:"auto"}},toDOM(t){const e=document.createElement("bdi"),i=String(t.attrs?.dir??"auto");return e.setAttribute("dir",i),e},toHTMLString:(t,e)=>`<bdi dir="${o(String(t.attrs?.dir??"auto"))}">${e}</bdi>`,parseHTML:[{tag:"bdi",getAttrs:t=>{const e=t.getAttribute("dir");return"ltr"===e||"rtl"===e?{dir:e}:{dir:"auto"}}}],sanitize:{tags:["bdi"],attrs:["dir"]}})}registerCommands(t){t.registerCommand("setDirectionLTR",()=>{const e=this.setDirection(t,"ltr");return e&&t.announce(this.locale.announceLTR),e}),t.registerCommand("setDirectionRTL",()=>{const e=this.setDirection(t,"rtl");return e&&t.announce(this.locale.announceRTL),e}),t.registerCommand("setDirectionAuto",()=>{const e=this.setDirection(t,"auto");return e&&t.announce(this.locale.announceAuto),e}),t.registerCommand("toggleBidiLTR",()=>{const e=this.applyBdi(t,"ltr");return e&&t.announce(this.locale.inlineLTR),e}),t.registerCommand("toggleBidiRTL",()=>{const e=this.applyBdi(t,"rtl");return e&&t.announce(this.locale.inlineRTL),e}),t.registerCommand("toggleBidiAuto",()=>{const e=this.applyBdi(t,"auto");return e&&t.announce(this.locale.inlineAuto),e}),t.registerCommand("removeBidi",()=>{const e=this.removeBdi(t);return e&&t.announce(this.locale.announceRemoveBidi),e}),t.registerCommand("toggleBidiIsolation",()=>this.toggleBidiIsolation(t)),t.registerCommand("toggleDirection",()=>{const e=t.getState(),i=d(e);if(!i||!this.directableTypes.has(i.type))return!1;const o=g(i),r="auto"===o?"rtl":"rtl"===o?"ltr":"auto";return this.setDirection(t,r)})}registerKeymaps(t){t.registerKeymap({"Mod-Shift-D":()=>t.executeCommand("toggleDirection"),"Mod-Shift-B":()=>t.executeCommand("toggleBidiIsolation")})}registerToolbarItem(t){const e={ltr:"setDirectionLTR",rtl:"setDirectionRTL",auto:"setDirectionAuto"},i=S.map(t=>({label:this.getDirectionLabel(t),command:e[t],icon:k[t]}));t.registerToolbarItem({id:"text-direction",group:"block",icon:k.auto,label:this.locale.toolbarLabel,tooltip:`${this.locale.toolbarTooltip} (${u("Mod-Shift-D")})`,command:"setDirectionAuto",popupType:"dropdown",popupConfig:{items:i},isActive:t=>this.isNonDefaultDirection(t),isEnabled:t=>this.isDirectable(t),getIcon:t=>{const e=d(t);if(!e)return k.auto;const i=g(e);return k[i]??k.auto}})}registerInlineToolbarItem(e){const i=[{label:this.locale.inlineLTR,command:"toggleBidiLTR",icon:k.ltr},{label:this.locale.inlineRTL,command:"toggleBidiRTL",icon:k.rtl},{label:this.locale.inlineAuto,command:"toggleBidiAuto",icon:k.auto},{label:this.locale.announceRemoveBidi,command:"removeBidi"}];e.registerToolbarItem({id:"inline-direction",group:"format",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 4v7h2V4h2v7h2V4h1V2H10a3 3 0 1 0 0 6zm-3.5 9.5L3 17l3.5 3.5V18h3v-2h-3v-2.5zm14 0L17 17l3.5 3.5V18h-3v-2h3v-2.5zM11 16h2v6h-2z"/></svg>',label:this.locale.inlineLabel,tooltip:`${this.locale.inlineTooltip} (${u("Mod-Shift-B")})`,command:"toggleBidiIsolation",popupType:"dropdown",popupConfig:{items:i},isActive:e=>t(e,"bdi"),isEnabled:t=>{const e=t.selection;return r(e)&&!n(e)}})}getDirectionLabel(t){return"ltr"===t?this.locale.ltr:"rtl"===t?this.locale.rtl:this.locale.auto}setDirection(t,e){const i=t.getState(),o=this.getSelectedBlockIds(i);if(0===o.length)return!1;const r=i.transaction("command");let n=!1;for(const a of o){const t=i.getBlock(a);if(!t||!this.directableTypes.has(t.type))continue;const o=i.getNodePath(a);o&&(r.setNodeAttr(o,{...t.attrs,dir:e}),n=!0)}if(!n)return!1;const s=r.setSelection(i.selection).build();return t.dispatch(s),!0}getSelectedBlockIds(t){const e=t.selection;if(s(e))return[e.nodeId];if(!r(e))return[];const i=e.anchor.blockId,o=e.head.blockId;if(i===o)return[i];const n=t.getBlockOrder(),a=n.indexOf(i),l=n.indexOf(o);if(-1===a||-1===l)return[];const c=Math.min(a,l),d=Math.max(a,l);return n.slice(c,d+1)}isNonDefaultDirection(t){const e=d(t);if(!e||!this.directableTypes.has(e.type))return!1;const i=e.attrs?.dir;return null!=i&&"auto"!==i}isDirectable(t){const e=d(t);return null!=e&&this.directableTypes.has(e.type)}toggleBidiIsolation(e){const i=e.getState();if(t(i,"bdi")){const t=this.removeBdi(e);return t&&e.announce(this.locale.announceRemoveBidi),t}const o=d(i),r="rtl"===(o?g(o):"auto")?"ltr":"rtl",n=this.applyBdi(e,r);if(n){const t="ltr"===r?this.locale.inlineLTR:this.locale.inlineRTL;e.announce(t)}return n}applyBdi(t,i){const o=t.getState(),r={type:a("bdi"),attrs:{dir:i}},n=e(o,r);return!!n&&(t.dispatch(n),!0)}removeBdi(t){const e=t.getState(),o=i(e,a("bdi"));return!!o&&(t.dispatch(o),!0)}}function L(t,e){const i=e.attrs?.dir;"ltr"!==i&&"rtl"!==i&&"auto"!==i||t.setAttribute("dir",i)}export{k as DIRECTION_ICONS,b as TEXT_DIRECTION_LOCALE_EN,x as TextDirectionAdvancedPlugin,h as detectTextDirection,m as findSiblingDirection,g as getBlockDir,f as loadTextDirectionLocale};
|
|
2
2
|
//# sourceMappingURL=text-direction-advanced.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-direction-advanced.mjs","sources":["../../src/plugins/text-direction/TextDirectionMiddleware.ts","../../src/plugins/text-direction/TextDirectionPlugin.ts"],"sourcesContent":["/**\n * Middleware registrations for the TextDirectionPlugin.\n * Separated from the main plugin file for maintainability.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { blockOffsetToTextOffset, getBlockText } from '../../model/Document.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Step } from '../../state/Transaction.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { detectTextDirection, findSiblingDirection, getBlockDir } from './DirectionDetection.js';\nimport type { TextDirection } from './TextDirectionPlugin.js';\n\n/**\n * Preserves the `dir` attribute when other plugins change the block\n * type (e.g. paragraph -> heading) via `setBlockType`, which replaces attrs.\n */\nexport function registerPreserveDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, _state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'setBlockType') return step;\n\t\t\t\tif (!directableTypes.has(step.nodeType)) return step;\n\n\t\t\t\tconst prevDir = step.previousAttrs?.dir;\n\t\t\t\tif (!prevDir || prevDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tattrs: { ...step.attrs, dir: prevDir },\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:preserve-dir' },\n\t);\n}\n\n/**\n * Auto-detects text direction on `insertText` and `deleteText` steps\n * for blocks with `dir=\"auto\"` (or blocks whose content changes direction).\n * Uses the first strong directional character to determine LTR vs RTL.\n */\nexport function registerAutoDetectMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tconst extraSteps: Step[] = [];\n\n\t\t\tfor (const step of tr.steps) {\n\t\t\t\tif (step.type === 'insertText') {\n\t\t\t\t\thandleInsertText(step, state, directableTypes, extraSteps);\n\t\t\t\t} else if (step.type === 'deleteText') {\n\t\t\t\t\thandleDeleteText(step, state, directableTypes, extraSteps);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (extraSteps.length > 0) {\n\t\t\t\tnext({ ...tr, steps: [...tr.steps, ...extraSteps] });\n\t\t\t} else {\n\t\t\t\tnext(tr);\n\t\t\t}\n\t\t},\n\t\t{ name: 'text-direction:auto-detect' },\n\t);\n}\n\n/** Builds a `setNodeAttr` step to change the `dir` attribute of a block. */\nfunction buildDirChangeStep(\n\tstate: EditorState,\n\tblock: BlockNode,\n\tdir: TextDirection | 'auto',\n): Step | undefined {\n\tconst path = state.getNodePath(block.id);\n\tif (!path) return undefined;\n\n\treturn {\n\t\ttype: 'setNodeAttr',\n\t\tpath,\n\t\tattrs: { ...block.attrs, dir },\n\t\tpreviousAttrs: block.attrs as Record<string, string | number | boolean>,\n\t};\n}\n\n/** Handles direction detection after text insertion. */\nfunction handleInsertText(\n\tstep: Extract<Step, { type: 'insertText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tconst existingText: string = getBlockText(block);\n\tif (getBlockDir(block) !== 'auto' && existingText.length > 0) return;\n\n\tconst textOffset: number = blockOffsetToTextOffset(block, step.offset);\n\tconst textAfter: string =\n\t\texistingText.slice(0, textOffset) + step.text + existingText.slice(textOffset);\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\n/** Handles direction re-detection after text deletion. */\nfunction handleDeleteText(\n\tstep: Extract<Step, { type: 'deleteText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tconst currentDir: TextDirection = getBlockDir(block);\n\tif (currentDir === 'auto') return;\n\n\tconst existingText: string = getBlockText(block);\n\tconst fromText: number = blockOffsetToTextOffset(block, step.from);\n\tconst toText: number = blockOffsetToTextOffset(block, step.to);\n\tconst textAfter: string = existingText.slice(0, fromText) + existingText.slice(toText);\n\n\tif (textAfter.length === 0) {\n\t\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, 'auto');\n\t\tif (dirStep) extraSteps.push(dirStep);\n\t\treturn;\n\t}\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected || detected === currentDir) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\n/**\n * Inherits `dir` from the nearest sibling when inserting a new block\n * (e.g. via GapCursor or NodeSelection).\n */\nexport function registerInheritDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'insertNode') return step;\n\t\t\t\tif (!directableTypes.has(step.node.type)) return step;\n\n\t\t\t\tconst newDir: string = String(step.node.attrs?.dir ?? 'auto');\n\t\t\t\tif (newDir !== 'auto') return step;\n\n\t\t\t\t// Detect direction from inserted node's text content\n\t\t\t\tconst nodeText: string = getBlockText(step.node);\n\t\t\t\tif (nodeText.length > 0) {\n\t\t\t\t\tconst detected: TextDirection | null = detectTextDirection(nodeText);\n\t\t\t\t\tif (detected) {\n\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...step,\n\t\t\t\t\t\t\tnode: {\n\t\t\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: detected },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fall back to sibling direction for empty blocks\n\t\t\t\tconst siblingDir: string | undefined = findSiblingDirection(\n\t\t\t\t\tstate,\n\t\t\t\t\tstep.parentPath,\n\t\t\t\t\tstep.index,\n\t\t\t\t);\n\t\t\t\tif (!siblingDir || siblingDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tnode: {\n\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: siblingDir },\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:inherit-dir' },\n\t);\n}\n","/**\n * TextDirectionPlugin: adds block-level text direction (`dir` attribute)\n * and inline bidi isolation (`<bdi>` mark) for RTL language support.\n *\n * Block-level: patches NodeSpecs for directable types to render the HTML\n * `dir` attribute. Provides `setDirectionLTR`, `setDirectionRTL`, and\n * `setDirectionAuto` commands with a toolbar dropdown.\n *\n * Inline: registers a `bdi` mark for bidi isolation of inline spans,\n * with `toggleBidiLTR`, `toggleBidiRTL`, `toggleBidiAuto`, and\n * `removeBidi` commands.\n */\n\nimport {\n\tapplyAttributedMark,\n\tisAttributedMarkActive,\n\tremoveAttributedMark,\n} from '../../commands/AttributedMarkCommands.js';\nimport { LocaleServiceKey } from '../../i18n/LocaleService.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport { isCollapsed, isNodeSelection, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport { isMac } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { getSelectedBlock } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { getBlockDir } from './DirectionDetection.js';\nimport { ShiftDirectionHandler } from './ShiftDirectionHandler.js';\nimport {\n\tTEXT_DIRECTION_LOCALE_EN,\n\ttype TextDirectionLocale,\n\tloadTextDirectionLocale,\n} from './TextDirectionLocale.js';\nimport {\n\tregisterAutoDetectMiddleware,\n\tregisterInheritDirMiddleware,\n\tregisterPreserveDirMiddleware,\n} from './TextDirectionMiddleware.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tbdi: { dir: 'ltr' | 'rtl' | 'auto' };\n\t}\n}\n\n// --- Public Types ---\n\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\n\nexport interface TextDirectionConfig {\n\t/** Block types that support direction. */\n\treadonly directableTypes: readonly string[];\n\treadonly locale?: TextDirectionLocale;\n}\n\n// --- Constants ---\n\nconst DEFAULT_CONFIG: TextDirectionConfig = {\n\tdirectableTypes: [\n\t\t'paragraph',\n\t\t'heading',\n\t\t'title',\n\t\t'subtitle',\n\t\t'table_cell',\n\t\t'blockquote',\n\t\t'list_item',\n\t],\n};\n\nexport const DIRECTION_ICONS: Readonly<Record<TextDirection, string>> = {\n\tltr: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z\"/></svg>',\n\trtl: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z\"/></svg>',\n\tauto: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z\"/></svg>',\n};\n\nconst ALL_DIRECTIONS: readonly TextDirection[] = ['ltr', 'rtl', 'auto'];\n\nconst INLINE_BDI_ICON: string =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4v7h2V4h2v7h2V4h1V2H10a3 3 0 1 0 0 6zm-3.5 9.5L3 17l3.5 3.5V18h3v-2h-3v-2.5zm14 0L17 17l3.5 3.5V18h-3v-2h3v-2.5zM11 16h2v6h-2z\"/></svg>';\n\n// --- Plugin ---\n\nexport class TextDirectionPlugin implements Plugin {\n\treadonly id = 'text-direction';\n\treadonly name = 'Text Direction';\n\treadonly priority = 91;\n\n\tprivate readonly config: TextDirectionConfig;\n\tprivate locale!: TextDirectionLocale;\n\tprivate directableTypes!: ReadonlySet<string>;\n\tprivate shiftDirHandler: ShiftDirectionHandler | null = null;\n\n\tconstructor(config?: Partial<TextDirectionConfig>) {\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 = lang === 'en' ? TEXT_DIRECTION_LOCALE_EN : await loadTextDirectionLocale(lang);\n\t\t}\n\n\t\tthis.directableTypes = new Set(this.config.directableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerBdiMark(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\t\tthis.registerInlineToolbarItem(context);\n\t\tregisterPreserveDirMiddleware(context, this.directableTypes);\n\t\tregisterAutoDetectMiddleware(context, this.directableTypes);\n\t\tregisterInheritDirMiddleware(context, this.directableTypes);\n\n\t\t// Ctrl+Shift direction shortcuts (Windows/Linux convention)\n\t\tif (!isMac()) {\n\t\t\tthis.shiftDirHandler = new ShiftDirectionHandler(context);\n\t\t\tthis.shiftDirHandler.attach(context.getContainer());\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.shiftDirHandler?.detach();\n\t\tthis.shiftDirHandler = null;\n\t}\n\n\t// --- NodeSpec Patching ---\n\n\t/**\n\t * Patches existing NodeSpecs for directable block types to support the\n\t * `dir` attribute and render it as an HTML attribute. Skips types\n\t * that already define a `dir` attribute in their spec.\n\t */\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tconst registry = context.getSchemaRegistry();\n\n\t\tfor (const type of this.config.directableTypes) {\n\t\t\tconst spec = registry.getNodeSpec(type);\n\t\t\tif (!spec) continue;\n\n\t\t\tif (spec.attrs?.dir) continue;\n\n\t\t\tconst originalToDOM = spec.toDOM;\n\n\t\t\tregistry.removeNodeSpec(type);\n\t\t\tregistry.registerNodeSpec({\n\t\t\t\t...spec,\n\t\t\t\tattrs: {\n\t\t\t\t\t...spec.attrs,\n\t\t\t\t\tdir: { default: 'auto' },\n\t\t\t\t},\n\t\t\t\ttoDOM(node) {\n\t\t\t\t\tconst el = originalToDOM.call(spec, node);\n\t\t\t\t\tapplyDirection(el, node);\n\t\t\t\t\treturn el;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\t// --- Inline <bdi> Mark ---\n\n\tprivate registerBdiMark(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'bdi',\n\t\t\trank: 10,\n\t\t\tattrs: {\n\t\t\t\tdir: { default: 'auto' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst el: HTMLElement = document.createElement('bdi');\n\t\t\t\tconst dir: string = String(mark.attrs?.dir ?? 'auto');\n\t\t\t\tel.setAttribute('dir', dir);\n\t\t\t\treturn el;\n\t\t\t},\n\t\t\ttoHTMLString: (mark, content) => {\n\t\t\t\tconst dir: string = escapeHTML(String(mark.attrs?.dir ?? 'auto'));\n\t\t\t\treturn `<bdi dir=\"${dir}\">${content}</bdi>`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'bdi',\n\t\t\t\t\tgetAttrs: (el) => {\n\t\t\t\t\t\tconst dir: string | null = el.getAttribute('dir');\n\t\t\t\t\t\tif (dir === 'ltr' || dir === 'rtl') return { dir };\n\t\t\t\t\t\treturn { dir: 'auto' };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['bdi'], attrs: ['dir'] },\n\t\t});\n\t}\n\n\t// --- Commands ---\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('setDirectionLTR', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.announceLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionRTL', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.announceRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionAuto', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.announceAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiLTR', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.inlineLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiRTL', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.inlineRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiAuto', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.inlineAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('removeBidi', () => {\n\t\t\tconst result: boolean = this.removeBdi(context);\n\t\t\tif (result) context.announce(this.locale.announceRemoveBidi);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiIsolation', () => {\n\t\t\treturn this.toggleBidiIsolation(context);\n\t\t});\n\n\t\tcontext.registerCommand('toggleDirection', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst block = getSelectedBlock(state);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\n\t\t\tconst current: TextDirection = getBlockDir(block);\n\t\t\tconst next: TextDirection = current === 'auto' ? 'rtl' : current === 'rtl' ? 'ltr' : 'auto';\n\t\t\treturn this.setDirection(context, next);\n\t\t});\n\t}\n\n\t// --- Keymaps ---\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-D': () => context.executeCommand('toggleDirection'),\n\t\t\t'Mod-Shift-B': () => context.executeCommand('toggleBidiIsolation'),\n\t\t});\n\t}\n\n\t// --- Toolbar ---\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst commandNames: Readonly<Record<TextDirection, string>> = {\n\t\t\tltr: 'setDirectionLTR',\n\t\t\trtl: 'setDirectionRTL',\n\t\t\tauto: 'setDirectionAuto',\n\t\t};\n\n\t\tconst dropdownItems = ALL_DIRECTIONS.map((dir) => ({\n\t\t\tlabel: this.getDirectionLabel(dir),\n\t\t\tcommand: commandNames[dir],\n\t\t\ticon: DIRECTION_ICONS[dir],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-direction',\n\t\t\tgroup: 'block',\n\t\t\ticon: DIRECTION_ICONS.auto,\n\t\t\tlabel: this.locale.toolbarLabel,\n\t\t\ttooltip: `${this.locale.toolbarTooltip} (${formatShortcut('Mod-Shift-D')})`,\n\t\t\tcommand: 'setDirectionAuto',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tisActive: (state) => this.isNonDefaultDirection(state),\n\t\t\tisEnabled: (state) => this.isDirectable(state),\n\t\t\tgetIcon: (state) => {\n\t\t\t\tconst block = getSelectedBlock(state);\n\t\t\t\tif (!block) return DIRECTION_ICONS.auto;\n\t\t\t\tconst dir: TextDirection = getBlockDir(block);\n\t\t\t\treturn DIRECTION_ICONS[dir] ?? DIRECTION_ICONS.auto;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerInlineToolbarItem(context: PluginContext): void {\n\t\tconst inlineItems = [\n\t\t\t{ label: this.locale.inlineLTR, command: 'toggleBidiLTR', icon: DIRECTION_ICONS.ltr },\n\t\t\t{ label: this.locale.inlineRTL, command: 'toggleBidiRTL', icon: DIRECTION_ICONS.rtl },\n\t\t\t{ label: this.locale.inlineAuto, command: 'toggleBidiAuto', icon: DIRECTION_ICONS.auto },\n\t\t\t{ label: this.locale.announceRemoveBidi, command: 'removeBidi' },\n\t\t];\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'inline-direction',\n\t\t\tgroup: 'format',\n\t\t\ticon: INLINE_BDI_ICON,\n\t\t\tlabel: this.locale.inlineLabel,\n\t\t\ttooltip: `${this.locale.inlineTooltip} (${formatShortcut('Mod-Shift-B')})`,\n\t\t\tcommand: 'toggleBidiIsolation',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: inlineItems },\n\t\t\tisActive: (state) => isAttributedMarkActive(state, 'bdi'),\n\t\t\tisEnabled: (state) => {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\treturn isTextSelection(sel) && !isCollapsed(sel);\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate getDirectionLabel(dir: TextDirection): string {\n\t\tif (dir === 'ltr') return this.locale.ltr;\n\t\tif (dir === 'rtl') return this.locale.rtl;\n\t\treturn this.locale.auto;\n\t}\n\n\t// --- Direction Logic ---\n\n\tprivate setDirection(context: PluginContext, direction: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst blockIds: BlockId[] = this.getSelectedBlockIds(state);\n\t\tif (blockIds.length === 0) return false;\n\n\t\tconst tb = state.transaction('command');\n\t\tlet changed = false;\n\n\t\tfor (const id of blockIds) {\n\t\t\tconst block = state.getBlock(id);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) continue;\n\n\t\t\tconst path = state.getNodePath(id);\n\t\t\tif (!path) continue;\n\n\t\t\ttb.setNodeAttr(path, { ...block.attrs, dir: direction });\n\t\t\tchanged = true;\n\t\t}\n\n\t\tif (!changed) return false;\n\n\t\tconst tr = tb.setSelection(state.selection).build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns all block IDs covered by the current selection.\n\t * Only handles TextSelection and NodeSelection — other selection types\n\t * (e.g. GapCursorSelection) return an empty array intentionally, since\n\t * gap cursors sit between blocks and have no associated block content.\n\t */\n\tprivate getSelectedBlockIds(state: EditorState): BlockId[] {\n\t\tconst sel = state.selection;\n\n\t\tif (isNodeSelection(sel)) {\n\t\t\treturn [sel.nodeId];\n\t\t}\n\n\t\tif (!isTextSelection(sel)) return [];\n\n\t\tconst anchorId: BlockId = sel.anchor.blockId;\n\t\tconst headId: BlockId = sel.head.blockId;\n\n\t\tif (anchorId === headId) return [anchorId];\n\n\t\tconst order: readonly BlockId[] = state.getBlockOrder();\n\t\tconst anchorIdx: number = order.indexOf(anchorId);\n\t\tconst headIdx: number = order.indexOf(headId);\n\t\tif (anchorIdx === -1 || headIdx === -1) return [];\n\n\t\tconst from: number = Math.min(anchorIdx, headIdx);\n\t\tconst to: number = Math.max(anchorIdx, headIdx);\n\t\treturn order.slice(from, to + 1) as BlockId[];\n\t}\n\n\tprivate isNonDefaultDirection(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\t\tconst dir = block.attrs?.dir;\n\t\treturn dir != null && dir !== 'auto';\n\t}\n\n\tprivate isDirectable(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\treturn block != null && this.directableTypes.has(block.type);\n\t}\n\n\t// --- Inline bdi mark operations ---\n\n\t/**\n\t * Cycles inline bidi isolation: no-bdi → bdi (opposite of block dir) →\n\t * remove. Applies the opposite direction of the current block for the\n\t * common case (e.g., LTR word in an RTL block gets bdi-ltr).\n\t */\n\tprivate toggleBidiIsolation(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tif (isAttributedMarkActive(state, 'bdi')) {\n\t\t\tconst result: boolean = this.removeBdi(context);\n\t\t\tif (result) context.announce(this.locale.announceRemoveBidi);\n\t\t\treturn result;\n\t\t}\n\t\tconst block = getSelectedBlock(state);\n\t\tconst blockDir: TextDirection = block ? getBlockDir(block) : 'auto';\n\t\tconst bdiDir: TextDirection = blockDir === 'rtl' ? 'ltr' : 'rtl';\n\t\tconst result: boolean = this.applyBdi(context, bdiDir);\n\t\tif (result) {\n\t\t\tconst announcement: string = bdiDir === 'ltr' ? this.locale.inlineLTR : this.locale.inlineRTL;\n\t\t\tcontext.announce(announcement);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate applyBdi(context: PluginContext, dir: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst mark = { type: markType('bdi'), attrs: { dir } };\n\t\tconst tr = applyAttributedMark(state, mark);\n\t\tif (!tr) return false;\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate removeBdi(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst tr = removeAttributedMark(state, markType('bdi'));\n\t\tif (!tr) return false;\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n}\n\n// --- Helpers ---\n\nfunction applyDirection(el: HTMLElement, node: BlockNode): void {\n\tconst dir = node.attrs?.dir;\n\tif (dir === 'ltr' || dir === 'rtl' || dir === 'auto') {\n\t\tel.setAttribute('dir', dir);\n\t}\n}\n"],"names":["buildDirChangeStep","state","block","dir","path","getNodePath","id","type","attrs","previousAttrs","handleInsertText","step","directableTypes","extraSteps","getBlock","blockId","has","existingText","getBlockText","getBlockDir","length","textOffset","blockOffsetToTextOffset","offset","textAfter","slice","text","detected","detectTextDirection","dirStep","push","handleDeleteText","currentDir","fromText","from","toText","to","DEFAULT_CONFIG","DIRECTION_ICONS","ltr","rtl","auto","ALL_DIRECTIONS","TextDirectionPlugin","name","priority","config","locale","shiftDirHandler","constructor","this","init","context","service","getService","LocaleServiceKey","lang","getLocale","TEXT_DIRECTION_LOCALE_EN","loadTextDirectionLocale","Set","patchNodeSpecs","registerBdiMark","registerCommands","registerKeymaps","registerToolbarItem","registerInlineToolbarItem","registerMiddleware","tr","_state","next","patched","patchedSteps","steps","map","nodeType","prevDir","registerPreserveDirMiddleware","registerAutoDetectMiddleware","node","String","nodeText","siblingDir","findSiblingDirection","parentPath","index","registerInheritDirMiddleware","isMac","ShiftDirectionHandler","attach","getContainer","destroy","detach","registry","getSchemaRegistry","spec","getNodeSpec","originalToDOM","toDOM","removeNodeSpec","registerNodeSpec","default","el","call","applyDirection","registerMarkSpec","rank","mark","document","createElement","setAttribute","toHTMLString","content","escapeHTML","parseHTML","tag","getAttrs","getAttribute","sanitize","tags","registerCommand","result","setDirection","announce","announceLTR","announceRTL","announceAuto","applyBdi","inlineLTR","inlineRTL","inlineAuto","removeBdi","announceRemoveBidi","toggleBidiIsolation","getState","getSelectedBlock","current","registerKeymap","executeCommand","commandNames","dropdownItems","label","getDirectionLabel","command","icon","group","toolbarLabel","tooltip","toolbarTooltip","formatShortcut","popupType","popupConfig","items","isActive","isNonDefaultDirection","isEnabled","isDirectable","getIcon","inlineItems","inlineLabel","inlineTooltip","isAttributedMarkActive","sel","selection","isTextSelection","isCollapsed","direction","blockIds","getSelectedBlockIds","tb","transaction","changed","setNodeAttr","setSelection","build","dispatch","isNodeSelection","nodeId","anchorId","anchor","headId","head","order","getBlockOrder","anchorIdx","indexOf","headIdx","Math","min","max","bdiDir","announcement","markType","applyAttributedMark","removeAttributedMark"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"text-direction-advanced.mjs","sources":["../../src/plugins/text-direction/TextDirectionMiddleware.ts","../../src/plugins/text-direction/TextDirectionPlugin.ts"],"sourcesContent":["/**\n * Middleware registrations for the TextDirectionPlugin.\n * Separated from the main plugin file for maintainability.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { blockOffsetToTextOffset, getBlockText } from '../../model/Document.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Step } from '../../state/Transaction.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { detectTextDirection, findSiblingDirection, getBlockDir } from './DirectionDetection.js';\nimport type { TextDirection } from './TextDirectionPlugin.js';\n\n/**\n * Preserves the `dir` attribute when other plugins change the block\n * type (e.g. paragraph -> heading) via `setBlockType`, which replaces attrs.\n */\nexport function registerPreserveDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, _state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'setBlockType') return step;\n\t\t\t\tif (!directableTypes.has(step.nodeType)) return step;\n\n\t\t\t\tconst prevDir = step.previousAttrs?.dir;\n\t\t\t\tif (!prevDir || prevDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tattrs: { ...step.attrs, dir: prevDir },\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:preserve-dir' },\n\t);\n}\n\n/**\n * Auto-detects text direction on `insertText` and `deleteText` steps\n * for blocks with `dir=\"auto\"` (or blocks whose content changes direction).\n * Uses the first strong directional character to determine LTR vs RTL.\n */\nexport function registerAutoDetectMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tconst extraSteps: Step[] = [];\n\n\t\t\tfor (const step of tr.steps) {\n\t\t\t\tif (step.type === 'insertText') {\n\t\t\t\t\thandleInsertText(step, state, directableTypes, extraSteps);\n\t\t\t\t} else if (step.type === 'deleteText') {\n\t\t\t\t\thandleDeleteText(step, state, directableTypes, extraSteps);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (extraSteps.length > 0) {\n\t\t\t\tnext({ ...tr, steps: [...tr.steps, ...extraSteps] });\n\t\t\t} else {\n\t\t\t\tnext(tr);\n\t\t\t}\n\t\t},\n\t\t{ name: 'text-direction:auto-detect' },\n\t);\n}\n\n/** Builds a `setNodeAttr` step to change the `dir` attribute of a block. */\nfunction buildDirChangeStep(\n\tstate: EditorState,\n\tblock: BlockNode,\n\tdir: TextDirection | 'auto',\n): Step | undefined {\n\tconst path = state.getNodePath(block.id);\n\tif (!path) return undefined;\n\n\treturn {\n\t\ttype: 'setNodeAttr',\n\t\tpath,\n\t\tattrs: { ...block.attrs, dir },\n\t\tpreviousAttrs: block.attrs as Record<string, string | number | boolean>,\n\t};\n}\n\n/** Handles direction detection after text insertion. */\nfunction handleInsertText(\n\tstep: Extract<Step, { type: 'insertText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tconst existingText: string = getBlockText(block);\n\tif (getBlockDir(block) !== 'auto' && existingText.length > 0) return;\n\n\tconst textOffset: number = blockOffsetToTextOffset(block, step.offset);\n\tconst textAfter: string =\n\t\texistingText.slice(0, textOffset) + step.text + existingText.slice(textOffset);\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\n/** Handles direction re-detection after text deletion. */\nfunction handleDeleteText(\n\tstep: Extract<Step, { type: 'deleteText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tconst currentDir: TextDirection = getBlockDir(block);\n\tif (currentDir === 'auto') return;\n\n\tconst existingText: string = getBlockText(block);\n\tconst fromText: number = blockOffsetToTextOffset(block, step.from);\n\tconst toText: number = blockOffsetToTextOffset(block, step.to);\n\tconst textAfter: string = existingText.slice(0, fromText) + existingText.slice(toText);\n\n\tif (textAfter.length === 0) {\n\t\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, 'auto');\n\t\tif (dirStep) extraSteps.push(dirStep);\n\t\treturn;\n\t}\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected || detected === currentDir) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\n/**\n * Inherits `dir` from the nearest sibling when inserting a new block\n * (e.g. via GapCursor or NodeSelection).\n */\nexport function registerInheritDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'insertNode') return step;\n\t\t\t\tif (!directableTypes.has(step.node.type)) return step;\n\n\t\t\t\tconst newDir: string = String(step.node.attrs?.dir ?? 'auto');\n\t\t\t\tif (newDir !== 'auto') return step;\n\n\t\t\t\t// Detect direction from inserted node's text content\n\t\t\t\tconst nodeText: string = getBlockText(step.node);\n\t\t\t\tif (nodeText.length > 0) {\n\t\t\t\t\tconst detected: TextDirection | null = detectTextDirection(nodeText);\n\t\t\t\t\tif (detected) {\n\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...step,\n\t\t\t\t\t\t\tnode: {\n\t\t\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: detected },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fall back to sibling direction for empty blocks\n\t\t\t\tconst siblingDir: string | undefined = findSiblingDirection(\n\t\t\t\t\tstate,\n\t\t\t\t\tstep.parentPath,\n\t\t\t\t\tstep.index,\n\t\t\t\t);\n\t\t\t\tif (!siblingDir || siblingDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tnode: {\n\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: siblingDir },\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:inherit-dir' },\n\t);\n}\n","/**\n * TextDirectionPlugin: adds block-level text direction (`dir` attribute)\n * and inline bidi isolation (`<bdi>` mark) for RTL language support.\n *\n * Block-level: patches NodeSpecs for directable types to render the HTML\n * `dir` attribute. Provides `setDirectionLTR`, `setDirectionRTL`, and\n * `setDirectionAuto` commands with a toolbar dropdown.\n *\n * Inline: registers a `bdi` mark for bidi isolation of inline spans,\n * with `toggleBidiLTR`, `toggleBidiRTL`, `toggleBidiAuto`, and\n * `removeBidi` commands.\n */\n\nimport {\n\tapplyAttributedMark,\n\tisAttributedMarkActive,\n\tremoveAttributedMark,\n} from '../../commands/AttributedMarkCommands.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport { isCollapsed, isNodeSelection, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport { isMac } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { getSelectedBlock, resolveLocale } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { getBlockDir } from './DirectionDetection.js';\nimport { ShiftDirectionHandler } from './ShiftDirectionHandler.js';\nimport {\n\tTEXT_DIRECTION_LOCALE_EN,\n\ttype TextDirectionLocale,\n\tloadTextDirectionLocale,\n} from './TextDirectionLocale.js';\nimport {\n\tregisterAutoDetectMiddleware,\n\tregisterInheritDirMiddleware,\n\tregisterPreserveDirMiddleware,\n} from './TextDirectionMiddleware.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tbdi: { dir: 'ltr' | 'rtl' | 'auto' };\n\t}\n}\n\n// --- Public Types ---\n\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\n\nexport interface TextDirectionConfig {\n\t/** Block types that support direction. */\n\treadonly directableTypes: readonly string[];\n\treadonly locale?: TextDirectionLocale;\n}\n\n// --- Constants ---\n\nconst DEFAULT_CONFIG: TextDirectionConfig = {\n\tdirectableTypes: [\n\t\t'paragraph',\n\t\t'heading',\n\t\t'title',\n\t\t'subtitle',\n\t\t'table_cell',\n\t\t'blockquote',\n\t\t'list_item',\n\t],\n};\n\nexport const DIRECTION_ICONS: Readonly<Record<TextDirection, string>> = {\n\tltr: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z\"/></svg>',\n\trtl: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z\"/></svg>',\n\tauto: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z\"/></svg>',\n};\n\nconst ALL_DIRECTIONS: readonly TextDirection[] = ['ltr', 'rtl', 'auto'];\n\nconst INLINE_BDI_ICON: string =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4v7h2V4h2v7h2V4h1V2H10a3 3 0 1 0 0 6zm-3.5 9.5L3 17l3.5 3.5V18h3v-2h-3v-2.5zm14 0L17 17l3.5 3.5V18h-3v-2h3v-2.5zM11 16h2v6h-2z\"/></svg>';\n\n// --- Plugin ---\n\nexport class TextDirectionPlugin implements Plugin {\n\treadonly id = 'text-direction';\n\treadonly name = 'Text Direction';\n\treadonly priority = 91;\n\n\tprivate readonly config: TextDirectionConfig;\n\tprivate locale!: TextDirectionLocale;\n\tprivate directableTypes!: ReadonlySet<string>;\n\tprivate shiftDirHandler: ShiftDirectionHandler | null = null;\n\n\tconstructor(config?: Partial<TextDirectionConfig>) {\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_DIRECTION_LOCALE_EN,\n\t\t\tloadTextDirectionLocale,\n\t\t);\n\n\t\tthis.directableTypes = new Set(this.config.directableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerBdiMark(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\t\tthis.registerInlineToolbarItem(context);\n\t\tregisterPreserveDirMiddleware(context, this.directableTypes);\n\t\tregisterAutoDetectMiddleware(context, this.directableTypes);\n\t\tregisterInheritDirMiddleware(context, this.directableTypes);\n\n\t\t// Ctrl+Shift direction shortcuts (Windows/Linux convention)\n\t\tif (!isMac()) {\n\t\t\tthis.shiftDirHandler = new ShiftDirectionHandler(context);\n\t\t\tthis.shiftDirHandler.attach(context.getContainer());\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.shiftDirHandler?.detach();\n\t\tthis.shiftDirHandler = null;\n\t}\n\n\t// --- NodeSpec Patching ---\n\n\t/**\n\t * Patches existing NodeSpecs for directable block types to support the\n\t * `dir` attribute and render it as an HTML attribute. Skips types\n\t * that already define a `dir` attribute in their spec.\n\t */\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tconst registry = context.getSchemaRegistry();\n\n\t\tfor (const type of this.config.directableTypes) {\n\t\t\tconst spec = registry.getNodeSpec(type);\n\t\t\tif (!spec) continue;\n\n\t\t\tif (spec.attrs?.dir) continue;\n\n\t\t\tconst originalToDOM = spec.toDOM;\n\n\t\t\tregistry.removeNodeSpec(type);\n\t\t\tregistry.registerNodeSpec({\n\t\t\t\t...spec,\n\t\t\t\tattrs: {\n\t\t\t\t\t...spec.attrs,\n\t\t\t\t\tdir: { default: 'auto' },\n\t\t\t\t},\n\t\t\t\ttoDOM(node) {\n\t\t\t\t\tconst el = originalToDOM.call(spec, node);\n\t\t\t\t\tapplyDirection(el, node);\n\t\t\t\t\treturn el;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\t// --- Inline <bdi> Mark ---\n\n\tprivate registerBdiMark(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'bdi',\n\t\t\trank: 10,\n\t\t\tattrs: {\n\t\t\t\tdir: { default: 'auto' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst el: HTMLElement = document.createElement('bdi');\n\t\t\t\tconst dir: string = String(mark.attrs?.dir ?? 'auto');\n\t\t\t\tel.setAttribute('dir', dir);\n\t\t\t\treturn el;\n\t\t\t},\n\t\t\ttoHTMLString: (mark, content) => {\n\t\t\t\tconst dir: string = escapeHTML(String(mark.attrs?.dir ?? 'auto'));\n\t\t\t\treturn `<bdi dir=\"${dir}\">${content}</bdi>`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'bdi',\n\t\t\t\t\tgetAttrs: (el) => {\n\t\t\t\t\t\tconst dir: string | null = el.getAttribute('dir');\n\t\t\t\t\t\tif (dir === 'ltr' || dir === 'rtl') return { dir };\n\t\t\t\t\t\treturn { dir: 'auto' };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['bdi'], attrs: ['dir'] },\n\t\t});\n\t}\n\n\t// --- Commands ---\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('setDirectionLTR', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.announceLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionRTL', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.announceRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionAuto', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.announceAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiLTR', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.inlineLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiRTL', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.inlineRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiAuto', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.inlineAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('removeBidi', () => {\n\t\t\tconst result: boolean = this.removeBdi(context);\n\t\t\tif (result) context.announce(this.locale.announceRemoveBidi);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiIsolation', () => {\n\t\t\treturn this.toggleBidiIsolation(context);\n\t\t});\n\n\t\tcontext.registerCommand('toggleDirection', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst block = getSelectedBlock(state);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\n\t\t\tconst current: TextDirection = getBlockDir(block);\n\t\t\tconst next: TextDirection = current === 'auto' ? 'rtl' : current === 'rtl' ? 'ltr' : 'auto';\n\t\t\treturn this.setDirection(context, next);\n\t\t});\n\t}\n\n\t// --- Keymaps ---\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-D': () => context.executeCommand('toggleDirection'),\n\t\t\t'Mod-Shift-B': () => context.executeCommand('toggleBidiIsolation'),\n\t\t});\n\t}\n\n\t// --- Toolbar ---\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst commandNames: Readonly<Record<TextDirection, string>> = {\n\t\t\tltr: 'setDirectionLTR',\n\t\t\trtl: 'setDirectionRTL',\n\t\t\tauto: 'setDirectionAuto',\n\t\t};\n\n\t\tconst dropdownItems = ALL_DIRECTIONS.map((dir) => ({\n\t\t\tlabel: this.getDirectionLabel(dir),\n\t\t\tcommand: commandNames[dir],\n\t\t\ticon: DIRECTION_ICONS[dir],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-direction',\n\t\t\tgroup: 'block',\n\t\t\ticon: DIRECTION_ICONS.auto,\n\t\t\tlabel: this.locale.toolbarLabel,\n\t\t\ttooltip: `${this.locale.toolbarTooltip} (${formatShortcut('Mod-Shift-D')})`,\n\t\t\tcommand: 'setDirectionAuto',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tisActive: (state) => this.isNonDefaultDirection(state),\n\t\t\tisEnabled: (state) => this.isDirectable(state),\n\t\t\tgetIcon: (state) => {\n\t\t\t\tconst block = getSelectedBlock(state);\n\t\t\t\tif (!block) return DIRECTION_ICONS.auto;\n\t\t\t\tconst dir: TextDirection = getBlockDir(block);\n\t\t\t\treturn DIRECTION_ICONS[dir] ?? DIRECTION_ICONS.auto;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerInlineToolbarItem(context: PluginContext): void {\n\t\tconst inlineItems = [\n\t\t\t{ label: this.locale.inlineLTR, command: 'toggleBidiLTR', icon: DIRECTION_ICONS.ltr },\n\t\t\t{ label: this.locale.inlineRTL, command: 'toggleBidiRTL', icon: DIRECTION_ICONS.rtl },\n\t\t\t{ label: this.locale.inlineAuto, command: 'toggleBidiAuto', icon: DIRECTION_ICONS.auto },\n\t\t\t{ label: this.locale.announceRemoveBidi, command: 'removeBidi' },\n\t\t];\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'inline-direction',\n\t\t\tgroup: 'format',\n\t\t\ticon: INLINE_BDI_ICON,\n\t\t\tlabel: this.locale.inlineLabel,\n\t\t\ttooltip: `${this.locale.inlineTooltip} (${formatShortcut('Mod-Shift-B')})`,\n\t\t\tcommand: 'toggleBidiIsolation',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: inlineItems },\n\t\t\tisActive: (state) => isAttributedMarkActive(state, 'bdi'),\n\t\t\tisEnabled: (state) => {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\treturn isTextSelection(sel) && !isCollapsed(sel);\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate getDirectionLabel(dir: TextDirection): string {\n\t\tif (dir === 'ltr') return this.locale.ltr;\n\t\tif (dir === 'rtl') return this.locale.rtl;\n\t\treturn this.locale.auto;\n\t}\n\n\t// --- Direction Logic ---\n\n\tprivate setDirection(context: PluginContext, direction: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst blockIds: BlockId[] = this.getSelectedBlockIds(state);\n\t\tif (blockIds.length === 0) return false;\n\n\t\tconst tb = state.transaction('command');\n\t\tlet changed = false;\n\n\t\tfor (const id of blockIds) {\n\t\t\tconst block = state.getBlock(id);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) continue;\n\n\t\t\tconst path = state.getNodePath(id);\n\t\t\tif (!path) continue;\n\n\t\t\ttb.setNodeAttr(path, { ...block.attrs, dir: direction });\n\t\t\tchanged = true;\n\t\t}\n\n\t\tif (!changed) return false;\n\n\t\tconst tr = tb.setSelection(state.selection).build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns all block IDs covered by the current selection.\n\t * Only handles TextSelection and NodeSelection — other selection types\n\t * (e.g. GapCursorSelection) return an empty array intentionally, since\n\t * gap cursors sit between blocks and have no associated block content.\n\t */\n\tprivate getSelectedBlockIds(state: EditorState): BlockId[] {\n\t\tconst sel = state.selection;\n\n\t\tif (isNodeSelection(sel)) {\n\t\t\treturn [sel.nodeId];\n\t\t}\n\n\t\tif (!isTextSelection(sel)) return [];\n\n\t\tconst anchorId: BlockId = sel.anchor.blockId;\n\t\tconst headId: BlockId = sel.head.blockId;\n\n\t\tif (anchorId === headId) return [anchorId];\n\n\t\tconst order: readonly BlockId[] = state.getBlockOrder();\n\t\tconst anchorIdx: number = order.indexOf(anchorId);\n\t\tconst headIdx: number = order.indexOf(headId);\n\t\tif (anchorIdx === -1 || headIdx === -1) return [];\n\n\t\tconst from: number = Math.min(anchorIdx, headIdx);\n\t\tconst to: number = Math.max(anchorIdx, headIdx);\n\t\treturn order.slice(from, to + 1) as BlockId[];\n\t}\n\n\tprivate isNonDefaultDirection(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\t\tconst dir = block.attrs?.dir;\n\t\treturn dir != null && dir !== 'auto';\n\t}\n\n\tprivate isDirectable(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\treturn block != null && this.directableTypes.has(block.type);\n\t}\n\n\t// --- Inline bdi mark operations ---\n\n\t/**\n\t * Cycles inline bidi isolation: no-bdi → bdi (opposite of block dir) →\n\t * remove. Applies the opposite direction of the current block for the\n\t * common case (e.g., LTR word in an RTL block gets bdi-ltr).\n\t */\n\tprivate toggleBidiIsolation(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tif (isAttributedMarkActive(state, 'bdi')) {\n\t\t\tconst result: boolean = this.removeBdi(context);\n\t\t\tif (result) context.announce(this.locale.announceRemoveBidi);\n\t\t\treturn result;\n\t\t}\n\t\tconst block = getSelectedBlock(state);\n\t\tconst blockDir: TextDirection = block ? getBlockDir(block) : 'auto';\n\t\tconst bdiDir: TextDirection = blockDir === 'rtl' ? 'ltr' : 'rtl';\n\t\tconst result: boolean = this.applyBdi(context, bdiDir);\n\t\tif (result) {\n\t\t\tconst announcement: string = bdiDir === 'ltr' ? this.locale.inlineLTR : this.locale.inlineRTL;\n\t\t\tcontext.announce(announcement);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate applyBdi(context: PluginContext, dir: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst mark = { type: markType('bdi'), attrs: { dir } };\n\t\tconst tr = applyAttributedMark(state, mark);\n\t\tif (!tr) return false;\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate removeBdi(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst tr = removeAttributedMark(state, markType('bdi'));\n\t\tif (!tr) return false;\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n}\n\n// --- Helpers ---\n\nfunction applyDirection(el: HTMLElement, node: BlockNode): void {\n\tconst dir = node.attrs?.dir;\n\tif (dir === 'ltr' || dir === 'rtl' || dir === 'auto') {\n\t\tel.setAttribute('dir', dir);\n\t}\n}\n"],"names":["buildDirChangeStep","state","block","dir","path","getNodePath","id","type","attrs","previousAttrs","handleInsertText","step","directableTypes","extraSteps","getBlock","blockId","has","existingText","getBlockText","getBlockDir","length","textOffset","blockOffsetToTextOffset","offset","textAfter","slice","text","detected","detectTextDirection","dirStep","push","handleDeleteText","currentDir","fromText","from","toText","to","DEFAULT_CONFIG","DIRECTION_ICONS","ltr","rtl","auto","ALL_DIRECTIONS","TextDirectionPlugin","name","priority","config","locale","shiftDirHandler","constructor","this","init","context","resolveLocale","TEXT_DIRECTION_LOCALE_EN","loadTextDirectionLocale","Set","patchNodeSpecs","registerBdiMark","registerCommands","registerKeymaps","registerToolbarItem","registerInlineToolbarItem","registerMiddleware","tr","_state","next","patched","patchedSteps","steps","map","nodeType","prevDir","registerPreserveDirMiddleware","registerAutoDetectMiddleware","node","String","nodeText","siblingDir","findSiblingDirection","parentPath","index","registerInheritDirMiddleware","isMac","ShiftDirectionHandler","attach","getContainer","destroy","detach","registry","getSchemaRegistry","spec","getNodeSpec","originalToDOM","toDOM","removeNodeSpec","registerNodeSpec","default","el","call","applyDirection","registerMarkSpec","rank","mark","document","createElement","setAttribute","toHTMLString","content","escapeHTML","parseHTML","tag","getAttrs","getAttribute","sanitize","tags","registerCommand","result","setDirection","announce","announceLTR","announceRTL","announceAuto","applyBdi","inlineLTR","inlineRTL","inlineAuto","removeBdi","announceRemoveBidi","toggleBidiIsolation","getState","getSelectedBlock","current","registerKeymap","executeCommand","commandNames","dropdownItems","label","getDirectionLabel","command","icon","group","toolbarLabel","tooltip","toolbarTooltip","formatShortcut","popupType","popupConfig","items","isActive","isNonDefaultDirection","isEnabled","isDirectable","getIcon","inlineItems","inlineLabel","inlineTooltip","isAttributedMarkActive","sel","selection","isTextSelection","isCollapsed","direction","blockIds","getSelectedBlockIds","tb","transaction","changed","setNodeAttr","setSelection","build","dispatch","isNodeSelection","nodeId","anchorId","anchor","headId","head","order","getBlockOrder","anchorIdx","indexOf","headIdx","Math","min","max","bdiDir","announcement","markType","applyAttributedMark","removeAttributedMark"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{h as t,j as e}from"../chunks/Selection-DhbizDM4.mjs";import{a as i}from"../chunks/Platform-CU6itXZo.mjs";import{r as o,g as r}from"../chunks/PluginHelpers-CdPR0MuT.mjs";import{f as s}from"../chunks/ShortcutFormatting-BLKS0Gys.mjs";import{S as n,g as c,l as a,T as l}from"../chunks/TextDirectionLocale-CKz0ZrH_.mjs";import{d as h,f as u}from"../chunks/TextDirectionLocale-CKz0ZrH_.mjs";const d={directableTypes:["paragraph","heading","title","subtitle","table_cell","blockquote","list_item"]},m={ltr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z"/></svg>',rtl:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z"/></svg>',auto:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z"/></svg>'},g=["ltr","rtl","auto"];class p{id="text-direction";name="Text Direction";priority=91;config;locale;directableTypes;shiftDirHandler=null;constructor(t){this.config={...d,...t}}async init(t){this.locale=await o(t,this.config.locale,l,a),this.directableTypes=new Set(this.config.directableTypes),this.patchNodeSpecs(t),this.registerCommands(t),this.registerKeymaps(t),this.registerToolbarItem(t),i()||(this.shiftDirHandler=new n(t),this.shiftDirHandler.attach(t.getContainer()))}destroy(){this.shiftDirHandler?.detach(),this.shiftDirHandler=null}patchNodeSpecs(t){const e=t.getSchemaRegistry();for(const i of this.config.directableTypes){const t=e.getNodeSpec(i);if(!t)continue;if(t.attrs?.dir)continue;const o=t.toDOM;e.removeNodeSpec(i),e.registerNodeSpec({...t,attrs:{...t.attrs,dir:{default:"auto"}},toDOM(e){const i=o.call(t,e);return f(i,e),i}})}}registerCommands(t){t.registerCommand("setDirectionLTR",()=>{const e=this.setDirection(t,"ltr");return e&&t.announce(this.locale.announceLTR),e}),t.registerCommand("setDirectionRTL",()=>{const e=this.setDirection(t,"rtl");return e&&t.announce(this.locale.announceRTL),e}),t.registerCommand("setDirectionAuto",()=>{const e=this.setDirection(t,"auto");return e&&t.announce(this.locale.announceAuto),e}),t.registerCommand("toggleDirection",()=>{const e=t.getState(),i=r(e);if(!i||!this.directableTypes.has(i.type))return!1;const o=c(i),s="auto"===o?"rtl":"rtl"===o?"ltr":"auto";return this.setDirection(t,s)})}registerKeymaps(t){t.registerKeymap({"Mod-Shift-D":()=>t.executeCommand("toggleDirection")})}registerToolbarItem(t){const e={ltr:"setDirectionLTR",rtl:"setDirectionRTL",auto:"setDirectionAuto"},i=g.map(t=>({label:this.getDirectionLabel(t),command:e[t],icon:m[t]}));t.registerToolbarItem({id:"text-direction",group:"block",icon:m.auto,label:this.locale.toolbarLabel,tooltip:`${this.locale.toolbarTooltip} (${s("Mod-Shift-D")})`,command:"setDirectionAuto",popupType:"dropdown",popupConfig:{items:i},isActive:t=>this.isNonDefaultDirection(t),isEnabled:t=>this.isDirectable(t),getIcon:t=>{const e=r(t);if(!e)return m.auto;const i=c(e);return m[i]??m.auto}})}getDirectionLabel(t){return"ltr"===t?this.locale.ltr:"rtl"===t?this.locale.rtl:this.locale.auto}setDirection(t,e){const i=t.getState(),o=this.getSelectedBlockIds(i);if(0===o.length)return!1;const r=i.transaction("command");let s=!1;for(const c of o){const t=i.getBlock(c);if(!t||!this.directableTypes.has(t.type))continue;const o=i.getNodePath(c);o&&(r.setNodeAttr(o,{...t.attrs,dir:e}),s=!0)}if(!s)return!1;const n=r.setSelection(i.selection).build();return t.dispatch(n),!0}getSelectedBlockIds(i){const o=i.selection;if(t(o))return[o.nodeId];if(!e(o))return[];const r=o.anchor.blockId,s=o.head.blockId;if(r===s)return[r];const n=i.getBlockOrder(),c=n.indexOf(r),a=n.indexOf(s);if(-1===c||-1===a)return[];const l=Math.min(c,a),h=Math.max(c,a);return n.slice(l,h+1)}isNonDefaultDirection(t){const e=r(t);if(!e||!this.directableTypes.has(e.type))return!1;const i=e.attrs?.dir;return null!=i&&"auto"!==i}isDirectable(t){const e=r(t);return null!=e&&this.directableTypes.has(e.type)}}function f(t,e){const i=e.attrs?.dir;"ltr"!==i&&"rtl"!==i&&"auto"!==i||t.setAttribute("dir",i)}export{m as DIRECTION_ICONS,l as TEXT_DIRECTION_LOCALE_EN,p as TextDirectionPlugin,h as detectTextDirection,u as findSiblingDirection,c as getBlockDir,a as loadTextDirectionLocale};
|
|
2
2
|
//# sourceMappingURL=text-direction.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-direction.mjs","sources":["../../src/plugins/text-direction/TextDirectionCorePlugin.ts"],"sourcesContent":["import { LocaleServiceKey } from '../../i18n/LocaleService.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport { isNodeSelection, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { isMac } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { getSelectedBlock } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { getBlockDir } from './DirectionDetection.js';\nimport { ShiftDirectionHandler } from './ShiftDirectionHandler.js';\nimport {\n\tTEXT_DIRECTION_LOCALE_EN,\n\ttype TextDirectionLocale,\n\tloadTextDirectionLocale,\n} from './TextDirectionLocale.js';\n\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\n\nexport interface TextDirectionConfig {\n\t/** Block types that support direction. */\n\treadonly directableTypes: readonly string[];\n\treadonly locale?: TextDirectionLocale;\n}\n\nconst DEFAULT_CONFIG: TextDirectionConfig = {\n\tdirectableTypes: [\n\t\t'paragraph',\n\t\t'heading',\n\t\t'title',\n\t\t'subtitle',\n\t\t'table_cell',\n\t\t'blockquote',\n\t\t'list_item',\n\t],\n};\n\nexport const DIRECTION_ICONS: Readonly<Record<TextDirection, string>> = {\n\tltr: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z\"/></svg>',\n\trtl: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z\"/></svg>',\n\tauto: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z\"/></svg>',\n};\n\nconst ALL_DIRECTIONS: readonly TextDirection[] = ['ltr', 'rtl', 'auto'];\n\n/**\n * Lean text-direction plugin.\n * Includes block-level direction controls and toolbar integration only.\n */\nexport class TextDirectionCorePlugin implements Plugin {\n\treadonly id = 'text-direction';\n\treadonly name = 'Text Direction';\n\treadonly priority = 91;\n\n\tprivate readonly config: TextDirectionConfig;\n\tprivate locale!: TextDirectionLocale;\n\tprivate directableTypes!: ReadonlySet<string>;\n\tprivate shiftDirHandler: ShiftDirectionHandler | null = null;\n\n\tconstructor(config?: Partial<TextDirectionConfig>) {\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 = lang === 'en' ? TEXT_DIRECTION_LOCALE_EN : await loadTextDirectionLocale(lang);\n\t\t}\n\n\t\tthis.directableTypes = new Set(this.config.directableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\n\t\t// Ctrl+Shift direction shortcuts (Windows/Linux convention)\n\t\tif (!isMac()) {\n\t\t\tthis.shiftDirHandler = new ShiftDirectionHandler(context);\n\t\t\tthis.shiftDirHandler.attach(context.getContainer());\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.shiftDirHandler?.detach();\n\t\tthis.shiftDirHandler = null;\n\t}\n\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tconst registry = context.getSchemaRegistry();\n\n\t\tfor (const type of this.config.directableTypes) {\n\t\t\tconst spec = registry.getNodeSpec(type);\n\t\t\tif (!spec) continue;\n\n\t\t\tif (spec.attrs?.dir) continue;\n\n\t\t\tconst originalToDOM = spec.toDOM;\n\n\t\t\tregistry.removeNodeSpec(type);\n\t\t\tregistry.registerNodeSpec({\n\t\t\t\t...spec,\n\t\t\t\tattrs: {\n\t\t\t\t\t...spec.attrs,\n\t\t\t\t\tdir: { default: 'auto' },\n\t\t\t\t},\n\t\t\t\ttoDOM(node) {\n\t\t\t\t\tconst el = originalToDOM.call(spec, node);\n\t\t\t\t\tapplyDirection(el, node);\n\t\t\t\t\treturn el;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('setDirectionLTR', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.announceLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionRTL', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.announceRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionAuto', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.announceAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleDirection', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst block = getSelectedBlock(state);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\n\t\t\tconst current: TextDirection = getBlockDir(block);\n\t\t\tconst next: TextDirection = current === 'auto' ? 'rtl' : current === 'rtl' ? 'ltr' : 'auto';\n\t\t\treturn this.setDirection(context, next);\n\t\t});\n\t}\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-D': () => context.executeCommand('toggleDirection'),\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst commandNames: Readonly<Record<TextDirection, string>> = {\n\t\t\tltr: 'setDirectionLTR',\n\t\t\trtl: 'setDirectionRTL',\n\t\t\tauto: 'setDirectionAuto',\n\t\t};\n\n\t\tconst dropdownItems = ALL_DIRECTIONS.map((dir) => ({\n\t\t\tlabel: this.getDirectionLabel(dir),\n\t\t\tcommand: commandNames[dir],\n\t\t\ticon: DIRECTION_ICONS[dir],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-direction',\n\t\t\tgroup: 'block',\n\t\t\ticon: DIRECTION_ICONS.auto,\n\t\t\tlabel: this.locale.toolbarLabel,\n\t\t\ttooltip: `${this.locale.toolbarTooltip} (${formatShortcut('Mod-Shift-D')})`,\n\t\t\tcommand: 'setDirectionAuto',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tisActive: (state) => this.isNonDefaultDirection(state),\n\t\t\tisEnabled: (state) => this.isDirectable(state),\n\t\t\tgetIcon: (state) => {\n\t\t\t\tconst block = getSelectedBlock(state);\n\t\t\t\tif (!block) return DIRECTION_ICONS.auto;\n\t\t\t\tconst dir: TextDirection = getBlockDir(block);\n\t\t\t\treturn DIRECTION_ICONS[dir] ?? DIRECTION_ICONS.auto;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate getDirectionLabel(dir: TextDirection): string {\n\t\tif (dir === 'ltr') return this.locale.ltr;\n\t\tif (dir === 'rtl') return this.locale.rtl;\n\t\treturn this.locale.auto;\n\t}\n\n\tprivate setDirection(context: PluginContext, direction: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst blockIds: BlockId[] = this.getSelectedBlockIds(state);\n\t\tif (blockIds.length === 0) return false;\n\n\t\tconst tb = state.transaction('command');\n\t\tlet changed = false;\n\n\t\tfor (const id of blockIds) {\n\t\t\tconst block = state.getBlock(id);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) continue;\n\n\t\t\tconst path = state.getNodePath(id);\n\t\t\tif (!path) continue;\n\n\t\t\ttb.setNodeAttr(path, { ...block.attrs, dir: direction });\n\t\t\tchanged = true;\n\t\t}\n\n\t\tif (!changed) return false;\n\n\t\tconst tr = tb.setSelection(state.selection).build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate getSelectedBlockIds(state: EditorState): BlockId[] {\n\t\tconst sel = state.selection;\n\n\t\tif (isNodeSelection(sel)) {\n\t\t\treturn [sel.nodeId];\n\t\t}\n\n\t\tif (!isTextSelection(sel)) return [];\n\n\t\tconst anchorId: BlockId = sel.anchor.blockId;\n\t\tconst headId: BlockId = sel.head.blockId;\n\n\t\tif (anchorId === headId) return [anchorId];\n\n\t\tconst order: readonly BlockId[] = state.getBlockOrder();\n\t\tconst anchorIdx: number = order.indexOf(anchorId);\n\t\tconst headIdx: number = order.indexOf(headId);\n\t\tif (anchorIdx === -1 || headIdx === -1) return [];\n\n\t\tconst from: number = Math.min(anchorIdx, headIdx);\n\t\tconst to: number = Math.max(anchorIdx, headIdx);\n\t\treturn order.slice(from, to + 1) as BlockId[];\n\t}\n\n\tprivate isNonDefaultDirection(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\t\tconst dir = block.attrs?.dir;\n\t\treturn dir != null && dir !== 'auto';\n\t}\n\n\tprivate isDirectable(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\treturn block != null && this.directableTypes.has(block.type);\n\t}\n}\n\nfunction applyDirection(el: HTMLElement, node: BlockNode): void {\n\tconst dir = node.attrs?.dir;\n\tif (dir === 'ltr' || dir === 'rtl' || dir === 'auto') {\n\t\tel.setAttribute('dir', dir);\n\t}\n}\n"],"names":["DEFAULT_CONFIG","directableTypes","DIRECTION_ICONS","ltr","rtl","auto","ALL_DIRECTIONS","TextDirectionCorePlugin","id","name","priority","config","locale","shiftDirHandler","constructor","this","init","context","service","getService","LocaleServiceKey","lang","getLocale","TEXT_DIRECTION_LOCALE_EN","loadTextDirectionLocale","Set","patchNodeSpecs","registerCommands","registerKeymaps","registerToolbarItem","isMac","ShiftDirectionHandler","attach","getContainer","destroy","detach","registry","getSchemaRegistry","type","spec","getNodeSpec","attrs","dir","originalToDOM","toDOM","removeNodeSpec","registerNodeSpec","default","node","el","call","applyDirection","registerCommand","result","setDirection","announce","announceLTR","announceRTL","announceAuto","state","getState","block","getSelectedBlock","has","current","getBlockDir","next","registerKeymap","executeCommand","commandNames","dropdownItems","map","label","getDirectionLabel","command","icon","group","toolbarLabel","tooltip","toolbarTooltip","formatShortcut","popupType","popupConfig","items","isActive","isNonDefaultDirection","isEnabled","isDirectable","getIcon","direction","blockIds","getSelectedBlockIds","length","tb","transaction","changed","getBlock","path","getNodePath","setNodeAttr","tr","setSelection","selection","build","dispatch","sel","isNodeSelection","nodeId","isTextSelection","anchorId","anchor","blockId","headId","head","order","getBlockOrder","anchorIdx","indexOf","headIdx","from","Math","min","to","max","slice","setAttribute"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"text-direction.mjs","sources":["../../src/plugins/text-direction/TextDirectionCorePlugin.ts"],"sourcesContent":["import type { BlockNode } from '../../model/Document.js';\nimport { isNodeSelection, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { isMac } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { getSelectedBlock, resolveLocale } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { getBlockDir } from './DirectionDetection.js';\nimport { ShiftDirectionHandler } from './ShiftDirectionHandler.js';\nimport {\n\tTEXT_DIRECTION_LOCALE_EN,\n\ttype TextDirectionLocale,\n\tloadTextDirectionLocale,\n} from './TextDirectionLocale.js';\n\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\n\nexport interface TextDirectionConfig {\n\t/** Block types that support direction. */\n\treadonly directableTypes: readonly string[];\n\treadonly locale?: TextDirectionLocale;\n}\n\nconst DEFAULT_CONFIG: TextDirectionConfig = {\n\tdirectableTypes: [\n\t\t'paragraph',\n\t\t'heading',\n\t\t'title',\n\t\t'subtitle',\n\t\t'table_cell',\n\t\t'blockquote',\n\t\t'list_item',\n\t],\n};\n\nexport const DIRECTION_ICONS: Readonly<Record<TextDirection, string>> = {\n\tltr: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z\"/></svg>',\n\trtl: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z\"/></svg>',\n\tauto: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z\"/></svg>',\n};\n\nconst ALL_DIRECTIONS: readonly TextDirection[] = ['ltr', 'rtl', 'auto'];\n\n/**\n * Lean text-direction plugin.\n * Includes block-level direction controls and toolbar integration only.\n */\nexport class TextDirectionCorePlugin implements Plugin {\n\treadonly id = 'text-direction';\n\treadonly name = 'Text Direction';\n\treadonly priority = 91;\n\n\tprivate readonly config: TextDirectionConfig;\n\tprivate locale!: TextDirectionLocale;\n\tprivate directableTypes!: ReadonlySet<string>;\n\tprivate shiftDirHandler: ShiftDirectionHandler | null = null;\n\n\tconstructor(config?: Partial<TextDirectionConfig>) {\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_DIRECTION_LOCALE_EN,\n\t\t\tloadTextDirectionLocale,\n\t\t);\n\n\t\tthis.directableTypes = new Set(this.config.directableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\n\t\t// Ctrl+Shift direction shortcuts (Windows/Linux convention)\n\t\tif (!isMac()) {\n\t\t\tthis.shiftDirHandler = new ShiftDirectionHandler(context);\n\t\t\tthis.shiftDirHandler.attach(context.getContainer());\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.shiftDirHandler?.detach();\n\t\tthis.shiftDirHandler = null;\n\t}\n\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tconst registry = context.getSchemaRegistry();\n\n\t\tfor (const type of this.config.directableTypes) {\n\t\t\tconst spec = registry.getNodeSpec(type);\n\t\t\tif (!spec) continue;\n\n\t\t\tif (spec.attrs?.dir) continue;\n\n\t\t\tconst originalToDOM = spec.toDOM;\n\n\t\t\tregistry.removeNodeSpec(type);\n\t\t\tregistry.registerNodeSpec({\n\t\t\t\t...spec,\n\t\t\t\tattrs: {\n\t\t\t\t\t...spec.attrs,\n\t\t\t\t\tdir: { default: 'auto' },\n\t\t\t\t},\n\t\t\t\ttoDOM(node) {\n\t\t\t\t\tconst el = originalToDOM.call(spec, node);\n\t\t\t\t\tapplyDirection(el, node);\n\t\t\t\t\treturn el;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('setDirectionLTR', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.announceLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionRTL', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.announceRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionAuto', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.announceAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleDirection', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst block = getSelectedBlock(state);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\n\t\t\tconst current: TextDirection = getBlockDir(block);\n\t\t\tconst next: TextDirection = current === 'auto' ? 'rtl' : current === 'rtl' ? 'ltr' : 'auto';\n\t\t\treturn this.setDirection(context, next);\n\t\t});\n\t}\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-D': () => context.executeCommand('toggleDirection'),\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst commandNames: Readonly<Record<TextDirection, string>> = {\n\t\t\tltr: 'setDirectionLTR',\n\t\t\trtl: 'setDirectionRTL',\n\t\t\tauto: 'setDirectionAuto',\n\t\t};\n\n\t\tconst dropdownItems = ALL_DIRECTIONS.map((dir) => ({\n\t\t\tlabel: this.getDirectionLabel(dir),\n\t\t\tcommand: commandNames[dir],\n\t\t\ticon: DIRECTION_ICONS[dir],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-direction',\n\t\t\tgroup: 'block',\n\t\t\ticon: DIRECTION_ICONS.auto,\n\t\t\tlabel: this.locale.toolbarLabel,\n\t\t\ttooltip: `${this.locale.toolbarTooltip} (${formatShortcut('Mod-Shift-D')})`,\n\t\t\tcommand: 'setDirectionAuto',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tisActive: (state) => this.isNonDefaultDirection(state),\n\t\t\tisEnabled: (state) => this.isDirectable(state),\n\t\t\tgetIcon: (state) => {\n\t\t\t\tconst block = getSelectedBlock(state);\n\t\t\t\tif (!block) return DIRECTION_ICONS.auto;\n\t\t\t\tconst dir: TextDirection = getBlockDir(block);\n\t\t\t\treturn DIRECTION_ICONS[dir] ?? DIRECTION_ICONS.auto;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate getDirectionLabel(dir: TextDirection): string {\n\t\tif (dir === 'ltr') return this.locale.ltr;\n\t\tif (dir === 'rtl') return this.locale.rtl;\n\t\treturn this.locale.auto;\n\t}\n\n\tprivate setDirection(context: PluginContext, direction: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst blockIds: BlockId[] = this.getSelectedBlockIds(state);\n\t\tif (blockIds.length === 0) return false;\n\n\t\tconst tb = state.transaction('command');\n\t\tlet changed = false;\n\n\t\tfor (const id of blockIds) {\n\t\t\tconst block = state.getBlock(id);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) continue;\n\n\t\t\tconst path = state.getNodePath(id);\n\t\t\tif (!path) continue;\n\n\t\t\ttb.setNodeAttr(path, { ...block.attrs, dir: direction });\n\t\t\tchanged = true;\n\t\t}\n\n\t\tif (!changed) return false;\n\n\t\tconst tr = tb.setSelection(state.selection).build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate getSelectedBlockIds(state: EditorState): BlockId[] {\n\t\tconst sel = state.selection;\n\n\t\tif (isNodeSelection(sel)) {\n\t\t\treturn [sel.nodeId];\n\t\t}\n\n\t\tif (!isTextSelection(sel)) return [];\n\n\t\tconst anchorId: BlockId = sel.anchor.blockId;\n\t\tconst headId: BlockId = sel.head.blockId;\n\n\t\tif (anchorId === headId) return [anchorId];\n\n\t\tconst order: readonly BlockId[] = state.getBlockOrder();\n\t\tconst anchorIdx: number = order.indexOf(anchorId);\n\t\tconst headIdx: number = order.indexOf(headId);\n\t\tif (anchorIdx === -1 || headIdx === -1) return [];\n\n\t\tconst from: number = Math.min(anchorIdx, headIdx);\n\t\tconst to: number = Math.max(anchorIdx, headIdx);\n\t\treturn order.slice(from, to + 1) as BlockId[];\n\t}\n\n\tprivate isNonDefaultDirection(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\t\tconst dir = block.attrs?.dir;\n\t\treturn dir != null && dir !== 'auto';\n\t}\n\n\tprivate isDirectable(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\treturn block != null && this.directableTypes.has(block.type);\n\t}\n}\n\nfunction applyDirection(el: HTMLElement, node: BlockNode): void {\n\tconst dir = node.attrs?.dir;\n\tif (dir === 'ltr' || dir === 'rtl' || dir === 'auto') {\n\t\tel.setAttribute('dir', dir);\n\t}\n}\n"],"names":["DEFAULT_CONFIG","directableTypes","DIRECTION_ICONS","ltr","rtl","auto","ALL_DIRECTIONS","TextDirectionCorePlugin","id","name","priority","config","locale","shiftDirHandler","constructor","this","init","context","resolveLocale","TEXT_DIRECTION_LOCALE_EN","loadTextDirectionLocale","Set","patchNodeSpecs","registerCommands","registerKeymaps","registerToolbarItem","isMac","ShiftDirectionHandler","attach","getContainer","destroy","detach","registry","getSchemaRegistry","type","spec","getNodeSpec","attrs","dir","originalToDOM","toDOM","removeNodeSpec","registerNodeSpec","default","node","el","call","applyDirection","registerCommand","result","setDirection","announce","announceLTR","announceRTL","announceAuto","state","getState","block","getSelectedBlock","has","current","getBlockDir","next","registerKeymap","executeCommand","commandNames","dropdownItems","map","label","getDirectionLabel","command","icon","group","toolbarLabel","tooltip","toolbarTooltip","formatShortcut","popupType","popupConfig","items","isActive","isNonDefaultDirection","isEnabled","isDirectable","getIcon","direction","blockIds","getSelectedBlockIds","length","tb","transaction","changed","getBlock","path","getNodePath","setNodeAttr","tr","setSelection","selection","build","dispatch","sel","isNodeSelection","nodeId","isTextSelection","anchorId","anchor","blockId","headId","head","order","getBlockOrder","anchorIdx","indexOf","headIdx","from","Math","min","to","max","slice","setAttribute"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextFormattingPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-formatting/TextFormattingPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;
|
|
1
|
+
{"version":3,"file":"TextFormattingPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-formatting/TextFormattingPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,EAEN,KAAK,oBAAoB,EAEzB,MAAM,2BAA2B,CAAC;AAInC,mDAAmD;AACnD,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,2BAA2B,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC;CACvC;AAuGD,qBAAa,oBAAqB,YAAW,MAAM;IAClD,QAAQ,CAAC,EAAE,qBAAqB;IAChC,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,MAAM,CAAwB;gBAE1B,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAI5C,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjD,OAAO,CAAC,YAAY;IAsCpB,OAAO,CAAC,eAAe;IAWvB;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAoBpC,OAAO,CAAC,YAAY;IAKpB,qEAAqE;IACrE,OAAO,CAAC,gBAAgB;CAMxB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{m as t}from"../chunks/TypeBrands-Bp_Z_o5Y.mjs";import{r as e,t as s}from"../chunks/PluginHelpers-CdPR0MuT.mjs";import{f as i}from"../chunks/ShortcutFormatting-BLKS0Gys.mjs";import{c as o,i as r}from"../chunks/MarkCommands-CeCa4WSC.mjs";const n={boldLabel:"Bold",italicLabel:"Italic",underlineLabel:"Underline"},a=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("../chunks/ar-BYNFEVLc.mjs"),"./locales/de.ts":()=>import("../chunks/de-CFD_Wgik.mjs"),"./locales/es.ts":()=>import("../chunks/es-Ce-AEYxc.mjs"),"./locales/fr.ts":()=>import("../chunks/fr-B-_yKIAY.mjs"),"./locales/hi.ts":()=>import("../chunks/hi-BMIt3y_-.mjs"),"./locales/pt.ts":()=>import("../chunks/pt-Dx9UkZ3j.mjs"),"./locales/ru.ts":()=>import("../chunks/ru-BCriPw-8.mjs"),"./locales/zh.ts":()=>import("../chunks/zh-CY01pMD4.mjs")});async function c(t){if("en"===t)return n;const e=a[`./locales/${t}.ts`];if(!e)return n;try{return(await e()).default}catch{return n}}const l={bold:!0,italic:!0,underline:!0},g=[{type:"bold",configKey:"bold",rank:0,tag:"strong",icon:'<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>',keyBinding:"Mod-B",toHTMLString:t=>`<strong>${t}</strong>`,parseHTML:[{tag:"strong"},{tag:"b",getAttrs:t=>{const e=t.style.fontWeight;return"normal"!==e&&"400"!==e&&{}}},{tag:"span",getAttrs:t=>{const e=t.style.fontWeight;if(!e)return!1;if("bold"===e)return{};const s=Number.parseInt(e,10);return!Number.isNaN(s)&&s>=700&&{}}}],sanitize:{tags:["strong","b"]}},{type:"italic",configKey:"italic",rank:1,tag:"em",icon:'<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>',keyBinding:"Mod-I",toHTMLString:t=>`<em>${t}</em>`,parseHTML:[{tag:"em"},{tag:"i"},{tag:"span",getAttrs:t=>"italic"===t.style.fontStyle&&{}}],sanitize:{tags:["em","i"]}},{type:"underline",configKey:"underline",rank:2,tag:"u",icon:'<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>',keyBinding:"Mod-U",toHTMLString:t=>`<u>${t}</u>`,parseHTML:[{tag:"u"},{tag:"span",getAttrs:t=>!!t.style.textDecoration.includes("underline")&&{}}],sanitize:{tags:["u"]}}];class m{id="text-formatting";name="Text Formatting";priority=20;config;locale;constructor(t){this.config={...l,...t}}async init(t){this.locale=await e(t,this.config.locale,n,c);const s=g.filter(t=>this.config[t.configKey]);for(const e of s)this.registerMark(t,e);this.registerKeymaps(t,s),this.registerDisabledToolbarItems(t)}registerMark(e,n){const a=s(n.type),c=this.isToolbarVisible(n.configKey);if(e.registerMarkSpec({type:n.type,rank:n.rank,toDOM:()=>document.createElement(n.tag),toHTMLString:(t,e)=>n.toHTMLString(e),parseHTML:n.parseHTML,sanitize:n.sanitize}),e.registerCommand(a,()=>{const s=o(e.getState(),t(n.type));return!!s&&(e.dispatch(s),!0)}),c){const s=this.getMarkLabel(n.type);e.registerToolbarItem({id:n.type,group:"format",icon:n.icon,label:s,tooltip:`${s} (${i(n.keyBinding)})`,command:a,isActive:e=>r(e,t(n.type))})}}registerKeymaps(t,e){const i={};for(const o of e){const e=s(o.type);i[o.keyBinding]=()=>t.executeCommand(e)}Object.keys(i).length>0&&t.registerKeymap(i)}registerDisabledToolbarItems(t){if(this.config.toolbar)for(const e of g){const i=this.config[e.configKey],o=this.config.toolbar[e.configKey]??!0;!i&&o&&t.registerToolbarItem({id:e.type,group:"format",icon:e.icon,label:this.getMarkLabel(e.type),command:s(e.type),isEnabled:()=>!1})}}getMarkLabel(t){const e=`${t}Label`;return this.locale[e]}isToolbarVisible(t){return!this.config.toolbar||(this.config.toolbar[t]??!0)}}export{n as TEXT_FORMATTING_LOCALE_EN,m as TextFormattingPlugin,c as loadTextFormattingLocale};
|
|
2
2
|
//# sourceMappingURL=text-formatting.mjs.map
|