@notectl/core 2.1.2 → 2.2.1
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/dist/chunks/AlignmentPlugin-BLzRjrUl.mjs +2 -0
- package/dist/chunks/AlignmentPlugin-BLzRjrUl.mjs.map +1 -0
- package/dist/chunks/AttrRegistry-CRnXTPha.mjs +2 -0
- package/dist/chunks/AttrRegistry-CRnXTPha.mjs.map +1 -0
- package/dist/chunks/AttributedMarkCommands-CxhdUsuE.mjs +2 -0
- package/dist/chunks/AttributedMarkCommands-CxhdUsuE.mjs.map +1 -0
- package/dist/chunks/BidiIsolationPlugin-DNPXe5ga.mjs +2 -0
- package/dist/chunks/BidiIsolationPlugin-DNPXe5ga.mjs.map +1 -0
- package/dist/chunks/BlockInsertion-C7jFEeYB.mjs +2 -0
- package/dist/chunks/BlockInsertion-C7jFEeYB.mjs.map +1 -0
- package/dist/chunks/BlockTypePickerRegistry-U4uY7-lN.mjs +2 -0
- package/dist/chunks/BlockTypePickerRegistry-U4uY7-lN.mjs.map +1 -0
- package/dist/chunks/BlockquotePlugin-YgXcV4mT.mjs +2 -0
- package/dist/chunks/BlockquotePlugin-YgXcV4mT.mjs.map +1 -0
- package/dist/chunks/CaretNavigationPlugin-P6OYaTSq.mjs +2 -0
- package/dist/chunks/CaretNavigationPlugin-P6OYaTSq.mjs.map +1 -0
- package/dist/chunks/CodeBlockPlugin-ChPv3Edf.mjs +2 -0
- package/dist/chunks/CodeBlockPlugin-ChPv3Edf.mjs.map +1 -0
- package/dist/chunks/ColorGrid-D5-teEjD.mjs +2 -0
- package/dist/chunks/ColorGrid-D5-teEjD.mjs.map +1 -0
- package/dist/chunks/ColorPickerPopup-_Gp09pdx.mjs +2 -0
- package/dist/chunks/ColorPickerPopup-_Gp09pdx.mjs.map +1 -0
- package/dist/chunks/ColorValidation-okAvytHQ.mjs +2 -0
- package/dist/chunks/ColorValidation-okAvytHQ.mjs.map +1 -0
- package/dist/chunks/CommandHelpers-NV80Ff1G.mjs +2 -0
- package/dist/chunks/CommandHelpers-NV80Ff1G.mjs.map +1 -0
- package/dist/chunks/Commands-ixGhPiRG.mjs +2 -0
- package/dist/chunks/Commands-ixGhPiRG.mjs.map +1 -0
- package/dist/chunks/Decoration-DZK7hrL1.mjs +2 -0
- package/dist/chunks/Decoration-DZK7hrL1.mjs.map +1 -0
- package/dist/chunks/DirectionDetection-7HmMUZrx.mjs +2 -0
- package/dist/chunks/DirectionDetection-7HmMUZrx.mjs.map +1 -0
- package/dist/chunks/DirectionIcons-DhRvPVoz.mjs +2 -0
- package/dist/chunks/DirectionIcons-DhRvPVoz.mjs.map +1 -0
- package/dist/chunks/Document-znhIcvM9.mjs +2 -0
- package/dist/chunks/Document-znhIcvM9.mjs.map +1 -0
- package/dist/chunks/DocumentParser-DCjOW3us.mjs +2 -0
- package/dist/chunks/DocumentParser-DCjOW3us.mjs.map +1 -0
- package/dist/chunks/FontPlugin-COYtG1Uo.mjs +2 -0
- package/dist/chunks/FontPlugin-COYtG1Uo.mjs.map +1 -0
- package/dist/chunks/FontSizePlugin-CLcfdTm3.mjs +2 -0
- package/dist/chunks/FontSizePlugin-CLcfdTm3.mjs.map +1 -0
- package/dist/chunks/FormulaPlugin-DphHU4Rn.mjs +2 -0
- package/dist/chunks/FormulaPlugin-DphHU4Rn.mjs.map +1 -0
- package/dist/chunks/GapCursorNavigation-Bkuu_Ek8.mjs +2 -0
- package/dist/chunks/GapCursorNavigation-Bkuu_Ek8.mjs.map +1 -0
- package/dist/chunks/GapCursorPlugin-CRDmQEi1.mjs +2 -0
- package/dist/chunks/GapCursorPlugin-CRDmQEi1.mjs.map +1 -0
- package/dist/chunks/HardBreakPlugin-Cr6dMQ-H.mjs +2 -0
- package/dist/chunks/HardBreakPlugin-Cr6dMQ-H.mjs.map +1 -0
- package/dist/chunks/HeadingPlugin-3NL4ARPp.mjs +2 -0
- package/dist/chunks/HeadingPlugin-3NL4ARPp.mjs.map +1 -0
- package/dist/chunks/HighlightPlugin-dHxnAuoW.mjs +2 -0
- package/dist/chunks/HighlightPlugin-dHxnAuoW.mjs.map +1 -0
- package/dist/chunks/HorizontalRulePlugin-BYPaI4TR.mjs +2 -0
- package/dist/chunks/HorizontalRulePlugin-BYPaI4TR.mjs.map +1 -0
- package/dist/chunks/ImagePlugin-kgokm-a1.mjs +2 -0
- package/dist/chunks/ImagePlugin-kgokm-a1.mjs.map +1 -0
- package/dist/chunks/InlineCodePlugin-Bl1jyDwk.mjs +2 -0
- package/dist/chunks/InlineCodePlugin-Bl1jyDwk.mjs.map +1 -0
- package/dist/chunks/InlineStyleMarkSpec-Cc-b1tlm.mjs +2 -0
- package/dist/chunks/InlineStyleMarkSpec-Cc-b1tlm.mjs.map +1 -0
- package/dist/chunks/KeyboardNav-DZXdTg-_.mjs +2 -0
- package/dist/chunks/KeyboardNav-DZXdTg-_.mjs.map +1 -0
- package/dist/chunks/LinkPlugin-Dmcfo3On.mjs +2 -0
- package/dist/chunks/LinkPlugin-Dmcfo3On.mjs.map +1 -0
- package/dist/chunks/ListPlugin-Ch-5CsFc.mjs +2 -0
- package/dist/chunks/ListPlugin-Ch-5CsFc.mjs.map +1 -0
- package/dist/chunks/NavigationQueries-3zTaNBlp.mjs +2 -0
- package/dist/chunks/NavigationQueries-3zTaNBlp.mjs.map +1 -0
- package/dist/chunks/NodeResolver-BplmzA7c.mjs +2 -0
- package/dist/chunks/NodeResolver-BplmzA7c.mjs.map +1 -0
- package/dist/chunks/NodeSelectionCommands-dUmbRoZ2.mjs +2 -0
- package/dist/chunks/NodeSelectionCommands-dUmbRoZ2.mjs.map +1 -0
- package/dist/chunks/NodeSpecPatching-DToX09gc.mjs +2 -0
- package/dist/chunks/NodeSpecPatching-DToX09gc.mjs.map +1 -0
- package/dist/chunks/Platform-wPvKFB9m.mjs +2 -0
- package/dist/chunks/Platform-wPvKFB9m.mjs.map +1 -0
- package/dist/chunks/PluginHelpers-C3aCCGfX.mjs +2 -0
- package/dist/chunks/PluginHelpers-C3aCCGfX.mjs.map +1 -0
- package/dist/chunks/PopupKeyboardPatterns-ZdAQB78m.mjs +2 -0
- package/dist/chunks/PopupKeyboardPatterns-ZdAQB78m.mjs.map +1 -0
- package/dist/chunks/PopupManager-DsT1uRWi.mjs +2 -0
- package/dist/chunks/PopupManager-DsT1uRWi.mjs.map +1 -0
- package/dist/chunks/PopupPositioning-BEnz90Oh.mjs +2 -0
- package/dist/chunks/PopupPositioning-BEnz90Oh.mjs.map +1 -0
- package/dist/chunks/PrintPlugin-Bq-Z14K1.mjs +2 -0
- package/dist/chunks/PrintPlugin-Bq-Z14K1.mjs.map +1 -0
- package/dist/chunks/PrintTypes-DA0Cc--M.mjs +2 -0
- package/dist/chunks/PrintTypes-DA0Cc--M.mjs.map +1 -0
- package/dist/chunks/RangeIterator-Cl4_k8cx.mjs +2 -0
- package/dist/chunks/RangeIterator-Cl4_k8cx.mjs.map +1 -0
- package/dist/chunks/SelectionSync-DCJpNFat.mjs +2 -0
- package/dist/chunks/SelectionSync-DCJpNFat.mjs.map +1 -0
- package/dist/chunks/ShortcutFormatting-DZK70CN9.mjs +2 -0
- package/dist/chunks/ShortcutFormatting-DZK70CN9.mjs.map +1 -0
- package/dist/chunks/SimpleMark-CezTJnXh.mjs +2 -0
- package/dist/chunks/SimpleMark-CezTJnXh.mjs.map +1 -0
- package/dist/chunks/SmartPastePlugin-DlApY6Vw.mjs +2 -0
- package/dist/chunks/SmartPastePlugin-DlApY6Vw.mjs.map +1 -0
- package/dist/chunks/StrikethroughPlugin-BuFDABvz.mjs +2 -0
- package/dist/chunks/StrikethroughPlugin-BuFDABvz.mjs.map +1 -0
- package/dist/chunks/StyleRuntime-Bwde5icB.mjs +2 -0
- package/dist/chunks/StyleRuntime-Bwde5icB.mjs.map +1 -0
- package/dist/chunks/SuperSubPlugin-CiLJ7i4s.mjs +2 -0
- package/dist/chunks/SuperSubPlugin-CiLJ7i4s.mjs.map +1 -0
- package/dist/chunks/SyntaxTokenTypes-C9dGwufi.mjs +2 -0
- package/dist/chunks/SyntaxTokenTypes-C9dGwufi.mjs.map +1 -0
- package/dist/chunks/TablePlugin-5ru-y-YX.mjs +2 -0
- package/dist/chunks/TablePlugin-5ru-y-YX.mjs.map +1 -0
- package/dist/chunks/TextColorPlugin-Vz-Nz8aH.mjs +2 -0
- package/dist/chunks/TextColorPlugin-Vz-Nz8aH.mjs.map +1 -0
- package/dist/chunks/TextDirectionAutoPlugin-Behl6KMe.mjs +2 -0
- package/dist/chunks/TextDirectionAutoPlugin-Behl6KMe.mjs.map +1 -0
- package/dist/chunks/TextDirectionPlugin-C3h1n-aA.mjs +2 -0
- package/dist/chunks/TextDirectionPlugin-C3h1n-aA.mjs.map +1 -0
- package/dist/chunks/TextDirectionService-DRfeQnF6.mjs +2 -0
- package/dist/chunks/TextDirectionService-DRfeQnF6.mjs.map +1 -0
- package/dist/chunks/TextFormattingPlugin-D_nRMeBn.mjs +2 -0
- package/dist/chunks/TextFormattingPlugin-D_nRMeBn.mjs.map +1 -0
- package/dist/chunks/ToolbarPlugin-CSMSgjPM.mjs +2 -0
- package/dist/chunks/ToolbarPlugin-CSMSgjPM.mjs.map +1 -0
- package/dist/chunks/TypedKeys-E3jOGByL.mjs +2 -0
- package/dist/chunks/TypedKeys-E3jOGByL.mjs.map +1 -0
- package/dist/chunks/VideoPlugin-BUCGIYXr.mjs +2 -0
- package/dist/chunks/VideoPlugin-BUCGIYXr.mjs.map +1 -0
- package/dist/chunks/WordBoundary-CYDAtEks.mjs +2 -0
- package/dist/chunks/WordBoundary-CYDAtEks.mjs.map +1 -0
- package/dist/chunks/XmlDetector-DxBGXqua.mjs +2 -0
- package/dist/chunks/XmlDetector-DxBGXqua.mjs.map +1 -0
- package/dist/chunks/XmlPatterns-BiHS8w3k.mjs +2 -0
- package/dist/chunks/XmlPatterns-BiHS8w3k.mjs.map +1 -0
- package/dist/chunks/XmlSupport-B_F65M8G.mjs +2 -0
- package/dist/chunks/XmlSupport-B_F65M8G.mjs.map +1 -0
- package/dist/chunks/ar-B38MlRRN.mjs +2 -0
- package/dist/chunks/ar-B38MlRRN.mjs.map +1 -0
- package/dist/chunks/ar-BIeE0C5A.mjs +2 -0
- package/dist/chunks/ar-BIeE0C5A.mjs.map +1 -0
- package/dist/chunks/ar-BK0rFxF_.mjs +2 -0
- package/dist/chunks/ar-BK0rFxF_.mjs.map +1 -0
- package/dist/chunks/ar-BK4O36ep.mjs +2 -0
- package/dist/chunks/ar-BK4O36ep.mjs.map +1 -0
- package/dist/chunks/ar-BNUWuZe3.mjs +2 -0
- package/dist/chunks/ar-BNUWuZe3.mjs.map +1 -0
- package/dist/chunks/ar-BSXH8acw.mjs +2 -0
- package/dist/chunks/ar-BSXH8acw.mjs.map +1 -0
- package/dist/chunks/ar-BY8yNlGe.mjs +2 -0
- package/dist/chunks/ar-BY8yNlGe.mjs.map +1 -0
- package/dist/chunks/ar-BgHkduPE.mjs +2 -0
- package/dist/chunks/ar-BgHkduPE.mjs.map +1 -0
- package/dist/chunks/ar-BnfWtLhK.mjs +2 -0
- package/dist/chunks/ar-BnfWtLhK.mjs.map +1 -0
- package/dist/chunks/ar-BwCPhCf6.mjs +2 -0
- package/dist/chunks/ar-BwCPhCf6.mjs.map +1 -0
- package/dist/chunks/ar-Bymjd9Z_.mjs +2 -0
- package/dist/chunks/ar-Bymjd9Z_.mjs.map +1 -0
- package/dist/chunks/ar-CKPpdJ7F.mjs +2 -0
- package/dist/chunks/ar-CKPpdJ7F.mjs.map +1 -0
- package/dist/chunks/ar-C_ir5Uf4.mjs +2 -0
- package/dist/chunks/ar-C_ir5Uf4.mjs.map +1 -0
- package/dist/chunks/ar-CkE6GDVA.mjs +2 -0
- package/dist/chunks/ar-CkE6GDVA.mjs.map +1 -0
- package/dist/chunks/ar-ClgA1KQM.mjs +2 -0
- package/dist/chunks/ar-ClgA1KQM.mjs.map +1 -0
- package/dist/chunks/ar-Cm1DOK74.mjs +2 -0
- package/dist/chunks/ar-Cm1DOK74.mjs.map +1 -0
- package/dist/chunks/ar-CseGhQtS.mjs +2 -0
- package/dist/chunks/ar-CseGhQtS.mjs.map +1 -0
- package/dist/chunks/ar-D0bqkviV.mjs +2 -0
- package/dist/chunks/ar-D0bqkviV.mjs.map +1 -0
- package/dist/chunks/ar-D5d185g0.mjs +2 -0
- package/dist/chunks/ar-D5d185g0.mjs.map +1 -0
- package/dist/chunks/ar-DSwUyX47.mjs +2 -0
- package/dist/chunks/ar-DSwUyX47.mjs.map +1 -0
- package/dist/chunks/ar-DfSNWZX7.mjs +2 -0
- package/dist/chunks/ar-DfSNWZX7.mjs.map +1 -0
- package/dist/chunks/ar-Dghtfs46.mjs +2 -0
- package/dist/chunks/ar-Dghtfs46.mjs.map +1 -0
- package/dist/chunks/ar-DvNKBrJd.mjs +2 -0
- package/dist/chunks/ar-DvNKBrJd.mjs.map +1 -0
- package/dist/chunks/ar-KNULRI8r.mjs +2 -0
- package/dist/chunks/ar-KNULRI8r.mjs.map +1 -0
- package/dist/chunks/ar-NtGRavHz.mjs +2 -0
- package/dist/chunks/ar-NtGRavHz.mjs.map +1 -0
- package/dist/chunks/ar-Y9KjJLX8.mjs +2 -0
- package/dist/chunks/ar-Y9KjJLX8.mjs.map +1 -0
- package/dist/chunks/ar-odM5gkvw.mjs +2 -0
- package/dist/chunks/ar-odM5gkvw.mjs.map +1 -0
- package/dist/chunks/color-picker-C89H4SVX.mjs +2 -0
- package/dist/chunks/color-picker-C89H4SVX.mjs.map +1 -0
- package/dist/chunks/de-B1TXiyll.mjs +2 -0
- package/dist/chunks/de-B1TXiyll.mjs.map +1 -0
- package/dist/chunks/de-BDRaxLyi.mjs +2 -0
- package/dist/chunks/de-BDRaxLyi.mjs.map +1 -0
- package/dist/chunks/de-BGOpZ8Ls.mjs +2 -0
- package/dist/chunks/de-BGOpZ8Ls.mjs.map +1 -0
- package/dist/chunks/de-BfZ5qXWz.mjs +2 -0
- package/dist/chunks/de-BfZ5qXWz.mjs.map +1 -0
- package/dist/chunks/de-BibufNIa.mjs +2 -0
- package/dist/chunks/de-BibufNIa.mjs.map +1 -0
- package/dist/chunks/de-BkZqCmzL.mjs +2 -0
- package/dist/chunks/de-BkZqCmzL.mjs.map +1 -0
- package/dist/chunks/de-BzRd2oyR.mjs +2 -0
- package/dist/chunks/de-BzRd2oyR.mjs.map +1 -0
- package/dist/chunks/de-C4gnHDmk.mjs +2 -0
- package/dist/chunks/de-C4gnHDmk.mjs.map +1 -0
- package/dist/chunks/de-C4iw9SEp.mjs +2 -0
- package/dist/chunks/de-C4iw9SEp.mjs.map +1 -0
- package/dist/chunks/de-CLWzcDoW.mjs +2 -0
- package/dist/chunks/de-CLWzcDoW.mjs.map +1 -0
- package/dist/chunks/de-Cbv0otYM.mjs +2 -0
- package/dist/chunks/de-Cbv0otYM.mjs.map +1 -0
- package/dist/chunks/de-Cinp7zmo.mjs +2 -0
- package/dist/chunks/de-Cinp7zmo.mjs.map +1 -0
- package/dist/chunks/de-CvnyjI_X.mjs +2 -0
- package/dist/chunks/de-CvnyjI_X.mjs.map +1 -0
- package/dist/chunks/de-DCx3Shj3.mjs +2 -0
- package/dist/chunks/de-DCx3Shj3.mjs.map +1 -0
- package/dist/chunks/de-Dav2GzjV.mjs +2 -0
- package/dist/chunks/de-Dav2GzjV.mjs.map +1 -0
- package/dist/chunks/de-Dc7GRbWc.mjs +2 -0
- package/dist/chunks/de-Dc7GRbWc.mjs.map +1 -0
- package/dist/chunks/de-DdntlpT3.mjs +2 -0
- package/dist/chunks/de-DdntlpT3.mjs.map +1 -0
- package/dist/chunks/de-DefykdF-.mjs +2 -0
- package/dist/chunks/de-DefykdF-.mjs.map +1 -0
- package/dist/chunks/de-DfQQIP8Y.mjs +2 -0
- package/dist/chunks/de-DfQQIP8Y.mjs.map +1 -0
- package/dist/chunks/de-DkcKDkbA.mjs +2 -0
- package/dist/chunks/de-DkcKDkbA.mjs.map +1 -0
- package/dist/chunks/de-DqGfLfeV.mjs +2 -0
- package/dist/chunks/de-DqGfLfeV.mjs.map +1 -0
- package/dist/chunks/de-DudqIJho.mjs +2 -0
- package/dist/chunks/de-DudqIJho.mjs.map +1 -0
- package/dist/chunks/de-LCXA2xWj.mjs +2 -0
- package/dist/chunks/de-LCXA2xWj.mjs.map +1 -0
- package/dist/chunks/de-YygmrxGp.mjs +2 -0
- package/dist/chunks/de-YygmrxGp.mjs.map +1 -0
- package/dist/chunks/de-asI3UlFG.mjs +2 -0
- package/dist/chunks/de-asI3UlFG.mjs.map +1 -0
- package/dist/chunks/de-kvMvD3AJ.mjs +2 -0
- package/dist/chunks/de-kvMvD3AJ.mjs.map +1 -0
- package/dist/chunks/de-pnfTnS03.mjs +2 -0
- package/dist/chunks/de-pnfTnS03.mjs.map +1 -0
- package/dist/chunks/es-4tbAR0If.mjs +2 -0
- package/dist/chunks/es-4tbAR0If.mjs.map +1 -0
- package/dist/chunks/es-B9z2Xwj0.mjs +2 -0
- package/dist/chunks/es-B9z2Xwj0.mjs.map +1 -0
- package/dist/chunks/es-BJxjRQSg.mjs +2 -0
- package/dist/chunks/es-BJxjRQSg.mjs.map +1 -0
- package/dist/chunks/es-BSyxBRjn.mjs +2 -0
- package/dist/chunks/es-BSyxBRjn.mjs.map +1 -0
- package/dist/chunks/es-Bcpq2xfU.mjs +2 -0
- package/dist/chunks/es-Bcpq2xfU.mjs.map +1 -0
- package/dist/chunks/es-BhUjc8mO.mjs +2 -0
- package/dist/chunks/es-BhUjc8mO.mjs.map +1 -0
- package/dist/chunks/es-Bm7hoJSI.mjs +2 -0
- package/dist/chunks/es-Bm7hoJSI.mjs.map +1 -0
- package/dist/chunks/es-C0E-lFIC.mjs +2 -0
- package/dist/chunks/es-C0E-lFIC.mjs.map +1 -0
- package/dist/chunks/es-C2wBBQ7N.mjs +2 -0
- package/dist/chunks/es-C2wBBQ7N.mjs.map +1 -0
- package/dist/chunks/es-C9vhYpfP.mjs +2 -0
- package/dist/chunks/es-C9vhYpfP.mjs.map +1 -0
- package/dist/chunks/es-Cgslt0Hp.mjs +2 -0
- package/dist/chunks/es-Cgslt0Hp.mjs.map +1 -0
- package/dist/chunks/es-CksXDFxg.mjs +2 -0
- package/dist/chunks/es-CksXDFxg.mjs.map +1 -0
- package/dist/chunks/es-CnQUZlfY.mjs +2 -0
- package/dist/chunks/es-CnQUZlfY.mjs.map +1 -0
- package/dist/chunks/es-CrRNOn2Q.mjs +2 -0
- package/dist/chunks/es-CrRNOn2Q.mjs.map +1 -0
- package/dist/chunks/es-D0427MIH.mjs +2 -0
- package/dist/chunks/es-D0427MIH.mjs.map +1 -0
- package/dist/chunks/es-D19xfXus.mjs +2 -0
- package/dist/chunks/es-D19xfXus.mjs.map +1 -0
- package/dist/chunks/es-Dk6lCcOt.mjs +2 -0
- package/dist/chunks/es-Dk6lCcOt.mjs.map +1 -0
- package/dist/chunks/es-Dls_xPCW.mjs +2 -0
- package/dist/chunks/es-Dls_xPCW.mjs.map +1 -0
- package/dist/chunks/es-DrcsyDvI.mjs +2 -0
- package/dist/chunks/es-DrcsyDvI.mjs.map +1 -0
- package/dist/chunks/es-DwKejbO9.mjs +2 -0
- package/dist/chunks/es-DwKejbO9.mjs.map +1 -0
- package/dist/chunks/es-NcrWuNe1.mjs +2 -0
- package/dist/chunks/es-NcrWuNe1.mjs.map +1 -0
- package/dist/chunks/es-RaZerssd.mjs +2 -0
- package/dist/chunks/es-RaZerssd.mjs.map +1 -0
- package/dist/chunks/es-TIjHCFNF.mjs +2 -0
- package/dist/chunks/es-TIjHCFNF.mjs.map +1 -0
- package/dist/chunks/es-eZcDkBb-.mjs +2 -0
- package/dist/chunks/es-eZcDkBb-.mjs.map +1 -0
- package/dist/chunks/es-j_-KW9-4.mjs +2 -0
- package/dist/chunks/es-j_-KW9-4.mjs.map +1 -0
- package/dist/chunks/es-kGLwn8EB.mjs +2 -0
- package/dist/chunks/es-kGLwn8EB.mjs.map +1 -0
- package/dist/chunks/es-qQRDC0Ge.mjs +2 -0
- package/dist/chunks/es-qQRDC0Ge.mjs.map +1 -0
- package/dist/chunks/fonts-ZXAIMT3b.mjs +2 -0
- package/dist/chunks/fonts-ZXAIMT3b.mjs.map +1 -0
- package/dist/chunks/fr-B27zAq0X.mjs +2 -0
- package/dist/chunks/fr-B27zAq0X.mjs.map +1 -0
- package/dist/chunks/fr-BEd3ZHO4.mjs +2 -0
- package/dist/chunks/fr-BEd3ZHO4.mjs.map +1 -0
- package/dist/chunks/fr-BHXLpdaH.mjs +2 -0
- package/dist/chunks/fr-BHXLpdaH.mjs.map +1 -0
- package/dist/chunks/fr-BKu4eU3V.mjs +2 -0
- package/dist/chunks/fr-BKu4eU3V.mjs.map +1 -0
- package/dist/chunks/fr-BUrUZ5UQ.mjs +2 -0
- package/dist/chunks/fr-BUrUZ5UQ.mjs.map +1 -0
- package/dist/chunks/fr-BlqlUQ3b.mjs +2 -0
- package/dist/chunks/fr-BlqlUQ3b.mjs.map +1 -0
- package/dist/chunks/fr-BruEqDw1.mjs +2 -0
- package/dist/chunks/fr-BruEqDw1.mjs.map +1 -0
- package/dist/chunks/fr-BwuuFBkA.mjs +2 -0
- package/dist/chunks/fr-BwuuFBkA.mjs.map +1 -0
- package/dist/chunks/fr-C2lLh5Ti.mjs +2 -0
- package/dist/chunks/fr-C2lLh5Ti.mjs.map +1 -0
- package/dist/chunks/fr-C7N2_AlK.mjs +2 -0
- package/dist/chunks/fr-C7N2_AlK.mjs.map +1 -0
- package/dist/chunks/fr-COfd6sLW.mjs +2 -0
- package/dist/chunks/fr-COfd6sLW.mjs.map +1 -0
- package/dist/chunks/fr-COx4cSxc.mjs +2 -0
- package/dist/chunks/fr-COx4cSxc.mjs.map +1 -0
- package/dist/chunks/fr-CX37XjPO.mjs +2 -0
- package/dist/chunks/fr-CX37XjPO.mjs.map +1 -0
- package/dist/chunks/fr-CYn6fMiH.mjs +2 -0
- package/dist/chunks/fr-CYn6fMiH.mjs.map +1 -0
- package/dist/chunks/fr-CbsiyDEa.mjs +2 -0
- package/dist/chunks/fr-CbsiyDEa.mjs.map +1 -0
- package/dist/chunks/fr-CcZiELJY.mjs +2 -0
- package/dist/chunks/fr-CcZiELJY.mjs.map +1 -0
- package/dist/chunks/fr-CeHzUPVT.mjs +2 -0
- package/dist/chunks/fr-CeHzUPVT.mjs.map +1 -0
- package/dist/chunks/fr-Cv73J4QZ.mjs +2 -0
- package/dist/chunks/fr-Cv73J4QZ.mjs.map +1 -0
- package/dist/chunks/fr-DDLuorz7.mjs +2 -0
- package/dist/chunks/fr-DDLuorz7.mjs.map +1 -0
- package/dist/chunks/fr-DMA4CAyo.mjs +2 -0
- package/dist/chunks/fr-DMA4CAyo.mjs.map +1 -0
- package/dist/chunks/fr-DNJuGtO1.mjs +2 -0
- package/dist/chunks/fr-DNJuGtO1.mjs.map +1 -0
- package/dist/chunks/fr-DQOE8O6_.mjs +2 -0
- package/dist/chunks/fr-DQOE8O6_.mjs.map +1 -0
- package/dist/chunks/fr-DXjOwGew.mjs +2 -0
- package/dist/chunks/fr-DXjOwGew.mjs.map +1 -0
- package/dist/chunks/fr-DilrEvE_.mjs +2 -0
- package/dist/chunks/fr-DilrEvE_.mjs.map +1 -0
- package/dist/chunks/fr-P7iY3ntE.mjs +2 -0
- package/dist/chunks/fr-P7iY3ntE.mjs.map +1 -0
- package/dist/chunks/fr-ViUNGo_J.mjs +2 -0
- package/dist/chunks/fr-ViUNGo_J.mjs.map +1 -0
- package/dist/chunks/fr-gdIyLcGC.mjs +2 -0
- package/dist/chunks/fr-gdIyLcGC.mjs.map +1 -0
- package/dist/chunks/full-h88Sb2MR.mjs +2 -0
- package/dist/chunks/full-h88Sb2MR.mjs.map +1 -0
- package/dist/chunks/hi-BC82Jxjl.mjs +2 -0
- package/dist/chunks/hi-BC82Jxjl.mjs.map +1 -0
- package/dist/chunks/hi-BCTarnem.mjs +2 -0
- package/dist/chunks/hi-BCTarnem.mjs.map +1 -0
- package/dist/chunks/hi-BMStjhJF.mjs +2 -0
- package/dist/chunks/hi-BMStjhJF.mjs.map +1 -0
- package/dist/chunks/hi-BQ2Fyx7t.mjs +2 -0
- package/dist/chunks/hi-BQ2Fyx7t.mjs.map +1 -0
- package/dist/chunks/hi-Bg4-z2Os.mjs +2 -0
- package/dist/chunks/hi-Bg4-z2Os.mjs.map +1 -0
- package/dist/chunks/hi-BgqI_gOH.mjs +2 -0
- package/dist/chunks/hi-BgqI_gOH.mjs.map +1 -0
- package/dist/chunks/hi-CEPSeUBX.mjs +2 -0
- package/dist/chunks/hi-CEPSeUBX.mjs.map +1 -0
- package/dist/chunks/hi-CRaZj5Uo.mjs +2 -0
- package/dist/chunks/hi-CRaZj5Uo.mjs.map +1 -0
- package/dist/chunks/hi-CT0uK1Me.mjs +2 -0
- package/dist/chunks/hi-CT0uK1Me.mjs.map +1 -0
- package/dist/chunks/hi-CnIpMd8L.mjs +2 -0
- package/dist/chunks/hi-CnIpMd8L.mjs.map +1 -0
- package/dist/chunks/hi-CnSv0JhL.mjs +2 -0
- package/dist/chunks/hi-CnSv0JhL.mjs.map +1 -0
- package/dist/chunks/hi-DLLBZu67.mjs +2 -0
- package/dist/chunks/hi-DLLBZu67.mjs.map +1 -0
- package/dist/chunks/hi-DMg_aiSR.mjs +2 -0
- package/dist/chunks/hi-DMg_aiSR.mjs.map +1 -0
- package/dist/chunks/hi-DWwLzOX5.mjs +2 -0
- package/dist/chunks/hi-DWwLzOX5.mjs.map +1 -0
- package/dist/chunks/hi-D_4Xi4Nv.mjs +2 -0
- package/dist/chunks/hi-D_4Xi4Nv.mjs.map +1 -0
- package/dist/chunks/hi-D_Jtykmj.mjs +2 -0
- package/dist/chunks/hi-D_Jtykmj.mjs.map +1 -0
- package/dist/chunks/hi-Da5pRz8E.mjs +2 -0
- package/dist/chunks/hi-Da5pRz8E.mjs.map +1 -0
- package/dist/chunks/hi-DqL20WmM.mjs +2 -0
- package/dist/chunks/hi-DqL20WmM.mjs.map +1 -0
- package/dist/chunks/hi-DwQopxRg.mjs +2 -0
- package/dist/chunks/hi-DwQopxRg.mjs.map +1 -0
- package/dist/chunks/hi-IuMohSSw.mjs +2 -0
- package/dist/chunks/hi-IuMohSSw.mjs.map +1 -0
- package/dist/chunks/hi-PUX7dDPm.mjs +2 -0
- package/dist/chunks/hi-PUX7dDPm.mjs.map +1 -0
- package/dist/chunks/hi-RmfZAmwT.mjs +2 -0
- package/dist/chunks/hi-RmfZAmwT.mjs.map +1 -0
- package/dist/chunks/hi-UIBrTEVu.mjs +2 -0
- package/dist/chunks/hi-UIBrTEVu.mjs.map +1 -0
- package/dist/chunks/hi-_SjWnfeh.mjs +2 -0
- package/dist/chunks/hi-_SjWnfeh.mjs.map +1 -0
- package/dist/chunks/hi-dV2GZgH_.mjs +2 -0
- package/dist/chunks/hi-dV2GZgH_.mjs.map +1 -0
- package/dist/chunks/hi-ehh5oKz3.mjs +2 -0
- package/dist/chunks/hi-ehh5oKz3.mjs.map +1 -0
- package/dist/chunks/hi-yXnRBFJK.mjs +2 -0
- package/dist/chunks/hi-yXnRBFJK.mjs.map +1 -0
- package/dist/chunks/minimal-a40NeBQ_.mjs +2 -0
- package/dist/chunks/minimal-a40NeBQ_.mjs.map +1 -0
- package/dist/chunks/pt-2a8Oto6x.mjs +2 -0
- package/dist/chunks/pt-2a8Oto6x.mjs.map +1 -0
- package/dist/chunks/pt-ALzIyTiI.mjs +2 -0
- package/dist/chunks/pt-ALzIyTiI.mjs.map +1 -0
- package/dist/chunks/pt-B2hMlTc6.mjs +2 -0
- package/dist/chunks/pt-B2hMlTc6.mjs.map +1 -0
- package/dist/chunks/pt-BCIkSb0w.mjs +2 -0
- package/dist/chunks/pt-BCIkSb0w.mjs.map +1 -0
- package/dist/chunks/pt-BFotmq5x.mjs +2 -0
- package/dist/chunks/pt-BFotmq5x.mjs.map +1 -0
- package/dist/chunks/pt-BM7OScX6.mjs +2 -0
- package/dist/chunks/pt-BM7OScX6.mjs.map +1 -0
- package/dist/chunks/pt-BM7zXWxW.mjs +2 -0
- package/dist/chunks/pt-BM7zXWxW.mjs.map +1 -0
- package/dist/chunks/pt-BchCuzFq.mjs +2 -0
- package/dist/chunks/pt-BchCuzFq.mjs.map +1 -0
- package/dist/chunks/pt-BmcHFWoR.mjs +2 -0
- package/dist/chunks/pt-BmcHFWoR.mjs.map +1 -0
- package/dist/chunks/pt-C53W99RV.mjs +2 -0
- package/dist/chunks/pt-C53W99RV.mjs.map +1 -0
- package/dist/chunks/pt-CORQy8qv.mjs +2 -0
- package/dist/chunks/pt-CORQy8qv.mjs.map +1 -0
- package/dist/chunks/pt-CUPKr943.mjs +2 -0
- package/dist/chunks/pt-CUPKr943.mjs.map +1 -0
- package/dist/chunks/pt-CYkKDsLa.mjs +2 -0
- package/dist/chunks/pt-CYkKDsLa.mjs.map +1 -0
- package/dist/chunks/pt-Cd_SXHKt.mjs +2 -0
- package/dist/chunks/pt-Cd_SXHKt.mjs.map +1 -0
- package/dist/chunks/pt-CjN3Oq-6.mjs +2 -0
- package/dist/chunks/pt-CjN3Oq-6.mjs.map +1 -0
- package/dist/chunks/pt-CrKrgktr.mjs +2 -0
- package/dist/chunks/pt-CrKrgktr.mjs.map +1 -0
- package/dist/chunks/pt-Crmbkj0e.mjs +2 -0
- package/dist/chunks/pt-Crmbkj0e.mjs.map +1 -0
- package/dist/chunks/pt-D19IWOM_.mjs +2 -0
- package/dist/chunks/pt-D19IWOM_.mjs.map +1 -0
- package/dist/chunks/pt-D6zY7l2E.mjs +2 -0
- package/dist/chunks/pt-D6zY7l2E.mjs.map +1 -0
- package/dist/chunks/pt-DA5hufLZ.mjs +2 -0
- package/dist/chunks/pt-DA5hufLZ.mjs.map +1 -0
- package/dist/chunks/pt-DEfBqu-c.mjs +2 -0
- package/dist/chunks/pt-DEfBqu-c.mjs.map +1 -0
- package/dist/chunks/pt-DG3rw6nK.mjs +2 -0
- package/dist/chunks/pt-DG3rw6nK.mjs.map +1 -0
- package/dist/chunks/pt-DRoAHNZi.mjs +2 -0
- package/dist/chunks/pt-DRoAHNZi.mjs.map +1 -0
- package/dist/chunks/pt-Eml9QiUL.mjs +2 -0
- package/dist/chunks/pt-Eml9QiUL.mjs.map +1 -0
- package/dist/chunks/pt-Haa3wVmA.mjs +2 -0
- package/dist/chunks/pt-Haa3wVmA.mjs.map +1 -0
- package/dist/chunks/pt-aj7zOxTg.mjs +2 -0
- package/dist/chunks/pt-aj7zOxTg.mjs.map +1 -0
- package/dist/chunks/pt-l6dTmkQk.mjs +2 -0
- package/dist/chunks/pt-l6dTmkQk.mjs.map +1 -0
- package/dist/chunks/ru--JPEpdcJ.mjs +2 -0
- package/dist/chunks/ru--JPEpdcJ.mjs.map +1 -0
- package/dist/chunks/ru-B76ORyqe.mjs +2 -0
- package/dist/chunks/ru-B76ORyqe.mjs.map +1 -0
- package/dist/chunks/ru-BDQ62WuE.mjs +2 -0
- package/dist/chunks/ru-BDQ62WuE.mjs.map +1 -0
- package/dist/chunks/ru-BQ6W3lwr.mjs +2 -0
- package/dist/chunks/ru-BQ6W3lwr.mjs.map +1 -0
- package/dist/chunks/ru-BQpaitci.mjs +2 -0
- package/dist/chunks/ru-BQpaitci.mjs.map +1 -0
- package/dist/chunks/ru-Bm9VwJLu.mjs +2 -0
- package/dist/chunks/ru-Bm9VwJLu.mjs.map +1 -0
- package/dist/chunks/ru-BnNdik6i.mjs +2 -0
- package/dist/chunks/ru-BnNdik6i.mjs.map +1 -0
- package/dist/chunks/ru-Bo4am8cd.mjs +2 -0
- package/dist/chunks/ru-Bo4am8cd.mjs.map +1 -0
- package/dist/chunks/ru-C1k56xWQ.mjs +2 -0
- package/dist/chunks/ru-C1k56xWQ.mjs.map +1 -0
- package/dist/chunks/ru-C4rnSQlI.mjs +2 -0
- package/dist/chunks/ru-C4rnSQlI.mjs.map +1 -0
- package/dist/chunks/ru-CKM3t1sv.mjs +2 -0
- package/dist/chunks/ru-CKM3t1sv.mjs.map +1 -0
- package/dist/chunks/ru-CO6eCsxU.mjs +2 -0
- package/dist/chunks/ru-CO6eCsxU.mjs.map +1 -0
- package/dist/chunks/ru-CTaYpQ9_.mjs +2 -0
- package/dist/chunks/ru-CTaYpQ9_.mjs.map +1 -0
- package/dist/chunks/ru-CdY8d80t.mjs +2 -0
- package/dist/chunks/ru-CdY8d80t.mjs.map +1 -0
- package/dist/chunks/ru-CsDtaWRd.mjs +2 -0
- package/dist/chunks/ru-CsDtaWRd.mjs.map +1 -0
- package/dist/chunks/ru-Cy_4nn8h.mjs +2 -0
- package/dist/chunks/ru-Cy_4nn8h.mjs.map +1 -0
- package/dist/chunks/ru-DACtjNuJ.mjs +2 -0
- package/dist/chunks/ru-DACtjNuJ.mjs.map +1 -0
- package/dist/chunks/ru-DN6yN_w9.mjs +2 -0
- package/dist/chunks/ru-DN6yN_w9.mjs.map +1 -0
- package/dist/chunks/ru-DThFtd76.mjs +2 -0
- package/dist/chunks/ru-DThFtd76.mjs.map +1 -0
- package/dist/chunks/ru-Dd_P7hP7.mjs +2 -0
- package/dist/chunks/ru-Dd_P7hP7.mjs.map +1 -0
- package/dist/chunks/ru-Dhuxwzwy.mjs +2 -0
- package/dist/chunks/ru-Dhuxwzwy.mjs.map +1 -0
- package/dist/chunks/ru-Dn6UDGIG.mjs +2 -0
- package/dist/chunks/ru-Dn6UDGIG.mjs.map +1 -0
- package/dist/chunks/ru-DojHc5wu.mjs +2 -0
- package/dist/chunks/ru-DojHc5wu.mjs.map +1 -0
- package/dist/chunks/ru-DyWzWBjV.mjs +2 -0
- package/dist/chunks/ru-DyWzWBjV.mjs.map +1 -0
- package/dist/chunks/ru-NBxCkjlP.mjs +2 -0
- package/dist/chunks/ru-NBxCkjlP.mjs.map +1 -0
- package/dist/chunks/ru-_MQaVHam.mjs +2 -0
- package/dist/chunks/ru-_MQaVHam.mjs.map +1 -0
- package/dist/chunks/ru-wv17PPrd.mjs +2 -0
- package/dist/chunks/ru-wv17PPrd.mjs.map +1 -0
- package/dist/chunks/src-ooaZ_Egu.mjs +2 -0
- package/dist/chunks/src-ooaZ_Egu.mjs.map +1 -0
- package/dist/chunks/zh-2-Y3Limy.mjs +2 -0
- package/dist/chunks/zh-2-Y3Limy.mjs.map +1 -0
- package/dist/chunks/zh-B02VPMqX.mjs +2 -0
- package/dist/chunks/zh-B02VPMqX.mjs.map +1 -0
- package/dist/chunks/zh-BYjLBWWN.mjs +2 -0
- package/dist/chunks/zh-BYjLBWWN.mjs.map +1 -0
- package/dist/chunks/zh-Bt2ZdHcS.mjs +2 -0
- package/dist/chunks/zh-Bt2ZdHcS.mjs.map +1 -0
- package/dist/chunks/zh-BuN_C4o-.mjs +2 -0
- package/dist/chunks/zh-BuN_C4o-.mjs.map +1 -0
- package/dist/chunks/zh-CA3BDj0Y.mjs +2 -0
- package/dist/chunks/zh-CA3BDj0Y.mjs.map +1 -0
- package/dist/chunks/zh-CHuGP7RS.mjs +2 -0
- package/dist/chunks/zh-CHuGP7RS.mjs.map +1 -0
- package/dist/chunks/zh-CIPsF5P8.mjs +2 -0
- package/dist/chunks/zh-CIPsF5P8.mjs.map +1 -0
- package/dist/chunks/zh-C_YS18re.mjs +2 -0
- package/dist/chunks/zh-C_YS18re.mjs.map +1 -0
- package/dist/chunks/zh-CfMPFWUg.mjs +2 -0
- package/dist/chunks/zh-CfMPFWUg.mjs.map +1 -0
- package/dist/chunks/zh-CfjCcBIB.mjs +2 -0
- package/dist/chunks/zh-CfjCcBIB.mjs.map +1 -0
- package/dist/chunks/zh-CqQph809.mjs +2 -0
- package/dist/chunks/zh-CqQph809.mjs.map +1 -0
- package/dist/chunks/zh-Cxe42GC5.mjs +2 -0
- package/dist/chunks/zh-Cxe42GC5.mjs.map +1 -0
- package/dist/chunks/zh-CyMU2cTf.mjs +2 -0
- package/dist/chunks/zh-CyMU2cTf.mjs.map +1 -0
- package/dist/chunks/zh-Cynz1sBa.mjs +2 -0
- package/dist/chunks/zh-Cynz1sBa.mjs.map +1 -0
- package/dist/chunks/zh-DRKs6Q0a.mjs +2 -0
- package/dist/chunks/zh-DRKs6Q0a.mjs.map +1 -0
- package/dist/chunks/zh-DTuIJjx6.mjs +2 -0
- package/dist/chunks/zh-DTuIJjx6.mjs.map +1 -0
- package/dist/chunks/zh-DTz9l6mp.mjs +2 -0
- package/dist/chunks/zh-DTz9l6mp.mjs.map +1 -0
- package/dist/chunks/zh-DZwjiJmn.mjs +2 -0
- package/dist/chunks/zh-DZwjiJmn.mjs.map +1 -0
- package/dist/chunks/zh-D_VJDQl4.mjs +2 -0
- package/dist/chunks/zh-D_VJDQl4.mjs.map +1 -0
- package/dist/chunks/zh-Dt20Om7Z.mjs +2 -0
- package/dist/chunks/zh-Dt20Om7Z.mjs.map +1 -0
- package/dist/chunks/zh-SgsZ9f-W.mjs +2 -0
- package/dist/chunks/zh-SgsZ9f-W.mjs.map +1 -0
- package/dist/chunks/zh-XR7Ls7m-.mjs +2 -0
- package/dist/chunks/zh-XR7Ls7m-.mjs.map +1 -0
- package/dist/chunks/zh-aXPI9lKF.mjs +2 -0
- package/dist/chunks/zh-aXPI9lKF.mjs.map +1 -0
- package/dist/chunks/zh-cLXIKkZQ.mjs +2 -0
- package/dist/chunks/zh-cLXIKkZQ.mjs.map +1 -0
- package/dist/chunks/zh-cZUtN871.mjs +2 -0
- package/dist/chunks/zh-cZUtN871.mjs.map +1 -0
- package/dist/chunks/zh-hcdnCGUp.mjs +2 -0
- package/dist/chunks/zh-hcdnCGUp.mjs.map +1 -0
- package/dist/commands/AttributedMarkCommands.d.ts.map +1 -1
- package/dist/commands/BlockInsertion.d.ts +27 -0
- package/dist/commands/BlockInsertion.d.ts.map +1 -1
- package/dist/commands/CommandHelpers.d.ts +12 -0
- package/dist/commands/CommandHelpers.d.ts.map +1 -1
- package/dist/commands/Commands.d.ts.map +1 -1
- package/dist/commands/ContainerCommands.d.ts +24 -0
- package/dist/commands/ContainerCommands.d.ts.map +1 -0
- package/dist/commands/CursorMarks.d.ts +13 -0
- package/dist/commands/CursorMarks.d.ts.map +1 -0
- package/dist/commands/GapCursorCommands.d.ts.map +1 -1
- package/dist/commands/MarkCommands.d.ts.map +1 -1
- package/dist/commands/NodeSelectionCommands.d.ts.map +1 -1
- package/dist/commands/PasteCommand.d.ts.map +1 -1
- package/dist/commands/SelectionDeletion.d.ts +25 -0
- package/dist/commands/SelectionDeletion.d.ts.map +1 -0
- package/dist/decorations/Decoration.d.ts +6 -0
- package/dist/decorations/Decoration.d.ts.map +1 -1
- package/dist/decorations/PositionMapping.d.ts +13 -3
- package/dist/decorations/PositionMapping.d.ts.map +1 -1
- package/dist/editor/ContentSerializer.d.ts +1 -1
- package/dist/editor/ContentSerializer.d.ts.map +1 -1
- package/dist/editor/EditorConfig.d.ts +14 -2
- package/dist/editor/EditorConfig.d.ts.map +1 -1
- package/dist/editor/EditorDOM.d.ts.map +1 -1
- package/dist/editor/EditorInitializer.d.ts.map +1 -1
- package/dist/editor/NotectlEditor.d.ts +12 -7
- package/dist/editor/NotectlEditor.d.ts.map +1 -1
- package/dist/editor/PluginBootstrapper.d.ts.map +1 -1
- package/dist/editor/styles/base.d.ts +1 -1
- package/dist/editor/styles/base.d.ts.map +1 -1
- package/dist/editor/styles/table.d.ts +1 -1
- package/dist/editor/styles/table.d.ts.map +1 -1
- package/dist/editor/styles/toolbar.d.ts +1 -1
- package/dist/editor/styles/toolbar.d.ts.map +1 -1
- package/dist/fonts.d.ts +11 -0
- package/dist/fonts.d.ts.map +1 -1
- package/dist/fonts.mjs +1 -1
- package/dist/full.d.ts +2 -0
- package/dist/full.d.ts.map +1 -1
- package/dist/full.mjs +1 -1
- package/dist/html.d.ts +1 -1
- package/dist/html.d.ts.map +1 -1
- package/dist/html.mjs +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/input/ClipboardHandler.d.ts.map +1 -1
- package/dist/input/HTMLParser.d.ts +3 -0
- package/dist/input/HTMLParser.d.ts.map +1 -1
- package/dist/input/InputHandler.d.ts +9 -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/KeyboardHandler.d.ts.map +1 -1
- package/dist/input/PasteHTMLHandler.d.ts +1 -1
- package/dist/input/PasteHTMLHandler.d.ts.map +1 -1
- package/dist/input/PasteRichBlockHandler.d.ts +1 -1
- package/dist/input/PasteRichBlockHandler.d.ts.map +1 -1
- package/dist/input/SelectionDocument.d.ts.map +1 -1
- package/dist/model/ContentSlice.d.ts +6 -7
- package/dist/model/ContentSlice.d.ts.map +1 -1
- package/dist/model/Document.d.ts +34 -0
- package/dist/model/Document.d.ts.map +1 -1
- package/dist/model/GraphemeUtils.d.ts +8 -2
- package/dist/model/GraphemeUtils.d.ts.map +1 -1
- package/dist/model/MarkSpec.d.ts +6 -0
- package/dist/model/MarkSpec.d.ts.map +1 -1
- package/dist/model/NodeResolver.d.ts +18 -0
- package/dist/model/NodeResolver.d.ts.map +1 -1
- package/dist/model/Schema.d.ts +6 -0
- package/dist/model/Schema.d.ts.map +1 -1
- package/dist/model/SchemaRegistry.d.ts.map +1 -1
- package/dist/model/TextInputInterceptor.d.ts +21 -0
- package/dist/model/TextInputInterceptor.d.ts.map +1 -0
- 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/MiddlewareChain.d.ts +11 -0
- package/dist/plugins/MiddlewareChain.d.ts.map +1 -1
- package/dist/plugins/Plugin.d.ts +7 -0
- package/dist/plugins/Plugin.d.ts.map +1 -1
- package/dist/plugins/PluginContextFactory.d.ts +6 -0
- package/dist/plugins/PluginContextFactory.d.ts.map +1 -1
- package/dist/plugins/PluginManager.d.ts +5 -0
- package/dist/plugins/PluginManager.d.ts.map +1 -1
- package/dist/plugins/RegistrationTracker.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/bidi-isolation/BidiIsolationPlugin.d.ts.map +1 -1
- package/dist/plugins/bidi-isolation.mjs +1 -1
- package/dist/plugins/blockquote/BlockquoteKeyboardHandlers.d.ts +1 -1
- package/dist/plugins/blockquote/BlockquoteKeyboardHandlers.d.ts.map +1 -1
- package/dist/plugins/blockquote/BlockquotePlugin.d.ts +13 -3
- package/dist/plugins/blockquote/BlockquotePlugin.d.ts.map +1 -1
- package/dist/plugins/blockquote/BlockquoteStyles.d.ts +1 -1
- package/dist/plugins/blockquote/BlockquoteStyles.d.ts.map +1 -1
- package/dist/plugins/blockquote.mjs +1 -1
- package/dist/plugins/caret-navigation.mjs +1 -1
- package/dist/plugins/code-block/AutoPairController.d.ts +50 -0
- package/dist/plugins/code-block/AutoPairController.d.ts.map +1 -0
- package/dist/plugins/code-block/BracketPairing.d.ts +49 -0
- package/dist/plugins/code-block/BracketPairing.d.ts.map +1 -0
- package/dist/plugins/code-block/CodeBlockDecorations.d.ts +16 -0
- package/dist/plugins/code-block/CodeBlockDecorations.d.ts.map +1 -0
- package/dist/plugins/code-block/CodeBlockHighlighting.d.ts +10 -0
- package/dist/plugins/code-block/CodeBlockHighlighting.d.ts.map +1 -0
- package/dist/plugins/code-block/CodeBlockKeyboardHandlers.d.ts +11 -2
- package/dist/plugins/code-block/CodeBlockKeyboardHandlers.d.ts.map +1 -1
- package/dist/plugins/code-block/CodeBlockLocale.d.ts +4 -0
- package/dist/plugins/code-block/CodeBlockLocale.d.ts.map +1 -1
- package/dist/plugins/code-block/CodeBlockNodeView.d.ts.map +1 -1
- package/dist/plugins/code-block/CodeBlockPlugin.d.ts +4 -14
- package/dist/plugins/code-block/CodeBlockPlugin.d.ts.map +1 -1
- package/dist/plugins/code-block/CodeBlockSchema.d.ts +11 -0
- package/dist/plugins/code-block/CodeBlockSchema.d.ts.map +1 -0
- package/dist/plugins/code-block/CodeBlockTypes.d.ts +66 -0
- package/dist/plugins/code-block/CodeBlockTypes.d.ts.map +1 -1
- package/dist/plugins/code-block/IndentHelpers.d.ts +71 -0
- package/dist/plugins/code-block/IndentHelpers.d.ts.map +1 -0
- package/dist/plugins/code-block/PairStack.d.ts +37 -0
- package/dist/plugins/code-block/PairStack.d.ts.map +1 -0
- package/dist/plugins/code-block/TokenCache.d.ts +21 -0
- package/dist/plugins/code-block/TokenCache.d.ts.map +1 -0
- package/dist/plugins/code-block/highlighter/RegexTokenizer.d.ts.map +1 -1
- package/dist/plugins/code-block/highlighter/TokenIteration.d.ts +18 -0
- package/dist/plugins/code-block/highlighter/TokenIteration.d.ts.map +1 -0
- package/dist/plugins/code-block/highlighter/languages/index.d.ts +1 -0
- package/dist/plugins/code-block/highlighter/languages/index.d.ts.map +1 -1
- package/dist/plugins/code-block/highlighter/languages/java.d.ts.map +1 -1
- package/dist/plugins/code-block/highlighter/languages/typescript.d.ts +3 -0
- package/dist/plugins/code-block/highlighter/languages/typescript.d.ts.map +1 -0
- package/dist/plugins/code-block/index.d.ts +1 -0
- package/dist/plugins/code-block/index.d.ts.map +1 -1
- package/dist/plugins/code-block/locales/ar.d.ts.map +1 -1
- package/dist/plugins/code-block/locales/de.d.ts.map +1 -1
- package/dist/plugins/code-block/locales/es.d.ts.map +1 -1
- package/dist/plugins/code-block/locales/fr.d.ts.map +1 -1
- package/dist/plugins/code-block/locales/hi.d.ts.map +1 -1
- package/dist/plugins/code-block/locales/pt.d.ts.map +1 -1
- package/dist/plugins/code-block/locales/ru.d.ts.map +1 -1
- package/dist/plugins/code-block/locales/zh.d.ts.map +1 -1
- package/dist/plugins/code-block.mjs +1 -1
- package/dist/plugins/font/FontPlugin.d.ts.map +1 -1
- package/dist/plugins/font-size/FontSizeOperations.d.ts +7 -3
- package/dist/plugins/font-size/FontSizeOperations.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.mjs +1 -1
- package/dist/plugins/formula/DisplayMathNodeSpec.d.ts +5 -0
- package/dist/plugins/formula/DisplayMathNodeSpec.d.ts.map +1 -0
- package/dist/plugins/formula/DisplayMathNodeView.d.ts +12 -0
- package/dist/plugins/formula/DisplayMathNodeView.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaCommands.d.ts +35 -0
- package/dist/plugins/formula/FormulaCommands.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaEditTrigger.d.ts +12 -0
- package/dist/plugins/formula/FormulaEditTrigger.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaEditorMount.d.ts +19 -0
- package/dist/plugins/formula/FormulaEditorMount.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaInputRules.d.ts +4 -0
- package/dist/plugins/formula/FormulaInputRules.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaLocale.d.ts +45 -0
- package/dist/plugins/formula/FormulaLocale.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaOverlay.d.ts +38 -0
- package/dist/plugins/formula/FormulaOverlay.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaPasteInterceptor.d.ts +10 -0
- package/dist/plugins/formula/FormulaPasteInterceptor.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaPlugin.d.ts +22 -0
- package/dist/plugins/formula/FormulaPlugin.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaRendering.d.ts +18 -0
- package/dist/plugins/formula/FormulaRendering.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaStyles.d.ts +12 -0
- package/dist/plugins/formula/FormulaStyles.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaToolbar.d.ts +5 -0
- package/dist/plugins/formula/FormulaToolbar.d.ts.map +1 -0
- package/dist/plugins/formula/FormulaTypes.d.ts +64 -0
- package/dist/plugins/formula/FormulaTypes.d.ts.map +1 -0
- package/dist/plugins/formula/InlineMathNodeSpec.d.ts +5 -0
- package/dist/plugins/formula/InlineMathNodeSpec.d.ts.map +1 -0
- package/dist/plugins/formula/MathFont.d.ts +4 -0
- package/dist/plugins/formula/MathFont.d.ts.map +1 -0
- package/dist/plugins/formula/MathFontFace.d.ts +4 -0
- package/dist/plugins/formula/MathFontFace.d.ts.map +1 -0
- package/dist/plugins/formula/index.d.ts +14 -0
- package/dist/plugins/formula/index.d.ts.map +1 -0
- package/dist/plugins/formula/latex/LatexParser.d.ts +8 -0
- package/dist/plugins/formula/latex/LatexParser.d.ts.map +1 -0
- package/dist/plugins/formula/latex/LatexParserTypes.d.ts +61 -0
- package/dist/plugins/formula/latex/LatexParserTypes.d.ts.map +1 -0
- package/dist/plugins/formula/latex/LatexSymbols.d.ts +87 -0
- package/dist/plugins/formula/latex/LatexSymbols.d.ts.map +1 -0
- package/dist/plugins/formula/latex/LatexToMathML.d.ts +33 -0
- package/dist/plugins/formula/latex/LatexToMathML.d.ts.map +1 -0
- package/dist/plugins/formula/latex/LatexTokenizer.d.ts +45 -0
- package/dist/plugins/formula/latex/LatexTokenizer.d.ts.map +1 -0
- package/dist/plugins/formula/latex/MathAlphabet.d.ts +42 -0
- package/dist/plugins/formula/latex/MathAlphabet.d.ts.map +1 -0
- package/dist/plugins/formula/latex/handlers/Accents.d.ts +6 -0
- package/dist/plugins/formula/latex/handlers/Accents.d.ts.map +1 -0
- package/dist/plugins/formula/latex/handlers/Delimiters.d.ts +12 -0
- package/dist/plugins/formula/latex/handlers/Delimiters.d.ts.map +1 -0
- package/dist/plugins/formula/latex/handlers/Environments.d.ts +9 -0
- package/dist/plugins/formula/latex/handlers/Environments.d.ts.map +1 -0
- package/dist/plugins/formula/latex/handlers/Fonts.d.ts +6 -0
- package/dist/plugins/formula/latex/handlers/Fonts.d.ts.map +1 -0
- package/dist/plugins/formula/latex/handlers/Spacing.d.ts +13 -0
- package/dist/plugins/formula/latex/handlers/Spacing.d.ts.map +1 -0
- package/dist/plugins/formula/latex/handlers/Structures.d.ts +19 -0
- package/dist/plugins/formula/latex/handlers/Structures.d.ts.map +1 -0
- package/dist/plugins/formula/latex/index.d.ts +11 -0
- package/dist/plugins/formula/latex/index.d.ts.map +1 -0
- package/dist/plugins/formula/locales/ar.d.ts +4 -0
- package/dist/plugins/formula/locales/ar.d.ts.map +1 -0
- package/dist/plugins/formula/locales/de.d.ts +4 -0
- package/dist/plugins/formula/locales/de.d.ts.map +1 -0
- package/dist/plugins/formula/locales/es.d.ts +4 -0
- package/dist/plugins/formula/locales/es.d.ts.map +1 -0
- package/dist/plugins/formula/locales/fr.d.ts +4 -0
- package/dist/plugins/formula/locales/fr.d.ts.map +1 -0
- package/dist/plugins/formula/locales/hi.d.ts +4 -0
- package/dist/plugins/formula/locales/hi.d.ts.map +1 -0
- package/dist/plugins/formula/locales/pt.d.ts +4 -0
- package/dist/plugins/formula/locales/pt.d.ts.map +1 -0
- package/dist/plugins/formula/locales/ru.d.ts +4 -0
- package/dist/plugins/formula/locales/ru.d.ts.map +1 -0
- package/dist/plugins/formula/locales/zh.d.ts +4 -0
- package/dist/plugins/formula/locales/zh.d.ts.map +1 -0
- package/dist/plugins/formula/math-field/MathField.d.ts +45 -0
- package/dist/plugins/formula/math-field/MathField.d.ts.map +1 -0
- package/dist/plugins/formula/math-field/MathFieldTypes.d.ts +73 -0
- package/dist/plugins/formula/math-field/MathFieldTypes.d.ts.map +1 -0
- package/dist/plugins/formula/math-field/MathPalette.d.ts +16 -0
- package/dist/plugins/formula/math-field/MathPalette.d.ts.map +1 -0
- package/dist/plugins/formula/math-field/MathPaletteData.d.ts +15 -0
- package/dist/plugins/formula/math-field/MathPaletteData.d.ts.map +1 -0
- package/dist/plugins/formula/math-field/index.d.ts +9 -0
- package/dist/plugins/formula/math-field/index.d.ts.map +1 -0
- package/dist/plugins/formula/mathml/MathMLBuilder.d.ts +58 -0
- package/dist/plugins/formula/mathml/MathMLBuilder.d.ts.map +1 -0
- package/dist/plugins/formula/mathml/MathMLDocument.d.ts +54 -0
- package/dist/plugins/formula/mathml/MathMLDocument.d.ts.map +1 -0
- package/dist/plugins/formula/mathml/MathMLSanitize.d.ts +15 -0
- package/dist/plugins/formula/mathml/MathMLSanitize.d.ts.map +1 -0
- package/dist/plugins/formula/mathml/index.d.ts +8 -0
- package/dist/plugins/formula/mathml/index.d.ts.map +1 -0
- package/dist/plugins/formula.mjs +1 -0
- package/dist/plugins/gap-cursor.mjs +1 -1
- package/dist/plugins/hard-break.mjs +1 -1
- package/dist/plugins/heading.mjs +1 -1
- package/dist/plugins/highlight/HighlightPalette.d.ts +7 -0
- package/dist/plugins/highlight/HighlightPalette.d.ts.map +1 -0
- package/dist/plugins/highlight/HighlightPlugin.d.ts.map +1 -1
- package/dist/plugins/highlight.mjs +1 -1
- package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts.map +1 -1
- package/dist/plugins/horizontal-rule.mjs +1 -1
- package/dist/plugins/image/ImageCommands.d.ts.map +1 -1
- package/dist/plugins/image/ImageNodeView.d.ts.map +1 -1
- package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
- package/dist/plugins/image/ImagePopup.d.ts.map +1 -1
- package/dist/plugins/image/ImagePopupStyles.d.ts +3 -0
- package/dist/plugins/image/ImagePopupStyles.d.ts.map +1 -0
- package/dist/plugins/image.mjs +1 -1
- package/dist/plugins/inline-code/InlineCodePlugin.d.ts +1 -4
- package/dist/plugins/inline-code/InlineCodePlugin.d.ts.map +1 -1
- package/dist/plugins/inline-code.mjs +1 -1
- package/dist/plugins/language/bundles/JavaSupport.d.ts.map +1 -1
- package/dist/plugins/language/bundles/TypeScriptSupport.d.ts +3 -0
- package/dist/plugins/language/bundles/TypeScriptSupport.d.ts.map +1 -0
- package/dist/plugins/language/bundles/index.d.ts +1 -0
- package/dist/plugins/language/bundles/index.d.ts.map +1 -1
- package/dist/plugins/language/index.d.ts +1 -1
- package/dist/plugins/language/index.d.ts.map +1 -1
- package/dist/plugins/language.mjs +1 -1
- package/dist/plugins/link/LinkPlugin.d.ts.map +1 -1
- package/dist/plugins/link.mjs +1 -1
- package/dist/plugins/list.mjs +1 -1
- package/dist/plugins/print.mjs +1 -1
- package/dist/plugins/shared/InlineStyleMarkSpec.d.ts +22 -0
- package/dist/plugins/shared/InlineStyleMarkSpec.d.ts.map +1 -0
- package/dist/plugins/shared/NodeSpecPatching.d.ts +16 -0
- package/dist/plugins/shared/NodeSpecPatching.d.ts.map +1 -0
- 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/PopupPositioning.d.ts +20 -0
- package/dist/plugins/shared/PopupPositioning.d.ts.map +1 -1
- package/dist/plugins/shared/SimpleMark.d.ts +22 -0
- package/dist/plugins/shared/SimpleMark.d.ts.map +1 -0
- package/dist/plugins/shared.mjs +1 -1
- package/dist/plugins/smart-paste/detectors/DetectionScorer.d.ts +17 -0
- package/dist/plugins/smart-paste/detectors/DetectionScorer.d.ts.map +1 -0
- package/dist/plugins/smart-paste/detectors/LexerDetector.d.ts +36 -0
- package/dist/plugins/smart-paste/detectors/LexerDetector.d.ts.map +1 -0
- package/dist/plugins/smart-paste/detectors/TokenStats.d.ts +44 -0
- package/dist/plugins/smart-paste/detectors/TokenStats.d.ts.map +1 -0
- package/dist/plugins/smart-paste/index.d.ts +3 -1
- package/dist/plugins/smart-paste/index.d.ts.map +1 -1
- package/dist/plugins/smart-paste.mjs +1 -1
- package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts +0 -4
- package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts.map +1 -1
- package/dist/plugins/strikethrough.mjs +1 -1
- package/dist/plugins/super-sub/SuperSubPlugin.d.ts.map +1 -1
- package/dist/plugins/super-sub.mjs +1 -1
- package/dist/plugins/table/TableCommands.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.mjs +1 -1
- package/dist/plugins/text-color/TextColorPalette.d.ts +6 -0
- package/dist/plugins/text-color/TextColorPalette.d.ts.map +1 -0
- package/dist/plugins/text-color/TextColorPlugin.d.ts.map +1 -1
- package/dist/plugins/text-color.mjs +1 -1
- package/dist/plugins/text-direction/TextDirectionPlugin.d.ts.map +1 -1
- package/dist/plugins/text-direction-auto.mjs +1 -1
- package/dist/plugins/text-direction.mjs +1 -1
- package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts.map +1 -1
- package/dist/plugins/text-formatting.mjs +1 -1
- package/dist/plugins/toolbar/ToolbarOverflowController.d.ts +14 -1
- package/dist/plugins/toolbar/ToolbarOverflowController.d.ts.map +1 -1
- package/dist/plugins/toolbar/ToolbarPlugin.d.ts +13 -1
- package/dist/plugins/toolbar/ToolbarPlugin.d.ts.map +1 -1
- package/dist/plugins/toolbar/ToolbarRenderers.d.ts.map +1 -1
- package/dist/plugins/toolbar/index.d.ts +1 -1
- package/dist/plugins/toolbar/index.d.ts.map +1 -1
- package/dist/plugins/toolbar.mjs +1 -1
- package/dist/plugins/video/VideoCommands.d.ts +62 -0
- package/dist/plugins/video/VideoCommands.d.ts.map +1 -0
- package/dist/plugins/video/VideoEditOverlay.d.ts +30 -0
- package/dist/plugins/video/VideoEditOverlay.d.ts.map +1 -0
- package/dist/plugins/video/VideoEmbedPrompt.d.ts +18 -0
- package/dist/plugins/video/VideoEmbedPrompt.d.ts.map +1 -0
- package/dist/plugins/video/VideoFacade.d.ts +46 -0
- package/dist/plugins/video/VideoFacade.d.ts.map +1 -0
- package/dist/plugins/video/VideoLocale.d.ts +53 -0
- package/dist/plugins/video/VideoLocale.d.ts.map +1 -0
- package/dist/plugins/video/VideoNodeSpec.d.ts +24 -0
- package/dist/plugins/video/VideoNodeSpec.d.ts.map +1 -0
- package/dist/plugins/video/VideoNodeView.d.ts +16 -0
- package/dist/plugins/video/VideoNodeView.d.ts.map +1 -0
- package/dist/plugins/video/VideoPasteInterceptor.d.ts +9 -0
- package/dist/plugins/video/VideoPasteInterceptor.d.ts.map +1 -0
- package/dist/plugins/video/VideoPlugin.d.ts +31 -0
- package/dist/plugins/video/VideoPlugin.d.ts.map +1 -0
- package/dist/plugins/video/VideoPopup.d.ts +28 -0
- package/dist/plugins/video/VideoPopup.d.ts.map +1 -0
- package/dist/plugins/video/VideoPopupStyles.d.ts +3 -0
- package/dist/plugins/video/VideoPopupStyles.d.ts.map +1 -0
- package/dist/plugins/video/VideoProviders.d.ts +98 -0
- package/dist/plugins/video/VideoProviders.d.ts.map +1 -0
- package/dist/plugins/video/VideoResize.d.ts +35 -0
- package/dist/plugins/video/VideoResize.d.ts.map +1 -0
- package/dist/plugins/video/VideoSanitizeHook.d.ts +23 -0
- package/dist/plugins/video/VideoSanitizeHook.d.ts.map +1 -0
- package/dist/plugins/video/VideoSelectionToolbar.d.ts +20 -0
- package/dist/plugins/video/VideoSelectionToolbar.d.ts.map +1 -0
- package/dist/plugins/video/VideoStyles.d.ts +3 -0
- package/dist/plugins/video/VideoStyles.d.ts.map +1 -0
- package/dist/plugins/video/VideoTypes.d.ts +102 -0
- package/dist/plugins/video/VideoTypes.d.ts.map +1 -0
- package/dist/plugins/video/VideoViewHelpers.d.ts +13 -0
- package/dist/plugins/video/VideoViewHelpers.d.ts.map +1 -0
- package/dist/plugins/video/index.d.ts +6 -0
- package/dist/plugins/video/index.d.ts.map +1 -0
- package/dist/plugins/video/locales/ar.d.ts +4 -0
- package/dist/plugins/video/locales/ar.d.ts.map +1 -0
- package/dist/plugins/video/locales/de.d.ts +4 -0
- package/dist/plugins/video/locales/de.d.ts.map +1 -0
- package/dist/plugins/video/locales/es.d.ts +4 -0
- package/dist/plugins/video/locales/es.d.ts.map +1 -0
- package/dist/plugins/video/locales/fr.d.ts +4 -0
- package/dist/plugins/video/locales/fr.d.ts.map +1 -0
- package/dist/plugins/video/locales/hi.d.ts +4 -0
- package/dist/plugins/video/locales/hi.d.ts.map +1 -0
- package/dist/plugins/video/locales/pt.d.ts +4 -0
- package/dist/plugins/video/locales/pt.d.ts.map +1 -0
- package/dist/plugins/video/locales/ru.d.ts +4 -0
- package/dist/plugins/video/locales/ru.d.ts.map +1 -0
- package/dist/plugins/video/locales/zh.d.ts +4 -0
- package/dist/plugins/video/locales/zh.d.ts.map +1 -0
- package/dist/plugins/video.mjs +1 -0
- package/dist/presets/FullPreset.d.ts +1 -1
- package/dist/presets/FullPreset.d.ts.map +1 -1
- package/dist/presets/PresetTypes.d.ts +4 -0
- package/dist/presets/PresetTypes.d.ts.map +1 -1
- package/dist/presets/full.mjs +1 -1
- package/dist/presets/minimal.mjs +1 -1
- package/dist/presets.mjs +1 -1
- package/dist/serialization/CSSClassCollector.d.ts.map +1 -1
- package/dist/serialization/ContentHTMLTypes.d.ts +19 -1
- package/dist/serialization/ContentHTMLTypes.d.ts.map +1 -1
- package/dist/serialization/DocumentParser.d.ts.map +1 -1
- package/dist/serialization/DocumentSerializer.d.ts +3 -3
- package/dist/serialization/DocumentSerializer.d.ts.map +1 -1
- package/dist/serialization/HTMLWhitespace.d.ts +22 -0
- package/dist/serialization/HTMLWhitespace.d.ts.map +1 -0
- package/dist/serialization/MarkSerializer.d.ts.map +1 -1
- package/dist/serialization/index.d.ts +1 -1
- package/dist/serialization/index.d.ts.map +1 -1
- package/dist/state/BlockTreeOps.d.ts +8 -1
- package/dist/state/BlockTreeOps.d.ts.map +1 -1
- package/dist/state/EditorState.d.ts.map +1 -1
- package/dist/state/History.d.ts +20 -0
- package/dist/state/History.d.ts.map +1 -1
- package/dist/state/InlineContentOps.d.ts +30 -0
- package/dist/state/InlineContentOps.d.ts.map +1 -1
- package/dist/state/Mapping.d.ts +261 -0
- package/dist/state/Mapping.d.ts.map +1 -0
- package/dist/state/NavigationQueries.d.ts +11 -0
- package/dist/state/NavigationQueries.d.ts.map +1 -1
- package/dist/state/SelectionMapping.d.ts +25 -0
- package/dist/state/SelectionMapping.d.ts.map +1 -0
- package/dist/state/StepApplication.d.ts +20 -3
- package/dist/state/StepApplication.d.ts.map +1 -1
- package/dist/state/StepHandlers.d.ts +68 -0
- package/dist/state/StepHandlers.d.ts.map +1 -0
- package/dist/state/StepInversion.d.ts +22 -5
- package/dist/state/StepInversion.d.ts.map +1 -1
- package/dist/state/StepMapping.d.ts +18 -0
- package/dist/state/StepMapping.d.ts.map +1 -0
- package/dist/state/StepMaps.d.ts +25 -0
- package/dist/state/StepMaps.d.ts.map +1 -0
- package/dist/state/Steps.d.ts +38 -0
- package/dist/state/Steps.d.ts.map +1 -1
- package/dist/state/Transaction.d.ts +25 -1
- package/dist/state/Transaction.d.ts.map +1 -1
- package/dist/state/TransactionBuilder.d.ts +51 -7
- package/dist/state/TransactionBuilder.d.ts.map +1 -1
- package/dist/test/TestUtils.d.ts +3 -1
- package/dist/test/TestUtils.d.ts.map +1 -1
- package/dist/view/CaretNavigation.d.ts.map +1 -1
- package/dist/view/EditorView.d.ts.map +1 -1
- package/dist/view/SelectionSync.d.ts.map +1 -1
- package/dist/view/ViewMovementCommands.d.ts.map +1 -1
- package/package.json +16 -1
- package/dist/chunks/AlignmentPlugin-bqK6ze-E.mjs +0 -2
- package/dist/chunks/AlignmentPlugin-bqK6ze-E.mjs.map +0 -1
- package/dist/chunks/AttrRegistry-nDKtHK87.mjs +0 -2
- package/dist/chunks/AttrRegistry-nDKtHK87.mjs.map +0 -1
- package/dist/chunks/AttributedMarkCommands-35jTbVRg.mjs +0 -2
- package/dist/chunks/AttributedMarkCommands-35jTbVRg.mjs.map +0 -1
- package/dist/chunks/BidiIsolationPlugin-SIKxfWXp.mjs +0 -2
- package/dist/chunks/BidiIsolationPlugin-SIKxfWXp.mjs.map +0 -1
- package/dist/chunks/BlockInsertion-DsnHLcvM.mjs +0 -2
- package/dist/chunks/BlockInsertion-DsnHLcvM.mjs.map +0 -1
- package/dist/chunks/BlockTypePickerRegistry-C_jLddOz.mjs +0 -2
- package/dist/chunks/BlockTypePickerRegistry-C_jLddOz.mjs.map +0 -1
- package/dist/chunks/BlockquotePlugin-BEaZSoVT.mjs +0 -2
- package/dist/chunks/BlockquotePlugin-BEaZSoVT.mjs.map +0 -1
- package/dist/chunks/CaretNavigationPlugin-DHl61oc6.mjs +0 -2
- package/dist/chunks/CaretNavigationPlugin-DHl61oc6.mjs.map +0 -1
- package/dist/chunks/CodeBlockPlugin-DglqiSNK.mjs +0 -2
- package/dist/chunks/CodeBlockPlugin-DglqiSNK.mjs.map +0 -1
- package/dist/chunks/ColorGrid-Czm0p2E9.mjs +0 -2
- package/dist/chunks/ColorGrid-Czm0p2E9.mjs.map +0 -1
- package/dist/chunks/ColorPickerPopup-CL-W380M.mjs +0 -2
- package/dist/chunks/ColorPickerPopup-CL-W380M.mjs.map +0 -1
- package/dist/chunks/ColorValidation-CiGxVsqd.mjs +0 -2
- package/dist/chunks/ColorValidation-CiGxVsqd.mjs.map +0 -1
- package/dist/chunks/CommandHelpers-DTlQcGv5.mjs +0 -2
- package/dist/chunks/CommandHelpers-DTlQcGv5.mjs.map +0 -1
- package/dist/chunks/Commands-BuYF23lf.mjs +0 -2
- package/dist/chunks/Commands-BuYF23lf.mjs.map +0 -1
- package/dist/chunks/Decoration-oeHDjWWq.mjs +0 -2
- package/dist/chunks/Decoration-oeHDjWWq.mjs.map +0 -1
- package/dist/chunks/DirectionDetection-Hun6-7ER.mjs +0 -2
- package/dist/chunks/DirectionDetection-Hun6-7ER.mjs.map +0 -1
- package/dist/chunks/DirectionIcons-CfaDcQ9a.mjs +0 -2
- package/dist/chunks/DirectionIcons-CfaDcQ9a.mjs.map +0 -1
- package/dist/chunks/Document-_qdGR4vh.mjs +0 -2
- package/dist/chunks/Document-_qdGR4vh.mjs.map +0 -1
- package/dist/chunks/DocumentParser-CyATBOz-.mjs +0 -2
- package/dist/chunks/DocumentParser-CyATBOz-.mjs.map +0 -1
- package/dist/chunks/FontPlugin-B-Sxa0UW.mjs +0 -2
- package/dist/chunks/FontPlugin-B-Sxa0UW.mjs.map +0 -1
- package/dist/chunks/FontSizePlugin-C1zlyXL2.mjs +0 -2
- package/dist/chunks/FontSizePlugin-C1zlyXL2.mjs.map +0 -1
- package/dist/chunks/GapCursorNavigation-BaXDnjFf.mjs +0 -2
- package/dist/chunks/GapCursorNavigation-BaXDnjFf.mjs.map +0 -1
- package/dist/chunks/GapCursorPlugin-nldun8cE.mjs +0 -2
- package/dist/chunks/GapCursorPlugin-nldun8cE.mjs.map +0 -1
- package/dist/chunks/HardBreakPlugin-DZRdsE15.mjs +0 -2
- package/dist/chunks/HardBreakPlugin-DZRdsE15.mjs.map +0 -1
- package/dist/chunks/HeadingPlugin-EPAmsEGt.mjs +0 -2
- package/dist/chunks/HeadingPlugin-EPAmsEGt.mjs.map +0 -1
- package/dist/chunks/HighlightPlugin-RN3l6pVJ.mjs +0 -2
- package/dist/chunks/HighlightPlugin-RN3l6pVJ.mjs.map +0 -1
- package/dist/chunks/HorizontalRulePlugin-BJPXzTtJ.mjs +0 -2
- package/dist/chunks/HorizontalRulePlugin-BJPXzTtJ.mjs.map +0 -1
- package/dist/chunks/ImagePlugin-CCEevNfJ.mjs +0 -2
- package/dist/chunks/ImagePlugin-CCEevNfJ.mjs.map +0 -1
- package/dist/chunks/InlineCodePlugin-B7IOgUSI.mjs +0 -2
- package/dist/chunks/InlineCodePlugin-B7IOgUSI.mjs.map +0 -1
- package/dist/chunks/KeyboardNav-CsdlWnNl.mjs +0 -2
- package/dist/chunks/KeyboardNav-CsdlWnNl.mjs.map +0 -1
- package/dist/chunks/LinkPlugin-Bhwg24lH.mjs +0 -2
- package/dist/chunks/LinkPlugin-Bhwg24lH.mjs.map +0 -1
- package/dist/chunks/ListPlugin-BkG6UO4x.mjs +0 -2
- package/dist/chunks/ListPlugin-BkG6UO4x.mjs.map +0 -1
- package/dist/chunks/NavigationQueries-CgYPG6oY.mjs +0 -2
- package/dist/chunks/NavigationQueries-CgYPG6oY.mjs.map +0 -1
- package/dist/chunks/NodeResolver-DVPpO5nC.mjs +0 -2
- package/dist/chunks/NodeResolver-DVPpO5nC.mjs.map +0 -1
- package/dist/chunks/NodeSelectionCommands-Ddxu5Qck.mjs +0 -2
- package/dist/chunks/NodeSelectionCommands-Ddxu5Qck.mjs.map +0 -1
- package/dist/chunks/Platform-D9TRT4Mn.mjs +0 -2
- package/dist/chunks/Platform-D9TRT4Mn.mjs.map +0 -1
- package/dist/chunks/PluginHelpers-D-MvWR98.mjs +0 -2
- package/dist/chunks/PluginHelpers-D-MvWR98.mjs.map +0 -1
- package/dist/chunks/PopupKeyboardPatterns-DQdL7RHx.mjs +0 -2
- package/dist/chunks/PopupKeyboardPatterns-DQdL7RHx.mjs.map +0 -1
- package/dist/chunks/PopupManager-CxPzNm-P.mjs +0 -2
- package/dist/chunks/PopupManager-CxPzNm-P.mjs.map +0 -1
- package/dist/chunks/PopupPositioning-DRNwWB0U.mjs +0 -2
- package/dist/chunks/PopupPositioning-DRNwWB0U.mjs.map +0 -1
- package/dist/chunks/PrintPlugin-DOk5IZRO.mjs +0 -2
- package/dist/chunks/PrintPlugin-DOk5IZRO.mjs.map +0 -1
- package/dist/chunks/PrintTypes-Drk6kLcl.mjs +0 -2
- package/dist/chunks/PrintTypes-Drk6kLcl.mjs.map +0 -1
- package/dist/chunks/RangeIterator-DytL1lUT.mjs +0 -2
- package/dist/chunks/RangeIterator-DytL1lUT.mjs.map +0 -1
- package/dist/chunks/ShortcutFormatting-DE6B8iGs.mjs +0 -2
- package/dist/chunks/ShortcutFormatting-DE6B8iGs.mjs.map +0 -1
- package/dist/chunks/SmartPastePlugin-DqKx94sH.mjs +0 -2
- package/dist/chunks/SmartPastePlugin-DqKx94sH.mjs.map +0 -1
- package/dist/chunks/StrikethroughPlugin-vYNzfxdy.mjs +0 -2
- package/dist/chunks/StrikethroughPlugin-vYNzfxdy.mjs.map +0 -1
- package/dist/chunks/StyleRuntime-D3d1XFFe.mjs +0 -2
- package/dist/chunks/StyleRuntime-D3d1XFFe.mjs.map +0 -1
- package/dist/chunks/SuperSubPlugin-BNsoXWHS.mjs +0 -2
- package/dist/chunks/SuperSubPlugin-BNsoXWHS.mjs.map +0 -1
- package/dist/chunks/SyntaxTokenTypes-CVUAMov0.mjs +0 -2
- package/dist/chunks/SyntaxTokenTypes-CVUAMov0.mjs.map +0 -1
- package/dist/chunks/TablePlugin-R-hmydrM.mjs +0 -2
- package/dist/chunks/TablePlugin-R-hmydrM.mjs.map +0 -1
- package/dist/chunks/TextColorPlugin-DQ-CB9cr.mjs +0 -2
- package/dist/chunks/TextColorPlugin-DQ-CB9cr.mjs.map +0 -1
- package/dist/chunks/TextDirectionAutoPlugin-kZ1tcu0d.mjs +0 -2
- package/dist/chunks/TextDirectionAutoPlugin-kZ1tcu0d.mjs.map +0 -1
- package/dist/chunks/TextDirectionPlugin-Bk3CkbYh.mjs +0 -2
- package/dist/chunks/TextDirectionPlugin-Bk3CkbYh.mjs.map +0 -1
- package/dist/chunks/TextDirectionService-DY4M8EwU.mjs +0 -2
- package/dist/chunks/TextDirectionService-DY4M8EwU.mjs.map +0 -1
- package/dist/chunks/TextFormattingPlugin-D13eP6nF.mjs +0 -2
- package/dist/chunks/TextFormattingPlugin-D13eP6nF.mjs.map +0 -1
- package/dist/chunks/ToolbarPlugin-DeH8n5d2.mjs +0 -2
- package/dist/chunks/ToolbarPlugin-DeH8n5d2.mjs.map +0 -1
- package/dist/chunks/TypedKeys-CU7aToqY.mjs +0 -2
- package/dist/chunks/TypedKeys-CU7aToqY.mjs.map +0 -1
- package/dist/chunks/WordBoundary-BE2u997Q.mjs +0 -2
- package/dist/chunks/WordBoundary-BE2u997Q.mjs.map +0 -1
- package/dist/chunks/XmlDetector-BtYxzBDa.mjs +0 -2
- package/dist/chunks/XmlDetector-BtYxzBDa.mjs.map +0 -1
- package/dist/chunks/XmlPatterns-DuP8GWVt.mjs +0 -2
- package/dist/chunks/XmlPatterns-DuP8GWVt.mjs.map +0 -1
- package/dist/chunks/XmlSupport-D54BdAJZ.mjs +0 -2
- package/dist/chunks/XmlSupport-D54BdAJZ.mjs.map +0 -1
- package/dist/chunks/ar-2Fkz_6nI.mjs +0 -2
- package/dist/chunks/ar-2Fkz_6nI.mjs.map +0 -1
- package/dist/chunks/ar-4ZPC8daa.mjs +0 -2
- package/dist/chunks/ar-4ZPC8daa.mjs.map +0 -1
- package/dist/chunks/ar-6I20_Djq.mjs +0 -2
- package/dist/chunks/ar-6I20_Djq.mjs.map +0 -1
- package/dist/chunks/ar-B7-Dm70S.mjs +0 -2
- package/dist/chunks/ar-B7-Dm70S.mjs.map +0 -1
- package/dist/chunks/ar-BRe0t96G.mjs +0 -2
- package/dist/chunks/ar-BRe0t96G.mjs.map +0 -1
- package/dist/chunks/ar-BnNyrtdi.mjs +0 -2
- package/dist/chunks/ar-BnNyrtdi.mjs.map +0 -1
- package/dist/chunks/ar-BsMfhWs5.mjs +0 -2
- package/dist/chunks/ar-BsMfhWs5.mjs.map +0 -1
- package/dist/chunks/ar-Bvja-bjE.mjs +0 -2
- package/dist/chunks/ar-Bvja-bjE.mjs.map +0 -1
- package/dist/chunks/ar-BxVbBvSa.mjs +0 -2
- package/dist/chunks/ar-BxVbBvSa.mjs.map +0 -1
- package/dist/chunks/ar-C5dW-co3.mjs +0 -2
- package/dist/chunks/ar-C5dW-co3.mjs.map +0 -1
- package/dist/chunks/ar-CARMr30L.mjs +0 -2
- package/dist/chunks/ar-CARMr30L.mjs.map +0 -1
- package/dist/chunks/ar-CB-pehGw.mjs +0 -2
- package/dist/chunks/ar-CB-pehGw.mjs.map +0 -1
- package/dist/chunks/ar-CEYgAxTM.mjs +0 -2
- package/dist/chunks/ar-CEYgAxTM.mjs.map +0 -1
- package/dist/chunks/ar-CO60qpZJ.mjs +0 -2
- package/dist/chunks/ar-CO60qpZJ.mjs.map +0 -1
- package/dist/chunks/ar-CtI_snUM.mjs +0 -2
- package/dist/chunks/ar-CtI_snUM.mjs.map +0 -1
- package/dist/chunks/ar-Cv1RQvhK.mjs +0 -2
- package/dist/chunks/ar-Cv1RQvhK.mjs.map +0 -1
- package/dist/chunks/ar-D5jV20Tu.mjs +0 -2
- package/dist/chunks/ar-D5jV20Tu.mjs.map +0 -1
- package/dist/chunks/ar-DJN9fQ7Z.mjs +0 -2
- package/dist/chunks/ar-DJN9fQ7Z.mjs.map +0 -1
- package/dist/chunks/ar-DPTsUnwA.mjs +0 -2
- package/dist/chunks/ar-DPTsUnwA.mjs.map +0 -1
- package/dist/chunks/ar-DZJIBD1Q.mjs +0 -2
- package/dist/chunks/ar-DZJIBD1Q.mjs.map +0 -1
- package/dist/chunks/ar-DkkbwV93.mjs +0 -2
- package/dist/chunks/ar-DkkbwV93.mjs.map +0 -1
- package/dist/chunks/ar-DmeMor8Y.mjs +0 -2
- package/dist/chunks/ar-DmeMor8Y.mjs.map +0 -1
- package/dist/chunks/ar-LnE7jPai.mjs +0 -2
- package/dist/chunks/ar-LnE7jPai.mjs.map +0 -1
- package/dist/chunks/ar-P3wW0fmA.mjs +0 -2
- package/dist/chunks/ar-P3wW0fmA.mjs.map +0 -1
- package/dist/chunks/ar-uum0DCfv.mjs +0 -2
- package/dist/chunks/ar-uum0DCfv.mjs.map +0 -1
- package/dist/chunks/color-picker-DlXhHBZ6.mjs +0 -2
- package/dist/chunks/color-picker-DlXhHBZ6.mjs.map +0 -1
- package/dist/chunks/de-8SHQu0rr.mjs +0 -2
- package/dist/chunks/de-8SHQu0rr.mjs.map +0 -1
- package/dist/chunks/de-B8a71A0X.mjs +0 -2
- package/dist/chunks/de-B8a71A0X.mjs.map +0 -1
- package/dist/chunks/de-B9weXoA1.mjs +0 -2
- package/dist/chunks/de-B9weXoA1.mjs.map +0 -1
- package/dist/chunks/de-BKm53tVU.mjs +0 -2
- package/dist/chunks/de-BKm53tVU.mjs.map +0 -1
- package/dist/chunks/de-BLWrnMfX.mjs +0 -2
- package/dist/chunks/de-BLWrnMfX.mjs.map +0 -1
- package/dist/chunks/de-BOujs1pF.mjs +0 -2
- package/dist/chunks/de-BOujs1pF.mjs.map +0 -1
- package/dist/chunks/de-B_1XleAG.mjs +0 -2
- package/dist/chunks/de-B_1XleAG.mjs.map +0 -1
- package/dist/chunks/de-BpmjrOMc.mjs +0 -2
- package/dist/chunks/de-BpmjrOMc.mjs.map +0 -1
- package/dist/chunks/de-C8OHD1fm.mjs +0 -2
- package/dist/chunks/de-C8OHD1fm.mjs.map +0 -1
- package/dist/chunks/de-CAVCXBBR.mjs +0 -2
- package/dist/chunks/de-CAVCXBBR.mjs.map +0 -1
- package/dist/chunks/de-CkMnuozT.mjs +0 -2
- package/dist/chunks/de-CkMnuozT.mjs.map +0 -1
- package/dist/chunks/de-CtDnvnnm.mjs +0 -2
- package/dist/chunks/de-CtDnvnnm.mjs.map +0 -1
- package/dist/chunks/de-Cz26vtXW.mjs +0 -2
- package/dist/chunks/de-Cz26vtXW.mjs.map +0 -1
- package/dist/chunks/de-D0BPSP3j.mjs +0 -2
- package/dist/chunks/de-D0BPSP3j.mjs.map +0 -1
- package/dist/chunks/de-D74v0paw.mjs +0 -2
- package/dist/chunks/de-D74v0paw.mjs.map +0 -1
- package/dist/chunks/de-DKj55F9g.mjs +0 -2
- package/dist/chunks/de-DKj55F9g.mjs.map +0 -1
- package/dist/chunks/de-DYuRb98l.mjs +0 -2
- package/dist/chunks/de-DYuRb98l.mjs.map +0 -1
- package/dist/chunks/de-DaK0-sdo.mjs +0 -2
- package/dist/chunks/de-DaK0-sdo.mjs.map +0 -1
- package/dist/chunks/de-Dia08Wsq.mjs +0 -2
- package/dist/chunks/de-Dia08Wsq.mjs.map +0 -1
- package/dist/chunks/de-Dp_uj2Z3.mjs +0 -2
- package/dist/chunks/de-Dp_uj2Z3.mjs.map +0 -1
- package/dist/chunks/de-DwX1CDNO.mjs +0 -2
- package/dist/chunks/de-DwX1CDNO.mjs.map +0 -1
- package/dist/chunks/de-DyF2mRfw.mjs +0 -2
- package/dist/chunks/de-DyF2mRfw.mjs.map +0 -1
- package/dist/chunks/de-X3BLBlF8.mjs +0 -2
- package/dist/chunks/de-X3BLBlF8.mjs.map +0 -1
- package/dist/chunks/de-dPC3Qk7N.mjs +0 -2
- package/dist/chunks/de-dPC3Qk7N.mjs.map +0 -1
- package/dist/chunks/de-pLGt5S7j.mjs +0 -2
- package/dist/chunks/de-pLGt5S7j.mjs.map +0 -1
- package/dist/chunks/es--xozZF4T.mjs +0 -2
- package/dist/chunks/es--xozZF4T.mjs.map +0 -1
- package/dist/chunks/es-2BjtTusm.mjs +0 -2
- package/dist/chunks/es-2BjtTusm.mjs.map +0 -1
- package/dist/chunks/es-B2rEK7_f.mjs +0 -2
- package/dist/chunks/es-B2rEK7_f.mjs.map +0 -1
- package/dist/chunks/es-B9esmUm1.mjs +0 -2
- package/dist/chunks/es-B9esmUm1.mjs.map +0 -1
- package/dist/chunks/es-BJxkHalP.mjs +0 -2
- package/dist/chunks/es-BJxkHalP.mjs.map +0 -1
- package/dist/chunks/es-BMKsnh3y.mjs +0 -2
- package/dist/chunks/es-BMKsnh3y.mjs.map +0 -1
- package/dist/chunks/es-BXFflrrU.mjs +0 -2
- package/dist/chunks/es-BXFflrrU.mjs.map +0 -1
- package/dist/chunks/es-BbX_lEEN.mjs +0 -2
- package/dist/chunks/es-BbX_lEEN.mjs.map +0 -1
- package/dist/chunks/es-BlHe_tc0.mjs +0 -2
- package/dist/chunks/es-BlHe_tc0.mjs.map +0 -1
- package/dist/chunks/es-Bu6nnEeT.mjs +0 -2
- package/dist/chunks/es-Bu6nnEeT.mjs.map +0 -1
- package/dist/chunks/es-Bx0CbUoY.mjs +0 -2
- package/dist/chunks/es-Bx0CbUoY.mjs.map +0 -1
- package/dist/chunks/es-CE9Tbsb7.mjs +0 -2
- package/dist/chunks/es-CE9Tbsb7.mjs.map +0 -1
- package/dist/chunks/es-COSomns3.mjs +0 -2
- package/dist/chunks/es-COSomns3.mjs.map +0 -1
- package/dist/chunks/es-C_7qthHu.mjs +0 -2
- package/dist/chunks/es-C_7qthHu.mjs.map +0 -1
- package/dist/chunks/es-CirfP3x1.mjs +0 -2
- package/dist/chunks/es-CirfP3x1.mjs.map +0 -1
- package/dist/chunks/es-CpF8eiPr.mjs +0 -2
- package/dist/chunks/es-CpF8eiPr.mjs.map +0 -1
- package/dist/chunks/es-D787y0ui.mjs +0 -2
- package/dist/chunks/es-D787y0ui.mjs.map +0 -1
- package/dist/chunks/es-D8iB5vwQ.mjs +0 -2
- package/dist/chunks/es-D8iB5vwQ.mjs.map +0 -1
- package/dist/chunks/es-DBb78XWu.mjs +0 -2
- package/dist/chunks/es-DBb78XWu.mjs.map +0 -1
- package/dist/chunks/es-DC6mYTD3.mjs +0 -2
- package/dist/chunks/es-DC6mYTD3.mjs.map +0 -1
- package/dist/chunks/es-Dh--mRZs.mjs +0 -2
- package/dist/chunks/es-Dh--mRZs.mjs.map +0 -1
- package/dist/chunks/es-DvPsYqFj.mjs +0 -2
- package/dist/chunks/es-DvPsYqFj.mjs.map +0 -1
- package/dist/chunks/es-DxXimuUa.mjs +0 -2
- package/dist/chunks/es-DxXimuUa.mjs.map +0 -1
- package/dist/chunks/es-mWJptxq3.mjs +0 -2
- package/dist/chunks/es-mWJptxq3.mjs.map +0 -1
- package/dist/chunks/es-qYV--o6U.mjs +0 -2
- package/dist/chunks/es-qYV--o6U.mjs.map +0 -1
- package/dist/chunks/fonts-CxtWyeNB.mjs +0 -2
- package/dist/chunks/fonts-CxtWyeNB.mjs.map +0 -1
- package/dist/chunks/fr--F426oao.mjs +0 -2
- package/dist/chunks/fr--F426oao.mjs.map +0 -1
- package/dist/chunks/fr-B0BPbbNB.mjs +0 -2
- package/dist/chunks/fr-B0BPbbNB.mjs.map +0 -1
- package/dist/chunks/fr-B4UQy0j-.mjs +0 -2
- package/dist/chunks/fr-B4UQy0j-.mjs.map +0 -1
- package/dist/chunks/fr-B4XLxkci.mjs +0 -2
- package/dist/chunks/fr-B4XLxkci.mjs.map +0 -1
- package/dist/chunks/fr-BC1Rfp9S.mjs +0 -2
- package/dist/chunks/fr-BC1Rfp9S.mjs.map +0 -1
- package/dist/chunks/fr-BRGGu0E2.mjs +0 -2
- package/dist/chunks/fr-BRGGu0E2.mjs.map +0 -1
- package/dist/chunks/fr-BoSz1pa9.mjs +0 -2
- package/dist/chunks/fr-BoSz1pa9.mjs.map +0 -1
- package/dist/chunks/fr-Bom3RFIN.mjs +0 -2
- package/dist/chunks/fr-Bom3RFIN.mjs.map +0 -1
- package/dist/chunks/fr-BtnwMUII.mjs +0 -2
- package/dist/chunks/fr-BtnwMUII.mjs.map +0 -1
- package/dist/chunks/fr-C6pglM3H.mjs +0 -2
- package/dist/chunks/fr-C6pglM3H.mjs.map +0 -1
- package/dist/chunks/fr-CDBpS6xE.mjs +0 -2
- package/dist/chunks/fr-CDBpS6xE.mjs.map +0 -1
- package/dist/chunks/fr-CN0ihkUg.mjs +0 -2
- package/dist/chunks/fr-CN0ihkUg.mjs.map +0 -1
- package/dist/chunks/fr-CNNBBeLM.mjs +0 -2
- package/dist/chunks/fr-CNNBBeLM.mjs.map +0 -1
- package/dist/chunks/fr-CVOY2y07.mjs +0 -2
- package/dist/chunks/fr-CVOY2y07.mjs.map +0 -1
- package/dist/chunks/fr-CZAbL_o0.mjs +0 -2
- package/dist/chunks/fr-CZAbL_o0.mjs.map +0 -1
- package/dist/chunks/fr-DJkPmQG_.mjs +0 -2
- package/dist/chunks/fr-DJkPmQG_.mjs.map +0 -1
- package/dist/chunks/fr-DkWdFDsR.mjs +0 -2
- package/dist/chunks/fr-DkWdFDsR.mjs.map +0 -1
- package/dist/chunks/fr-DnQHoPVo.mjs +0 -2
- package/dist/chunks/fr-DnQHoPVo.mjs.map +0 -1
- package/dist/chunks/fr-DsdueaiG.mjs +0 -2
- package/dist/chunks/fr-DsdueaiG.mjs.map +0 -1
- package/dist/chunks/fr-DxNdsa11.mjs +0 -2
- package/dist/chunks/fr-DxNdsa11.mjs.map +0 -1
- package/dist/chunks/fr-IO4_LYvE.mjs +0 -2
- package/dist/chunks/fr-IO4_LYvE.mjs.map +0 -1
- package/dist/chunks/fr-ZKDCEpww.mjs +0 -2
- package/dist/chunks/fr-ZKDCEpww.mjs.map +0 -1
- package/dist/chunks/fr-coufP_et.mjs +0 -2
- package/dist/chunks/fr-coufP_et.mjs.map +0 -1
- package/dist/chunks/fr-lYSOgOK7.mjs +0 -2
- package/dist/chunks/fr-lYSOgOK7.mjs.map +0 -1
- package/dist/chunks/fr-wobtRjcF.mjs +0 -2
- package/dist/chunks/fr-wobtRjcF.mjs.map +0 -1
- package/dist/chunks/full-5hGvv-bG.mjs +0 -2
- package/dist/chunks/full-5hGvv-bG.mjs.map +0 -1
- package/dist/chunks/hi-B0o90MFd.mjs +0 -2
- package/dist/chunks/hi-B0o90MFd.mjs.map +0 -1
- package/dist/chunks/hi-BFko34WG.mjs +0 -2
- package/dist/chunks/hi-BFko34WG.mjs.map +0 -1
- package/dist/chunks/hi-BVxSgaNT.mjs +0 -2
- package/dist/chunks/hi-BVxSgaNT.mjs.map +0 -1
- package/dist/chunks/hi-BirBQ5Ef.mjs +0 -2
- package/dist/chunks/hi-BirBQ5Ef.mjs.map +0 -1
- package/dist/chunks/hi-BnsbcSIX.mjs +0 -2
- package/dist/chunks/hi-BnsbcSIX.mjs.map +0 -1
- package/dist/chunks/hi-BoFuxLtG.mjs +0 -2
- package/dist/chunks/hi-BoFuxLtG.mjs.map +0 -1
- package/dist/chunks/hi-BptyTwAv.mjs +0 -2
- package/dist/chunks/hi-BptyTwAv.mjs.map +0 -1
- package/dist/chunks/hi-BulaYhi_.mjs +0 -2
- package/dist/chunks/hi-BulaYhi_.mjs.map +0 -1
- package/dist/chunks/hi-BzflHG6Y.mjs +0 -2
- package/dist/chunks/hi-BzflHG6Y.mjs.map +0 -1
- package/dist/chunks/hi-C7Hb-gQ_.mjs +0 -2
- package/dist/chunks/hi-C7Hb-gQ_.mjs.map +0 -1
- package/dist/chunks/hi-C_lY7kA9.mjs +0 -2
- package/dist/chunks/hi-C_lY7kA9.mjs.map +0 -1
- package/dist/chunks/hi-CkylXoIm.mjs +0 -2
- package/dist/chunks/hi-CkylXoIm.mjs.map +0 -1
- package/dist/chunks/hi-DGJTbrQi.mjs +0 -2
- package/dist/chunks/hi-DGJTbrQi.mjs.map +0 -1
- package/dist/chunks/hi-DGJgX0fG.mjs +0 -2
- package/dist/chunks/hi-DGJgX0fG.mjs.map +0 -1
- package/dist/chunks/hi-DKDYpjdr.mjs +0 -2
- package/dist/chunks/hi-DKDYpjdr.mjs.map +0 -1
- package/dist/chunks/hi-DfAX8S-T.mjs +0 -2
- package/dist/chunks/hi-DfAX8S-T.mjs.map +0 -1
- package/dist/chunks/hi-Dhq91ipt.mjs +0 -2
- package/dist/chunks/hi-Dhq91ipt.mjs.map +0 -1
- package/dist/chunks/hi-Dup389dM.mjs +0 -2
- package/dist/chunks/hi-Dup389dM.mjs.map +0 -1
- package/dist/chunks/hi-DzRFsYYN.mjs +0 -2
- package/dist/chunks/hi-DzRFsYYN.mjs.map +0 -1
- package/dist/chunks/hi-ObZRwITd.mjs +0 -2
- package/dist/chunks/hi-ObZRwITd.mjs.map +0 -1
- package/dist/chunks/hi-VvUzjfH_.mjs +0 -2
- package/dist/chunks/hi-VvUzjfH_.mjs.map +0 -1
- package/dist/chunks/hi-jWQDQkOX.mjs +0 -2
- package/dist/chunks/hi-jWQDQkOX.mjs.map +0 -1
- package/dist/chunks/hi-l3hIrp8J.mjs +0 -2
- package/dist/chunks/hi-l3hIrp8J.mjs.map +0 -1
- package/dist/chunks/hi-o8Gsu5Ly.mjs +0 -2
- package/dist/chunks/hi-o8Gsu5Ly.mjs.map +0 -1
- package/dist/chunks/hi-sxC2nk3h.mjs +0 -2
- package/dist/chunks/hi-sxC2nk3h.mjs.map +0 -1
- package/dist/chunks/minimal-pBhi4EJI.mjs +0 -2
- package/dist/chunks/minimal-pBhi4EJI.mjs.map +0 -1
- package/dist/chunks/pt--57Ug7ig.mjs +0 -2
- package/dist/chunks/pt--57Ug7ig.mjs.map +0 -1
- package/dist/chunks/pt-4j8Km9Db.mjs +0 -2
- package/dist/chunks/pt-4j8Km9Db.mjs.map +0 -1
- package/dist/chunks/pt-BTGFKCns.mjs +0 -2
- package/dist/chunks/pt-BTGFKCns.mjs.map +0 -1
- package/dist/chunks/pt-BU8Qfuoz.mjs +0 -2
- package/dist/chunks/pt-BU8Qfuoz.mjs.map +0 -1
- package/dist/chunks/pt-BYAOJxIB.mjs +0 -2
- package/dist/chunks/pt-BYAOJxIB.mjs.map +0 -1
- package/dist/chunks/pt-BjNWQm9A.mjs +0 -2
- package/dist/chunks/pt-BjNWQm9A.mjs.map +0 -1
- package/dist/chunks/pt-Bvnb_NpT.mjs +0 -2
- package/dist/chunks/pt-Bvnb_NpT.mjs.map +0 -1
- package/dist/chunks/pt-C2pkn7vo.mjs +0 -2
- package/dist/chunks/pt-C2pkn7vo.mjs.map +0 -1
- package/dist/chunks/pt-C8MhLnWx.mjs +0 -2
- package/dist/chunks/pt-C8MhLnWx.mjs.map +0 -1
- package/dist/chunks/pt-CJfYLSTe.mjs +0 -2
- package/dist/chunks/pt-CJfYLSTe.mjs.map +0 -1
- package/dist/chunks/pt-CdwVIYOK.mjs +0 -2
- package/dist/chunks/pt-CdwVIYOK.mjs.map +0 -1
- package/dist/chunks/pt-CwrVo90O.mjs +0 -2
- package/dist/chunks/pt-CwrVo90O.mjs.map +0 -1
- package/dist/chunks/pt-DD26CKCA.mjs +0 -2
- package/dist/chunks/pt-DD26CKCA.mjs.map +0 -1
- package/dist/chunks/pt-DLbf6uoo.mjs +0 -2
- package/dist/chunks/pt-DLbf6uoo.mjs.map +0 -1
- package/dist/chunks/pt-DNyNHwKh.mjs +0 -2
- package/dist/chunks/pt-DNyNHwKh.mjs.map +0 -1
- package/dist/chunks/pt-DVfMAcXb.mjs +0 -2
- package/dist/chunks/pt-DVfMAcXb.mjs.map +0 -1
- package/dist/chunks/pt-DWSFad3n.mjs +0 -2
- package/dist/chunks/pt-DWSFad3n.mjs.map +0 -1
- package/dist/chunks/pt-DZXY4i4G.mjs +0 -2
- package/dist/chunks/pt-DZXY4i4G.mjs.map +0 -1
- package/dist/chunks/pt-DfUpRhK1.mjs +0 -2
- package/dist/chunks/pt-DfUpRhK1.mjs.map +0 -1
- package/dist/chunks/pt-DlvNEDeW.mjs +0 -2
- package/dist/chunks/pt-DlvNEDeW.mjs.map +0 -1
- package/dist/chunks/pt-DzFyGwB4.mjs +0 -2
- package/dist/chunks/pt-DzFyGwB4.mjs.map +0 -1
- package/dist/chunks/pt-HhQcARW6.mjs +0 -2
- package/dist/chunks/pt-HhQcARW6.mjs.map +0 -1
- package/dist/chunks/pt-SjvTF40s.mjs +0 -2
- package/dist/chunks/pt-SjvTF40s.mjs.map +0 -1
- package/dist/chunks/pt-ihNE0VQJ.mjs +0 -2
- package/dist/chunks/pt-ihNE0VQJ.mjs.map +0 -1
- package/dist/chunks/pt-zfCjhIgy.mjs +0 -2
- package/dist/chunks/pt-zfCjhIgy.mjs.map +0 -1
- package/dist/chunks/ru-0AHodbWv.mjs +0 -2
- package/dist/chunks/ru-0AHodbWv.mjs.map +0 -1
- package/dist/chunks/ru-2MDGmLw0.mjs +0 -2
- package/dist/chunks/ru-2MDGmLw0.mjs.map +0 -1
- package/dist/chunks/ru-3VfYKfTm.mjs +0 -2
- package/dist/chunks/ru-3VfYKfTm.mjs.map +0 -1
- package/dist/chunks/ru-B-gRJ6nQ.mjs +0 -2
- package/dist/chunks/ru-B-gRJ6nQ.mjs.map +0 -1
- package/dist/chunks/ru-B6ITUB-Y.mjs +0 -2
- package/dist/chunks/ru-B6ITUB-Y.mjs.map +0 -1
- package/dist/chunks/ru-BKDWkabk.mjs +0 -2
- package/dist/chunks/ru-BKDWkabk.mjs.map +0 -1
- package/dist/chunks/ru-BMxJsSe3.mjs +0 -2
- package/dist/chunks/ru-BMxJsSe3.mjs.map +0 -1
- package/dist/chunks/ru-Bep1iHQL.mjs +0 -2
- package/dist/chunks/ru-Bep1iHQL.mjs.map +0 -1
- package/dist/chunks/ru-Blj0nqoL.mjs +0 -2
- package/dist/chunks/ru-Blj0nqoL.mjs.map +0 -1
- package/dist/chunks/ru-BqnHkmii.mjs +0 -2
- package/dist/chunks/ru-BqnHkmii.mjs.map +0 -1
- package/dist/chunks/ru-C-4AaPUK.mjs +0 -2
- package/dist/chunks/ru-C-4AaPUK.mjs.map +0 -1
- package/dist/chunks/ru-C9Nv7JJI.mjs +0 -2
- package/dist/chunks/ru-C9Nv7JJI.mjs.map +0 -1
- package/dist/chunks/ru-CJFtr1Ks.mjs +0 -2
- package/dist/chunks/ru-CJFtr1Ks.mjs.map +0 -1
- package/dist/chunks/ru-CN63yWk_.mjs +0 -2
- package/dist/chunks/ru-CN63yWk_.mjs.map +0 -1
- package/dist/chunks/ru-CcFX97-2.mjs +0 -2
- package/dist/chunks/ru-CcFX97-2.mjs.map +0 -1
- package/dist/chunks/ru-D8PhWFSp.mjs +0 -2
- package/dist/chunks/ru-D8PhWFSp.mjs.map +0 -1
- package/dist/chunks/ru-DYAncidS.mjs +0 -2
- package/dist/chunks/ru-DYAncidS.mjs.map +0 -1
- package/dist/chunks/ru-D_zXo-FA.mjs +0 -2
- package/dist/chunks/ru-D_zXo-FA.mjs.map +0 -1
- package/dist/chunks/ru-DhSPV6m0.mjs +0 -2
- package/dist/chunks/ru-DhSPV6m0.mjs.map +0 -1
- package/dist/chunks/ru-LNbpjKCw.mjs +0 -2
- package/dist/chunks/ru-LNbpjKCw.mjs.map +0 -1
- package/dist/chunks/ru-LXi1ONW4.mjs +0 -2
- package/dist/chunks/ru-LXi1ONW4.mjs.map +0 -1
- package/dist/chunks/ru-db7wsWkx.mjs +0 -2
- package/dist/chunks/ru-db7wsWkx.mjs.map +0 -1
- package/dist/chunks/ru-nZ4BjiD0.mjs +0 -2
- package/dist/chunks/ru-nZ4BjiD0.mjs.map +0 -1
- package/dist/chunks/ru-v9zumXd2.mjs +0 -2
- package/dist/chunks/ru-v9zumXd2.mjs.map +0 -1
- package/dist/chunks/ru-wK2ytv3A.mjs +0 -2
- package/dist/chunks/ru-wK2ytv3A.mjs.map +0 -1
- package/dist/chunks/src-CNK6vpUU.mjs +0 -2
- package/dist/chunks/src-CNK6vpUU.mjs.map +0 -1
- package/dist/chunks/zh-9AcCSFm0.mjs +0 -2
- package/dist/chunks/zh-9AcCSFm0.mjs.map +0 -1
- package/dist/chunks/zh-B3bJCfdB.mjs +0 -2
- package/dist/chunks/zh-B3bJCfdB.mjs.map +0 -1
- package/dist/chunks/zh-B46Dt1h7.mjs +0 -2
- package/dist/chunks/zh-B46Dt1h7.mjs.map +0 -1
- package/dist/chunks/zh-BRy2B6Og.mjs +0 -2
- package/dist/chunks/zh-BRy2B6Og.mjs.map +0 -1
- package/dist/chunks/zh-BfYi8wB2.mjs +0 -2
- package/dist/chunks/zh-BfYi8wB2.mjs.map +0 -1
- package/dist/chunks/zh-C0I3L6NA.mjs +0 -2
- package/dist/chunks/zh-C0I3L6NA.mjs.map +0 -1
- package/dist/chunks/zh-C33e4gfg.mjs +0 -2
- package/dist/chunks/zh-C33e4gfg.mjs.map +0 -1
- package/dist/chunks/zh-C9sNwnC1.mjs +0 -2
- package/dist/chunks/zh-C9sNwnC1.mjs.map +0 -1
- package/dist/chunks/zh-CACr0qSo.mjs +0 -2
- package/dist/chunks/zh-CACr0qSo.mjs.map +0 -1
- package/dist/chunks/zh-CU0hd8zq.mjs +0 -2
- package/dist/chunks/zh-CU0hd8zq.mjs.map +0 -1
- package/dist/chunks/zh-CX2zUoWR.mjs +0 -2
- package/dist/chunks/zh-CX2zUoWR.mjs.map +0 -1
- package/dist/chunks/zh-CblZ-34H.mjs +0 -2
- package/dist/chunks/zh-CblZ-34H.mjs.map +0 -1
- package/dist/chunks/zh-CicpU0g8.mjs +0 -2
- package/dist/chunks/zh-CicpU0g8.mjs.map +0 -1
- package/dist/chunks/zh-Cr3KdEZV.mjs +0 -2
- package/dist/chunks/zh-Cr3KdEZV.mjs.map +0 -1
- package/dist/chunks/zh-D24dsCiw.mjs +0 -2
- package/dist/chunks/zh-D24dsCiw.mjs.map +0 -1
- package/dist/chunks/zh-DQtLxQ3s.mjs +0 -2
- package/dist/chunks/zh-DQtLxQ3s.mjs.map +0 -1
- package/dist/chunks/zh-DR1OF5vm.mjs +0 -2
- package/dist/chunks/zh-DR1OF5vm.mjs.map +0 -1
- package/dist/chunks/zh-DS82x1KL.mjs +0 -2
- package/dist/chunks/zh-DS82x1KL.mjs.map +0 -1
- package/dist/chunks/zh-DdJA-AEY.mjs +0 -2
- package/dist/chunks/zh-DdJA-AEY.mjs.map +0 -1
- package/dist/chunks/zh-DpVlDZ9n.mjs +0 -2
- package/dist/chunks/zh-DpVlDZ9n.mjs.map +0 -1
- package/dist/chunks/zh-OWVKcbVR.mjs +0 -2
- package/dist/chunks/zh-OWVKcbVR.mjs.map +0 -1
- package/dist/chunks/zh-d19V68ib.mjs +0 -2
- package/dist/chunks/zh-d19V68ib.mjs.map +0 -1
- package/dist/chunks/zh-fSMt1FnB.mjs +0 -2
- package/dist/chunks/zh-fSMt1FnB.mjs.map +0 -1
- package/dist/chunks/zh-mLlk9Wki.mjs +0 -2
- package/dist/chunks/zh-mLlk9Wki.mjs.map +0 -1
- package/dist/chunks/zh-nnMt8E6m.mjs +0 -2
- package/dist/chunks/zh-nnMt8E6m.mjs.map +0 -1
- package/dist/input/InternalClipboard.d.ts +0 -13
- package/dist/input/InternalClipboard.d.ts.map +0 -1
- package/dist/plugins/smart-paste/detectors/JavaDetector.d.ts +0 -7
- package/dist/plugins/smart-paste/detectors/JavaDetector.d.ts.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./Commands-ixGhPiRG.mjs";var r=class{id="hard-break";name="Hard Break";priority=10;init(e){this.registerInlineNodeSpec(e),this.registerCommands(e),this.registerKeymap(e)}registerInlineNodeSpec(e){e.registerInlineNodeSpec({type:"hard_break",toDOM:()=>document.createElement("br"),toHTMLString:()=>"<br>",parseHTML:[{tag:"br"}],sanitize:{tags:["br"]}})}registerCommands(r){r.registerCommand("insertHardBreak",()=>{const t=e(r.getState());return!!t&&(r.dispatch(t),!0)})}registerKeymap(r){r.registerKeymap({"Shift-Enter":()=>{const t=e(r.getState());return!!t&&(r.dispatch(t),!0)}})}};export{r as t};
|
|
2
|
+
//# sourceMappingURL=HardBreakPlugin-Cr6dMQ-H.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HardBreakPlugin-Cr6dMQ-H.mjs","names":[],"sources":["../../src/plugins/hard-break/HardBreakPlugin.ts"],"sourcesContent":["/**\n * HardBreakPlugin: registers a hard line break (Shift+Enter → `<br>`)\n * as an InlineNode, with command and keymap bindings.\n */\n\nimport { insertHardBreakCommand } from '../../commands/Commands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface InlineNodeAttrRegistry {\n\t\thard_break: Record<string, never>;\n\t}\n}\n\n// --- Plugin ---\n\nexport class HardBreakPlugin implements Plugin {\n\treadonly id = 'hard-break';\n\treadonly name = 'Hard Break';\n\treadonly priority = 10;\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerInlineNodeSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymap(context);\n\t}\n\n\tprivate registerInlineNodeSpec(context: PluginContext): void {\n\t\tcontext.registerInlineNodeSpec({\n\t\t\ttype: 'hard_break',\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement('br');\n\t\t\t},\n\t\t\ttoHTMLString() {\n\t\t\t\treturn '<br>';\n\t\t\t},\n\t\t\tparseHTML: [{ tag: 'br' }],\n\t\t\tsanitize: { tags: ['br'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('insertHardBreak', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst tr = insertHardBreakCommand(state);\n\t\t\tif (!tr) return false;\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t});\n\t}\n\n\tprivate registerKeymap(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Shift-Enter': () => {\n\t\t\t\tconst state = context.getState();\n\t\t\t\tconst tr = insertHardBreakCommand(state);\n\t\t\t\tif (!tr) return false;\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t});\n\t}\n}\n"],"mappings":"4CAkBA,IAAa,EAAb,MACC,GAAc,aACd,KAAgB,aAChB,SAAoB,GAEpB,IAAA,CAAK,GACJ,KAAK,uBAAuB,GAC5B,KAAK,iBAAiB,GACtB,KAAK,eAAe,GAGrB,sBAAA,CAA+B,GAC9B,EAAQ,uBAAuB,CAC9B,KAAM,aACN,MAAA,IACQ,SAAS,cAAc,MAE/B,aAAA,IACQ,OAER,UAAW,CAAC,CAAE,IAAK,OACnB,SAAU,CAAE,KAAM,CAAC,SAIrB,gBAAA,CAAyB,GACxB,EAAQ,gBAAgB,kBAAA,KAEvB,MAAM,EAAK,EADG,EAAQ,YAEtB,QAAK,IACL,EAAQ,SAAS,IACV,KAIT,cAAA,CAAuB,GACtB,EAAQ,eAAe,CACtB,cAAA,KAEC,MAAM,EAAK,EADG,EAAQ,YAEtB,QAAK,IACL,EAAQ,SAAS,IACV"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{T as t,f as e,h as n,l as o,v as i}from"./Document-znhIcvM9.mjs";import{o as r,t as a,u as s}from"./Selection-aeiSsvhe.mjs";import{a as c}from"./TypeBrands-BZDKMjR-.mjs";import{n as l}from"./DomUtils-RKbAVBQz.mjs";import{o as g}from"./StyleRuntime-Bwde5icB.mjs";import{a as p,s as d}from"./PluginHelpers-C3aCCGfX.mjs";function h(t,e,n,o){const i=document.createElement("button");i.type="button",i.className="notectl-heading-picker__item",i.setAttribute("role","option"),i.setAttribute("aria-selected",String(e)),e&&i.classList.add("notectl-heading-picker__item--active");const r=document.createElement("span");r.className="notectl-heading-picker__check",r.textContent=e?"✓":"",i.appendChild(r);const a=document.createElement("span");return a.className="notectl-heading-picker__label",a.textContent=t,o&&g(a,{fontSize:o.fontSize,fontWeight:o.fontWeight}),i.appendChild(a),i.addEventListener("mousedown",n),i}function u(t,e){return t[`heading${e}`]}function m(t,e){const n=t.getState();if(!s(n.selection))return!1;const o=n.getBlock(n.selection.anchor.blockId);return!!o&&(o.type===e?k(t,c("paragraph")):k(t,c(e)))}function f(t,e){const n=t.getState(),o=n.selection;if(!s(o))return!1;const i=n.getBlock(o.anchor.blockId);return!!i&&("heading"===i.type&&i.attrs?.level===e?k(t,c("paragraph")):k(t,c("heading"),{level:e}))}function k(n,o,r){const a=n.getState(),c=a.selection;if(!s(c))return!1;const l=a.getBlock(c.anchor.blockId);if(!l)return!1;const g=a.transaction("command"),p=n.getSchemaRegistry().getNodeSpec(o);p?.excludeMarks&&p.excludeMarks.length>0&&(function(n,o,r){if(0===e(o))return;const a=new Set(r),s=i(o);let c=0;for(const e of s)if(t(e)){if(e.text.length>0)for(const t of e.marks)a.has(t.type)&&n.removeMark(o.id,c,c+e.text.length,t);c+=e.text.length}else c+=1}(g,l,p.excludeMarks),function(t,e,n){if(!e.storedMarks)return;const o=new Set(n),i=e.storedMarks.filter(t=>!o.has(t.type));i.length!==e.storedMarks.length&&t.setStoredMarks(i.length>0?i:null,e.storedMarks)}(g,a,p.excludeMarks));const d=g.setBlockType(c.anchor.blockId,o,r).setSelection(c).build();return n.dispatch(d),!0}var b=new Set(["heading","title","subtitle"]);var y={paragraph:"Paragraph",title:"Title",subtitle:"Subtitle",heading1:"Heading 1",heading2:"Heading 2",heading3:"Heading 3",heading4:"Heading 4",heading5:"Heading 5",heading6:"Heading 6",blockTypeLabel:"Block Type",blockTypesAria:"Block types"},v=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-D5d185g0.mjs"),"./locales/de.ts":()=>import("./de-pnfTnS03.mjs"),"./locales/es.ts":()=>import("./es-D0427MIH.mjs"),"./locales/fr.ts":()=>import("./fr-gdIyLcGC.mjs"),"./locales/hi.ts":()=>import("./hi-CnIpMd8L.mjs"),"./locales/pt.ts":()=>import("./pt-aj7zOxTg.mjs"),"./locales/ru.ts":()=>import("./ru-BnNdik6i.mjs"),"./locales/zh.ts":()=>import("./zh-DZwjiJmn.mjs")});async function x(t){return d(v,t,y)}var S={levels:[1,2,3,4,5,6]},T={1:"h1",2:"h2",3:"h3",4:"h4",5:"h5",6:"h6"},B=class{id="heading";name="Heading";priority=30;config;locale;constructor(t){this.config={...S,...t}}async init(t){this.locale=await p(t,this.config.locale,y,x),t.registerStyleSheet("\n/* Heading Select — Width overrides for combobox button */\n.notectl-toolbar-btn--heading {\n\tmin-width: 100px;\n\tmax-width: 160px;\n}\n\n/* Heading Picker Popup */\n.notectl-heading-picker {\n\tmin-width: 200px;\n\tmax-height: 320px;\n\toverflow-y: auto;\n}\n\n.notectl-heading-picker__list {\n\tpadding: 4px 0;\n}\n\n.notectl-heading-picker__item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\twidth: 100%;\n\tpadding: 7px 12px;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: var(--notectl-fg);\n\ttext-align: start;\n\twhite-space: nowrap;\n\tfont-family: inherit;\n\ttransition: background 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-heading-picker__item:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-heading-picker__item--active {\n\tbackground: var(--notectl-active-bg);\n\tcolor: var(--notectl-primary-fg);\n}\n\n@media (hover: hover) {\n\t.notectl-heading-picker__item--active:hover {\n\t\tbackground: var(--notectl-active-bg);\n\t}\n}\n\n.notectl-heading-picker__check {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 16px;\n\tflex-shrink: 0;\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-heading-picker__label {\n\tflex: 1;\n}\n"),this.registerNodeSpecs(t),function(t,e){t.registerCommand("setTitle",()=>m(t,"title")),t.registerCommand("setSubtitle",()=>m(t,"subtitle"));for(const n of e.levels)t.registerCommand(`setHeading${n}`,()=>f(t,n));t.registerCommand("toggleHeading",()=>f(t,1)),t.registerCommand("setParagraph",()=>k(t,c("paragraph")))}(t,this.config),function(t,i){const l={Enter:()=>function(t){return function(t,e){const n=t.getState();if(!s(n.selection))return!1;const o=n.selection;if(!r(o))return!1;const i=n.getBlock(o.anchor.blockId);return!(!i||!b.has(i.type))&&e({state:n,block:i,blockId:o.anchor.blockId,offset:o.anchor.offset})}(t,i=>{if(""===n(i.block)){const e=i.state.transaction("input").setBlockType(i.blockId,c("paragraph")).setSelection(i.state.selection).build();return t.dispatch(e),!0}const r=e(i.block);if(i.offset>=r){const e=o(),n=i.state.transaction("input").splitBlock(i.blockId,i.offset,e).setBlockType(e,c("paragraph")).setSelection(a(e,0)).build();return t.dispatch(n),!0}return!1})}(t)};for(const e of i.levels)e<=6&&(l[`Mod-Shift-${e}`]=()=>t.executeCommand(`setHeading${e}`));t.registerKeymap(l)}(t,this.config),function(t,e){for(const n of e.levels){const e="#".repeat(n),o=new RegExp(`^${e} $`);t.registerInputRule({pattern:o,handler(t,e,o,i){const l=t.selection;if(!s(l))return null;if(!r(l))return null;const g=t.getBlock(l.anchor.blockId);return g&&"paragraph"===g.type?t.transaction("input").deleteTextAt(l.anchor.blockId,o,o+n+1).setBlockType(l.anchor.blockId,c("heading"),{level:n}).setSelection(a(l.anchor.blockId,0)).build():null}})}}(t,this.config),function(t,e,n){t.registerBlockTypePickerEntry({id:"paragraph",label:n.paragraph,command:"setParagraph",priority:10,isActive:t=>!!s(t.selection)&&"paragraph"===t.getBlock(t.selection.anchor.blockId)?.type}),t.registerBlockTypePickerEntry({id:"title",label:n.title,command:"setTitle",priority:20,style:{fontSize:"1.6em",fontWeight:"700"},isActive:t=>!!s(t.selection)&&"title"===t.getBlock(t.selection.anchor.blockId)?.type}),t.registerBlockTypePickerEntry({id:"subtitle",label:n.subtitle,command:"setSubtitle",priority:30,style:{fontSize:"1.3em",fontWeight:"500"},isActive:t=>!!s(t.selection)&&"subtitle"===t.getBlock(t.selection.anchor.blockId)?.type});for(const o of e.levels)t.registerBlockTypePickerEntry({id:`heading-${o}`,label:u(n,o),command:`setHeading${o}`,priority:100+o,style:{fontSize:1.4-.1*o+"em",fontWeight:"600"},isActive:t=>{if(!s(t.selection))return!1;const e=t.getBlock(t.selection.anchor.blockId);return"heading"===e?.type&&e.attrs?.level===o}})}(t,this.config,this.locale),function(t,e){t.registerToolbarItem({id:"heading",group:"block",label:e.blockTypeLabel,tooltip:e.blockTypeLabel,command:"setParagraph",popupType:"combobox",getLabel:n=>function(t,e,n){if(!s(t.selection))return n.paragraph;const o=e.getBlockTypePickerRegistry().getBlockTypePickerEntries();for(const i of o)if(i.isActive(t))return i.label;return n.paragraph}(n,t,e),renderPopup:(t,n,o)=>{!function(t,e,n,o){t.classList.add("notectl-heading-picker");const i=e.getState();if(!s(i.selection))return;const r=e.getContainer(),a=document.createElement("div");a.className="notectl-heading-picker__list",a.setAttribute("role","listbox"),a.setAttribute("aria-label",n.blockTypesAria);const c=e.getBlockTypePickerRegistry().getBlockTypePickerEntries();for(const s of c){const t=s.isActive(i);a.appendChild(h(s.label,t,t=>{t.preventDefault(),t.stopPropagation(),e.executeCommand(s.command),o({restoreFocusTo:r})},s.style))}t.appendChild(a)}(t,n,e,o)},isActive:e=>t.getBlockTypePickerRegistry().getBlockTypePickerEntries().some(t=>"paragraph"!==t.id&&t.isActive(e))})}(t,this.locale)}registerNodeSpecs(t){t.registerNodeSpec({type:"title",group:"block",content:{allow:["text"]},excludeMarks:["fontSize"],toDOM(t){const e=l("h1",t.id);return e.classList.add("notectl-title"),e},toHTML:(t,e)=>`<h1 class="notectl-title">${e||"<br>"}</h1>`,parseHTML:[{tag:"h1",priority:60,getAttrs:t=>!!t.classList.contains("notectl-title")&&{}}],sanitize:{tags:["h1"],attrs:["class"]}}),t.registerNodeSpec({type:"subtitle",group:"block",content:{allow:["text"]},excludeMarks:["fontSize"],toDOM(t){const e=l("h2",t.id);return e.classList.add("notectl-subtitle"),e},toHTML:(t,e)=>`<h2 class="notectl-subtitle">${e||"<br>"}</h2>`,parseHTML:[{tag:"h2",priority:60,getAttrs:t=>!!t.classList.contains("notectl-subtitle")&&{}}],sanitize:{tags:["h2"],attrs:["class"]}}),t.registerNodeSpec({type:"heading",group:"block",content:{allow:["text"]},excludeMarks:["fontSize"],attrs:{level:{default:1}},toDOM:t=>l(T[t.attrs?.level??1]??"h1",t.id),toHTML(t,e){const n=T[t.attrs?.level??1]??"h1";return`<${n}>${e||"<br>"}</${n}>`},parseHTML:[{tag:"h1",getAttrs:()=>({level:1})},{tag:"h2",getAttrs:()=>({level:2})},{tag:"h3",getAttrs:()=>({level:3})},{tag:"h4",getAttrs:()=>({level:4})},{tag:"h5",getAttrs:()=>({level:5})},{tag:"h6",getAttrs:()=>({level:6})}],sanitize:{tags:["h1","h2","h3","h4","h5","h6"]}})}};export{y as n,x as r,B as t};
|
|
2
|
+
//# sourceMappingURL=HeadingPlugin-3NL4ARPp.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HeadingPlugin-3NL4ARPp.mjs","names":[],"sources":["../../src/editor/styles/heading-select.ts","../../src/plugins/heading/HeadingBlockTypePicker.ts","../../src/plugins/heading/HeadingCommands.ts","../../src/plugins/heading/HeadingInputRules.ts","../../src/plugins/heading/HeadingKeyboardHandlers.ts","../../src/plugins/heading/HeadingLocale.ts","../../src/plugins/heading/HeadingPlugin.ts"],"sourcesContent":["/** Heading picker toolbar combobox + popup styles. */\nexport const HEADING_SELECT_CSS = `\n/* Heading Select — Width overrides for combobox button */\n.notectl-toolbar-btn--heading {\n\tmin-width: 100px;\n\tmax-width: 160px;\n}\n\n/* Heading Picker Popup */\n.notectl-heading-picker {\n\tmin-width: 200px;\n\tmax-height: 320px;\n\toverflow-y: auto;\n}\n\n.notectl-heading-picker__list {\n\tpadding: 4px 0;\n}\n\n.notectl-heading-picker__item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\twidth: 100%;\n\tpadding: 7px 12px;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: var(--notectl-fg);\n\ttext-align: start;\n\twhite-space: nowrap;\n\tfont-family: inherit;\n\ttransition: background 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-heading-picker__item:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-heading-picker__item--active {\n\tbackground: var(--notectl-active-bg);\n\tcolor: var(--notectl-primary-fg);\n}\n\n@media (hover: hover) {\n\t.notectl-heading-picker__item--active:hover {\n\t\tbackground: var(--notectl-active-bg);\n\t}\n}\n\n.notectl-heading-picker__check {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 16px;\n\tflex-shrink: 0;\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-heading-picker__label {\n\tflex: 1;\n}\n`;\n","/**\n * Block type picker entries and toolbar dropdown for heading block types.\n * Registers picker entries for paragraph, title, subtitle, and all heading levels,\n * plus a combobox-style toolbar item with a custom popup.\n */\n\nimport { isTextSelection } from '../../model/Selection.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport { setStyleProperties } from '../../style/StyleRuntime.js';\nimport type { PluginContext } from '../Plugin.js';\nimport type { PopupCloseOptions } from '../shared/PopupManager.js';\nimport type { PickerEntryStyle } from './BlockTypePickerEntry.js';\nimport type { HeadingLocale } from './HeadingLocale.js';\nimport type { HeadingConfig } from './HeadingPlugin.js';\nimport type { HeadingLevel } from './HeadingPlugin.js';\n\n// --- Picker Entry Registration ---\n\n/** Registers block type picker entries for paragraph, title, subtitle, and heading levels. */\nexport function registerHeadingPickerEntries(\n\tcontext: PluginContext,\n\tconfig: HeadingConfig,\n\tlocale: HeadingLocale,\n): void {\n\tcontext.registerBlockTypePickerEntry({\n\t\tid: 'paragraph',\n\t\tlabel: locale.paragraph,\n\t\tcommand: 'setParagraph',\n\t\tpriority: 10,\n\t\tisActive: (state) => {\n\t\t\tif (!isTextSelection(state.selection)) return false;\n\t\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\t\treturn block?.type === 'paragraph';\n\t\t},\n\t});\n\n\tcontext.registerBlockTypePickerEntry({\n\t\tid: 'title',\n\t\tlabel: locale.title,\n\t\tcommand: 'setTitle',\n\t\tpriority: 20,\n\t\tstyle: { fontSize: '1.6em', fontWeight: '700' },\n\t\tisActive: (state) => {\n\t\t\tif (!isTextSelection(state.selection)) return false;\n\t\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\t\treturn block?.type === 'title';\n\t\t},\n\t});\n\n\tcontext.registerBlockTypePickerEntry({\n\t\tid: 'subtitle',\n\t\tlabel: locale.subtitle,\n\t\tcommand: 'setSubtitle',\n\t\tpriority: 30,\n\t\tstyle: { fontSize: '1.3em', fontWeight: '500' },\n\t\tisActive: (state) => {\n\t\t\tif (!isTextSelection(state.selection)) return false;\n\t\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\t\treturn block?.type === 'subtitle';\n\t\t},\n\t});\n\n\tfor (const level of config.levels) {\n\t\tcontext.registerBlockTypePickerEntry({\n\t\t\tid: `heading-${level}`,\n\t\t\tlabel: getHeadingLabel(locale, level),\n\t\t\tcommand: `setHeading${level}`,\n\t\t\tpriority: 100 + level,\n\t\t\tstyle: { fontSize: `${1.4 - level * 0.1}em`, fontWeight: '600' },\n\t\t\tisActive: (state) => {\n\t\t\t\tif (!isTextSelection(state.selection)) return false;\n\t\t\t\tconst block = state.getBlock(state.selection.anchor.blockId);\n\t\t\t\treturn block?.type === 'heading' && block.attrs?.level === level;\n\t\t\t},\n\t\t});\n\t}\n}\n\n// --- Toolbar Item ---\n\n/** Registers the heading toolbar dropdown with a combobox picker popup. */\nexport function registerHeadingToolbarItem(context: PluginContext, locale: HeadingLocale): void {\n\tcontext.registerToolbarItem({\n\t\tid: 'heading',\n\t\tgroup: 'block',\n\t\tlabel: locale.blockTypeLabel,\n\t\ttooltip: locale.blockTypeLabel,\n\t\tcommand: 'setParagraph',\n\t\tpopupType: 'combobox',\n\t\tgetLabel: (state: EditorState): string => getActiveLabel(state, context, locale),\n\t\trenderPopup: (container, ctx, onClose) => {\n\t\t\trenderHeadingPopup(container, ctx, locale, onClose);\n\t\t},\n\t\tisActive: (state) => {\n\t\t\tconst entries = context.getBlockTypePickerRegistry().getBlockTypePickerEntries();\n\t\t\treturn entries.some((entry) => entry.id !== 'paragraph' && entry.isActive(state));\n\t\t},\n\t});\n}\n\n// --- Popup Rendering ---\n\nfunction renderHeadingPopup(\n\tcontainer: HTMLElement,\n\tcontext: PluginContext,\n\tlocale: HeadingLocale,\n\tonClose: (options?: PopupCloseOptions) => void,\n): void {\n\tcontainer.classList.add('notectl-heading-picker');\n\n\tconst state: EditorState = context.getState();\n\tif (!isTextSelection(state.selection)) return;\n\n\tconst contentElement: HTMLElement = context.getContainer();\n\n\tconst list: HTMLDivElement = document.createElement('div');\n\tlist.className = 'notectl-heading-picker__list';\n\tlist.setAttribute('role', 'listbox');\n\tlist.setAttribute('aria-label', locale.blockTypesAria);\n\n\tconst entries = context.getBlockTypePickerRegistry().getBlockTypePickerEntries();\n\tfor (const entry of entries) {\n\t\tconst active: boolean = entry.isActive(state);\n\t\tlist.appendChild(\n\t\t\tcreatePickerItem(\n\t\t\t\tentry.label,\n\t\t\t\tactive,\n\t\t\t\t(e: MouseEvent) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tcontext.executeCommand(entry.command);\n\t\t\t\t\tonClose({ restoreFocusTo: contentElement });\n\t\t\t\t},\n\t\t\t\tentry.style,\n\t\t\t),\n\t\t);\n\t}\n\n\tcontainer.appendChild(list);\n}\n\nfunction createPickerItem(\n\tlabel: string,\n\tisActive: boolean,\n\thandler: (e: MouseEvent) => void,\n\tstyle?: PickerEntryStyle,\n): HTMLButtonElement {\n\tconst item: HTMLButtonElement = document.createElement('button');\n\titem.type = 'button';\n\titem.className = 'notectl-heading-picker__item';\n\titem.setAttribute('role', 'option');\n\titem.setAttribute('aria-selected', String(isActive));\n\n\tif (isActive) {\n\t\titem.classList.add('notectl-heading-picker__item--active');\n\t}\n\n\tconst check: HTMLSpanElement = document.createElement('span');\n\tcheck.className = 'notectl-heading-picker__check';\n\tcheck.textContent = isActive ? '\\u2713' : '';\n\titem.appendChild(check);\n\n\tconst labelSpan: HTMLSpanElement = document.createElement('span');\n\tlabelSpan.className = 'notectl-heading-picker__label';\n\tlabelSpan.textContent = label;\n\tif (style) {\n\t\tsetStyleProperties(labelSpan, {\n\t\t\tfontSize: style.fontSize,\n\t\t\tfontWeight: style.fontWeight,\n\t\t});\n\t}\n\titem.appendChild(labelSpan);\n\n\titem.addEventListener('mousedown', handler);\n\treturn item;\n}\n\n// --- Helpers ---\n\nfunction getHeadingLabel(locale: HeadingLocale, level: HeadingLevel): string {\n\tconst key = `heading${level}` as keyof HeadingLocale;\n\treturn locale[key] as string;\n}\n\nfunction getActiveLabel(state: EditorState, context: PluginContext, locale: HeadingLocale): string {\n\tif (!isTextSelection(state.selection)) return locale.paragraph;\n\tconst entries = context.getBlockTypePickerRegistry().getBlockTypePickerEntries();\n\tfor (const entry of entries) {\n\t\tif (entry.isActive(state)) return entry.label;\n\t}\n\treturn locale.paragraph;\n}\n","/**\n * Command registration and implementations for heading block types.\n * Handles toggle between heading/title/subtitle and paragraph,\n * plus excluded-mark stripping when switching block types.\n */\n\nimport type { BlockNode, Mark } from '../../model/Document.js';\nimport { getBlockLength, getInlineChildren, isTextNode } from '../../model/Document.js';\nimport { isTextSelection } from '../../model/Selection.js';\nimport { type NodeTypeName, nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { TransactionBuilder } from '../../state/Transaction.js';\nimport type { PluginContext } from '../Plugin.js';\nimport type { HeadingConfig, HeadingLevel } from './HeadingPlugin.js';\n\n/** Registers all heading commands (setTitle, setSubtitle, setHeadingN, toggleHeading, setParagraph). */\nexport function registerHeadingCommands(context: PluginContext, config: HeadingConfig): void {\n\tcontext.registerCommand('setTitle', () => toggleSpecialBlock(context, 'title'));\n\n\tcontext.registerCommand('setSubtitle', () => toggleSpecialBlock(context, 'subtitle'));\n\n\tfor (const level of config.levels) {\n\t\tcontext.registerCommand(`setHeading${level}`, () => toggleHeading(context, level));\n\t}\n\n\tcontext.registerCommand('toggleHeading', () => toggleHeading(context, 1));\n\n\tcontext.registerCommand('setParagraph', () => setBlockType(context, nodeType('paragraph')));\n}\n\n// --- Command Implementations ---\n\n/**\n * Toggles between a special block type (title/subtitle) and paragraph.\n * If the block is already that type, resets to paragraph.\n */\nfunction toggleSpecialBlock(context: PluginContext, type: string): boolean {\n\tconst state: EditorState = context.getState();\n\tif (!isTextSelection(state.selection)) return false;\n\n\tconst block: BlockNode | undefined = state.getBlock(state.selection.anchor.blockId);\n\tif (!block) return false;\n\n\tif (block.type === type) {\n\t\treturn setBlockType(context, nodeType('paragraph'));\n\t}\n\n\treturn setBlockType(context, nodeType(type) as NodeTypeName);\n}\n\n/**\n * Toggles between heading (at given level) and paragraph.\n * If the block is already a heading at the same level, resets to paragraph.\n */\nfunction toggleHeading(context: PluginContext, level: HeadingLevel): boolean {\n\tconst state: EditorState = context.getState();\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return false;\n\n\tconst block: BlockNode | undefined = state.getBlock(sel.anchor.blockId);\n\tif (!block) return false;\n\n\tif (block.type === 'heading' && block.attrs?.level === level) {\n\t\treturn setBlockType(context, nodeType('paragraph'));\n\t}\n\n\treturn setBlockType(context, nodeType('heading'), { level });\n}\n\nfunction setBlockType(\n\tcontext: PluginContext,\n\ttype: NodeTypeName,\n\tattrs?: Record<string, string | number | boolean>,\n): boolean {\n\tconst state: EditorState = context.getState();\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return false;\n\n\tconst block: BlockNode | undefined = state.getBlock(sel.anchor.blockId);\n\tif (!block) return false;\n\n\tconst builder: TransactionBuilder = state.transaction('command');\n\n\tconst spec = context.getSchemaRegistry().getNodeSpec(type);\n\tif (spec?.excludeMarks && spec.excludeMarks.length > 0) {\n\t\tstripExcludedMarks(builder, block, spec.excludeMarks);\n\t\tclearExcludedStoredMarks(builder, state, spec.excludeMarks);\n\t}\n\n\tconst tr = builder.setBlockType(sel.anchor.blockId, type, attrs).setSelection(sel).build();\n\tcontext.dispatch(tr);\n\treturn true;\n}\n\n// --- Mark Stripping Helpers ---\n\n/**\n * Adds removeMark steps for each excluded mark type found\n * on the block's inline text content.\n */\nfunction stripExcludedMarks(\n\tbuilder: TransactionBuilder,\n\tblock: BlockNode,\n\texcludeMarks: readonly string[],\n): void {\n\tconst blockLength: number = getBlockLength(block);\n\tif (blockLength === 0) return;\n\n\tconst excludeSet: Set<string> = new Set(excludeMarks);\n\tconst inlineChildren = getInlineChildren(block);\n\tlet offset = 0;\n\n\tfor (const child of inlineChildren) {\n\t\tif (isTextNode(child)) {\n\t\t\tif (child.text.length > 0) {\n\t\t\t\tfor (const mark of child.marks) {\n\t\t\t\t\tif (excludeSet.has(mark.type)) {\n\t\t\t\t\t\tbuilder.removeMark(block.id, offset, offset + child.text.length, mark);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\toffset += child.text.length;\n\t\t} else {\n\t\t\toffset += 1;\n\t\t}\n\t}\n}\n\n/**\n * Clears excluded mark types from stored marks so that\n * subsequent typing does not reintroduce them.\n */\nfunction clearExcludedStoredMarks(\n\tbuilder: TransactionBuilder,\n\tstate: EditorState,\n\texcludeMarks: readonly string[],\n): void {\n\tif (!state.storedMarks) return;\n\n\tconst excludeSet: Set<string> = new Set(excludeMarks);\n\tconst filtered: readonly Mark[] = state.storedMarks.filter((m: Mark) => !excludeSet.has(m.type));\n\n\tif (filtered.length !== state.storedMarks.length) {\n\t\tbuilder.setStoredMarks(filtered.length > 0 ? filtered : null, state.storedMarks);\n\t}\n}\n","/**\n * Input rule registration for heading block types.\n * Converts `# `, `## `, etc. at the start of a paragraph into headings.\n */\n\nimport { createCollapsedSelection, isCollapsed, isTextSelection } from '../../model/Selection.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { PluginContext } from '../Plugin.js';\nimport type { HeadingConfig } from './HeadingPlugin.js';\n\n/** Registers markdown-style input rules (e.g. `# ` → H1) for configured heading levels. */\nexport function registerHeadingInputRules(context: PluginContext, config: HeadingConfig): void {\n\tfor (const level of config.levels) {\n\t\tconst hashes: string = '#'.repeat(level);\n\t\tconst pattern: RegExp = new RegExp(`^${hashes} $`);\n\n\t\tcontext.registerInputRule({\n\t\t\tpattern,\n\t\t\thandler(state, _match, start, _end) {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\tif (!isTextSelection(sel)) return null;\n\t\t\t\tif (!isCollapsed(sel)) return null;\n\n\t\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\t\tif (!block || block.type !== 'paragraph') return null;\n\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.deleteTextAt(sel.anchor.blockId, start, start + level + 1)\n\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('heading'), { level })\n\t\t\t\t\t.setSelection(createCollapsedSelection(sel.anchor.blockId, 0))\n\t\t\t\t\t.build();\n\t\t\t},\n\t\t});\n\t}\n}\n","/**\n * Keyboard handlers for heading block types.\n * Handles Enter key behavior: empty heading → paragraph, cursor at end → split + paragraph.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { generateBlockId, getBlockLength, getBlockText } from '../../model/Document.js';\nimport { createCollapsedSelection, isCollapsed, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { PluginContext } from '../Plugin.js';\nimport type { HeadingConfig } from './HeadingPlugin.js';\n\n// --- Context Guard ---\n\nconst HEADING_TYPES: ReadonlySet<string> = new Set(['heading', 'title', 'subtitle']);\n\ninterface HeadingContext {\n\treadonly state: EditorState;\n\treadonly block: BlockNode;\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n}\n\n/**\n * Guards against NodeSelection, non-collapsed selections, and non-heading blocks.\n * Returns false (not handled) if the cursor is not inside a heading-type block.\n */\nfunction withHeadingContext(\n\tcontext: PluginContext,\n\thandler: (ctx: HeadingContext) => boolean,\n): boolean {\n\tconst state: EditorState = context.getState();\n\tif (!isTextSelection(state.selection)) return false;\n\n\tconst sel = state.selection;\n\tif (!isCollapsed(sel)) return false;\n\n\tconst block: BlockNode | undefined = state.getBlock(sel.anchor.blockId);\n\tif (!block || !HEADING_TYPES.has(block.type)) return false;\n\n\treturn handler({\n\t\tstate,\n\t\tblock,\n\t\tblockId: sel.anchor.blockId,\n\t\toffset: sel.anchor.offset,\n\t});\n}\n\n/** Registers all heading keyboard handlers (Enter, Mod-Shift-N shortcuts). */\nexport function registerHeadingKeymaps(context: PluginContext, config: HeadingConfig): void {\n\tconst keymap: Record<string, () => boolean> = {\n\t\tEnter: () => handleEnter(context),\n\t};\n\n\tfor (const level of config.levels) {\n\t\tif (level <= 6) {\n\t\t\tkeymap[`Mod-Shift-${level}`] = () => context.executeCommand(`setHeading${level}`);\n\t\t}\n\t}\n\n\tcontext.registerKeymap(keymap);\n}\n\n// --- Enter Handler ---\n\n/**\n * Handles Enter inside a heading block.\n * Empty heading → convert to paragraph.\n * Cursor at end → split and convert new block to paragraph.\n * Cursor in middle → normal split (both stay heading).\n */\nfunction handleEnter(context: PluginContext): boolean {\n\treturn withHeadingContext(context, (ctx) => {\n\t\tconst text: string = getBlockText(ctx.block);\n\n\t\tif (text === '') {\n\t\t\tconst tr = ctx.state\n\t\t\t\t.transaction('input')\n\t\t\t\t.setBlockType(ctx.blockId, nodeType('paragraph'))\n\t\t\t\t.setSelection(ctx.state.selection)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst blockLength: number = getBlockLength(ctx.block);\n\n\t\tif (ctx.offset >= blockLength) {\n\t\t\tconst newBlockId = generateBlockId();\n\t\t\tconst tr = ctx.state\n\t\t\t\t.transaction('input')\n\t\t\t\t.splitBlock(ctx.blockId, ctx.offset, newBlockId)\n\t\t\t\t.setBlockType(newBlockId, nodeType('paragraph'))\n\t\t\t\t.setSelection(createCollapsedSelection(newBlockId, 0))\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t});\n}\n","/**\n * Locale interface and default English locale for the HeadingPlugin.\n */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface HeadingLocale {\n\treadonly paragraph: string;\n\treadonly title: string;\n\treadonly subtitle: string;\n\treadonly heading1: string;\n\treadonly heading2: string;\n\treadonly heading3: string;\n\treadonly heading4: string;\n\treadonly heading5: string;\n\treadonly heading6: string;\n\treadonly blockTypeLabel: string;\n\treadonly blockTypesAria: string;\n}\n\n// --- Default English Locale ---\n\nexport const HEADING_LOCALE_EN: HeadingLocale = {\n\tparagraph: 'Paragraph',\n\ttitle: 'Title',\n\tsubtitle: 'Subtitle',\n\theading1: 'Heading 1',\n\theading2: 'Heading 2',\n\theading3: 'Heading 3',\n\theading4: 'Heading 4',\n\theading5: 'Heading 5',\n\theading6: 'Heading 6',\n\tblockTypeLabel: 'Block Type',\n\tblockTypesAria: 'Block types',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<HeadingLocale> = import.meta.glob<{\n\tdefault: HeadingLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadHeadingLocale(lang: string): Promise<HeadingLocale> {\n\treturn loadLocaleModule(localeModules, lang, HEADING_LOCALE_EN);\n}\n","/**\n * HeadingPlugin: registers Title, Subtitle, and H1–H6 heading block types\n * with NodeSpec, toggle commands, keyboard shortcuts, input rules, and a\n * combobox-style toolbar dropdown that reflects the current block type.\n *\n * This file is a thin orchestrator — command logic, input rules, keyboard\n * handlers, and picker/toolbar rendering are delegated to dedicated modules.\n */\n\nimport { HEADING_SELECT_CSS } from '../../editor/styles/heading-select.js';\nimport type { BlockAlignment } from '../../model/BlockAlignment.js';\nimport { createBlockElement } from '../../view/DomUtils.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport {\n\tregisterHeadingPickerEntries,\n\tregisterHeadingToolbarItem,\n} from './HeadingBlockTypePicker.js';\nimport { registerHeadingCommands } from './HeadingCommands.js';\nimport { registerHeadingInputRules } from './HeadingInputRules.js';\nimport { registerHeadingKeymaps } from './HeadingKeyboardHandlers.js';\nimport { HEADING_LOCALE_EN, type HeadingLocale, loadHeadingLocale } from './HeadingLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\theading: { level: HeadingLevel; align?: BlockAlignment };\n\t\ttitle: { align?: BlockAlignment };\n\t\tsubtitle: { align?: BlockAlignment };\n\t}\n}\n\n// --- Configuration ---\n\nexport type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;\n\nexport interface HeadingConfig {\n\t/** Which heading levels to enable. Defaults to [1, 2, 3, 4, 5, 6]. */\n\treadonly levels: readonly HeadingLevel[];\n\treadonly locale?: HeadingLocale;\n}\n\nconst DEFAULT_CONFIG: HeadingConfig = {\n\tlevels: [1, 2, 3, 4, 5, 6],\n};\n\n// --- Heading Tag Mapping ---\n\nconst HEADING_TAGS: Record<HeadingLevel, string> = {\n\t1: 'h1',\n\t2: 'h2',\n\t3: 'h3',\n\t4: 'h4',\n\t5: 'h5',\n\t6: 'h6',\n};\n\n// --- Plugin ---\n\nexport class HeadingPlugin implements Plugin {\n\treadonly id = 'heading';\n\treadonly name = 'Heading';\n\treadonly priority = 30;\n\n\tprivate readonly config: HeadingConfig;\n\tprivate locale!: HeadingLocale;\n\n\tconstructor(config?: Partial<HeadingConfig>) {\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\tHEADING_LOCALE_EN,\n\t\t\tloadHeadingLocale,\n\t\t);\n\t\tcontext.registerStyleSheet(HEADING_SELECT_CSS);\n\n\t\tthis.registerNodeSpecs(context);\n\t\tregisterHeadingCommands(context, this.config);\n\t\tregisterHeadingKeymaps(context, this.config);\n\t\tregisterHeadingInputRules(context, this.config);\n\t\tregisterHeadingPickerEntries(context, this.config, this.locale);\n\t\tregisterHeadingToolbarItem(context, this.locale);\n\t}\n\n\tprivate registerNodeSpecs(context: PluginContext): void {\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'title',\n\t\t\tgroup: 'block',\n\t\t\tcontent: { allow: ['text'] },\n\t\t\texcludeMarks: ['fontSize'],\n\t\t\ttoDOM(node) {\n\t\t\t\tconst el = createBlockElement('h1', node.id);\n\t\t\t\tel.classList.add('notectl-title');\n\t\t\t\treturn el;\n\t\t\t},\n\t\t\ttoHTML(_node, content) {\n\t\t\t\treturn `<h1 class=\"notectl-title\">${content || '<br>'}</h1>`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'h1',\n\t\t\t\t\tpriority: 60,\n\t\t\t\t\tgetAttrs: (el) => (el.classList.contains('notectl-title') ? {} : false),\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['h1'], attrs: ['class'] },\n\t\t});\n\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'subtitle',\n\t\t\tgroup: 'block',\n\t\t\tcontent: { allow: ['text'] },\n\t\t\texcludeMarks: ['fontSize'],\n\t\t\ttoDOM(node) {\n\t\t\t\tconst el = createBlockElement('h2', node.id);\n\t\t\t\tel.classList.add('notectl-subtitle');\n\t\t\t\treturn el;\n\t\t\t},\n\t\t\ttoHTML(_node, content) {\n\t\t\t\treturn `<h2 class=\"notectl-subtitle\">${content || '<br>'}</h2>`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'h2',\n\t\t\t\t\tpriority: 60,\n\t\t\t\t\tgetAttrs: (el) => (el.classList.contains('notectl-subtitle') ? {} : false),\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['h2'], attrs: ['class'] },\n\t\t});\n\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'heading',\n\t\t\tgroup: 'block',\n\t\t\tcontent: { allow: ['text'] },\n\t\t\texcludeMarks: ['fontSize'],\n\t\t\tattrs: {\n\t\t\t\tlevel: { default: 1 },\n\t\t\t},\n\t\t\ttoDOM(node) {\n\t\t\t\tconst level = node.attrs?.level ?? 1;\n\t\t\t\tconst tag = HEADING_TAGS[level] ?? 'h1';\n\t\t\t\treturn createBlockElement(tag, node.id);\n\t\t\t},\n\t\t\ttoHTML(node, content) {\n\t\t\t\tconst level = (node.attrs?.level ?? 1) as HeadingLevel;\n\t\t\t\tconst tag: string = HEADING_TAGS[level] ?? 'h1';\n\t\t\t\treturn `<${tag}>${content || '<br>'}</${tag}>`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{ tag: 'h1', getAttrs: () => ({ level: 1 }) },\n\t\t\t\t{ tag: 'h2', getAttrs: () => ({ level: 2 }) },\n\t\t\t\t{ tag: 'h3', getAttrs: () => ({ level: 3 }) },\n\t\t\t\t{ tag: 'h4', getAttrs: () => ({ level: 4 }) },\n\t\t\t\t{ tag: 'h5', getAttrs: () => ({ level: 5 }) },\n\t\t\t\t{ tag: 'h6', getAttrs: () => ({ level: 6 }) },\n\t\t\t],\n\t\t\tsanitize: { tags: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'] },\n\t\t});\n\t}\n}\n"],"mappings":"qUC6IA,SAAS,EACR,EACA,EACA,EACA,GAEA,MAAM,EAA0B,SAAS,cAAc,UACvD,EAAK,KAAO,SACZ,EAAK,UAAY,+BACjB,EAAK,aAAa,OAAQ,UAC1B,EAAK,aAAa,gBAAiB,OAAO,IAEtC,GACH,EAAK,UAAU,IAAI,wCAGpB,MAAM,EAAyB,SAAS,cAAc,QACtD,EAAM,UAAY,gCAClB,EAAM,YAAc,EAAW,IAAW,GAC1C,EAAK,YAAY,GAEjB,MAAM,EAA6B,SAAS,cAAc,QAY1D,OAXA,EAAU,UAAY,gCACtB,EAAU,YAAc,EACpB,GACH,EAAmB,EAAW,CAC7B,SAAU,EAAM,SAChB,WAAY,EAAM,aAGpB,EAAK,YAAY,GAEjB,EAAK,iBAAiB,YAAa,GAC5B,EAKR,SAAS,EAAgB,EAAuB,GAE/C,OAAO,EADK,UAAU,KChJvB,SAAS,EAAmB,EAAwB,GACnD,MAAM,EAAqB,EAAQ,WACnC,IAAK,EAAgB,EAAM,WAAY,OAAO,EAE9C,MAAM,EAA+B,EAAM,SAAS,EAAM,UAAU,OAAO,SAC3E,QAAK,IAED,EAAM,OAAS,EACX,EAAa,EAAS,EAAS,cAGhC,EAAa,EAAS,EAAS,KAOvC,SAAS,EAAc,EAAwB,GAC9C,MAAM,EAAqB,EAAQ,WAC7B,EAAM,EAAM,UAClB,IAAK,EAAgB,GAAM,OAAO,EAElC,MAAM,EAA+B,EAAM,SAAS,EAAI,OAAO,SAC/D,QAAK,IAEc,YAAf,EAAM,MAAsB,EAAM,OAAO,QAAU,EAC/C,EAAa,EAAS,EAAS,cAGhC,EAAa,EAAS,EAAS,WAAY,CAAE,WAGrD,SAAS,EACR,EACA,EACA,GAEA,MAAM,EAAqB,EAAQ,WAC7B,EAAM,EAAM,UAClB,IAAK,EAAgB,GAAM,OAAO,EAElC,MAAM,EAA+B,EAAM,SAAS,EAAI,OAAO,SAC/D,IAAK,EAAO,OAAO,EAEnB,MAAM,EAA8B,EAAM,YAAY,WAEhD,EAAO,EAAQ,oBAAoB,YAAY,GACjD,GAAM,cAAgB,EAAK,aAAa,OAAS,IAgBtD,SACC,EACA,EACA,GAGA,GAAoB,IADQ,EAAe,GACpB,OAEvB,MAAM,EAA0B,IAAI,IAAI,GAClC,EAAiB,EAAkB,GACzC,IAAI,EAAS,EAEb,IAAK,MAAM,KAAS,EACnB,GAAI,EAAW,GAAQ,CACtB,GAAI,EAAM,KAAK,OAAS,MAClB,MAAM,KAAQ,EAAM,MACpB,EAAW,IAAI,EAAK,OACvB,EAAQ,WAAW,EAAM,GAAI,EAAQ,EAAS,EAAM,KAAK,OAAQ,GAIpE,GAAU,EAAM,KAAK,YAErB,GAAU,EAtCX,CAAmB,EAAS,EAAO,EAAK,cA+C1C,SACC,EACA,EACA,GAEA,IAAK,EAAM,YAAa,OAExB,MAAM,EAA0B,IAAI,IAAI,GAClC,EAA4B,EAAM,YAAY,OAAQ,IAAa,EAAW,IAAI,EAAE,OAEtF,EAAS,SAAW,EAAM,YAAY,QACzC,EAAQ,eAAe,EAAS,OAAS,EAAI,EAAW,KAAM,EAAM,aAzDpE,CAAyB,EAAS,EAAO,EAAK,eAG/C,MAAM,EAAK,EAAQ,aAAa,EAAI,OAAO,QAAS,EAAM,GAAO,aAAa,GAAK,QAEnF,OADA,EAAQ,SAAS,IACV,EE3ER,IAAM,EAAqC,IAAI,IAAI,CAAC,UAAW,QAAS,aCQxE,IAAa,EAAmC,CAC/C,UAAW,YACX,MAAO,QACP,SAAU,WACV,SAAU,YACV,SAAU,YACV,SAAU,YACV,SAAU,YACV,SAAU,YACV,SAAU,YACV,eAAgB,aAChB,eAAgB,eAKX,iBAAgD,OAAA,OAAA,CAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,uBAItD,eAAsB,EAAkB,GACvC,OAAO,EAAiB,EAAe,EAAM,GCF9C,IAAM,EAAgC,CACrC,OAAQ,CAAC,EAAG,EAAG,EAAG,EAAG,EAAG,IAKnB,EAA6C,CAClD,EAAG,KACH,EAAG,KACH,EAAG,KACH,EAAG,KACH,EAAG,KACH,EAAG,MAKS,EAAb,MACC,GAAc,UACd,KAAgB,UAChB,SAAoB,GAEpB,OACA,OAEA,WAAA,CAAY,GACX,KAAK,OAAS,IAAK,KAAmB,GAGvC,UAAM,CAAK,GACV,KAAK,aAAe,EACnB,EACA,KAAK,OAAO,OACZ,EACA,GAED,EAAQ,mBN9EwB,myCMgFhC,KAAK,kBAAkB,GJjEzB,SAAwC,EAAwB,GAC/D,EAAQ,gBAAgB,WAAA,IAAkB,EAAmB,EAAS,UAEtE,EAAQ,gBAAgB,cAAA,IAAqB,EAAmB,EAAS,aAEzE,IAAK,MAAM,KAAS,EAAO,OAC1B,EAAQ,gBAAgB,aAAa,IAAA,IAAe,EAAc,EAAS,IAG5E,EAAQ,gBAAgB,gBAAA,IAAuB,EAAc,EAAS,IAEtE,EAAQ,gBAAgB,eAAA,IAAsB,EAAa,EAAS,EAAS,eIuD5E,CAAwB,EAAS,KAAK,QF/BxC,SAAuC,EAAwB,GAC9D,MAAM,EAAwC,CAC7C,MAAA,IAoBF,SAAqB,GACpB,OA7CD,SACC,EACA,GAEA,MAAM,EAAqB,EAAQ,WACnC,IAAK,EAAgB,EAAM,WAAY,OAAO,EAE9C,MAAM,EAAM,EAAM,UAClB,IAAK,EAAY,GAAM,OAAO,EAE9B,MAAM,EAA+B,EAAM,SAAS,EAAI,OAAO,SAC/D,SAAK,IAAU,EAAc,IAAI,EAAM,QAEhC,EAAQ,CACd,QACA,QACA,QAAS,EAAI,OAAO,QACpB,OAAQ,EAAI,OAAO,SA4Bb,CAAmB,EAAU,IAGnC,GAAa,KAFQ,EAAa,EAAI,OAErB,CAChB,MAAM,EAAK,EAAI,MACb,YAAY,SACZ,aAAa,EAAI,QAAS,EAAS,cACnC,aAAa,EAAI,MAAM,WACvB,QAEF,OADA,EAAQ,SAAS,IACV,EAGR,MAAM,EAAsB,EAAe,EAAI,OAE/C,GAAI,EAAI,QAAU,EAAa,CAC9B,MAAM,EAAa,IACb,EAAK,EAAI,MACb,YAAY,SACZ,WAAW,EAAI,QAAS,EAAI,OAAQ,GACpC,aAAa,EAAY,EAAS,cAClC,aAAa,EAAyB,EAAY,IAClD,QAEF,OADA,EAAQ,SAAS,IACV,EAGR,OAAO,IAhDM,CAAY,IAG1B,IAAK,MAAM,KAAS,EAAO,OACtB,GAAS,IACZ,EAAO,aAAa,KAAA,IAAiB,EAAQ,eAAe,aAAa,MAI3E,EAAQ,eAAe,GEqBtB,CAAuB,EAAS,KAAK,QHxEvC,SAA0C,EAAwB,GACjE,IAAK,MAAM,KAAS,EAAO,OAAQ,CAClC,MAAM,EAAiB,IAAI,OAAO,GAC5B,EAAkB,IAAI,OAAO,IAAI,OAEvC,EAAQ,kBAAkB,CACzB,UACA,OAAA,CAAQ,EAAO,EAAQ,EAAO,GAC7B,MAAM,EAAM,EAAM,UAClB,IAAK,EAAgB,GAAM,OAAO,KAClC,IAAK,EAAY,GAAM,OAAO,KAE9B,MAAM,EAAQ,EAAM,SAAS,EAAI,OAAO,SACxC,OAAK,GAAwB,cAAf,EAAM,KAEb,EACL,YAAY,SACZ,aAAa,EAAI,OAAO,QAAS,EAAO,EAAQ,EAAQ,GACxD,aAAa,EAAI,OAAO,QAAS,EAAS,WAAY,CAAE,UACxD,aAAa,EAAyB,EAAI,OAAO,QAAS,IAC1D,QAP+C,SG4DnD,CAA0B,EAAS,KAAK,QLjE1C,SACC,EACA,EACA,GAEA,EAAQ,6BAA6B,CACpC,GAAI,YACJ,MAAO,EAAO,UACd,QAAS,eACT,SAAU,GACV,SAAW,KACL,EAAgB,EAAM,YAEJ,cADT,EAAM,SAAS,EAAM,UAAU,OAAO,UACtC,OAIhB,EAAQ,6BAA6B,CACpC,GAAI,QACJ,MAAO,EAAO,MACd,QAAS,WACT,SAAU,GACV,MAAO,CAAE,SAAU,QAAS,WAAY,OACxC,SAAW,KACL,EAAgB,EAAM,YAEJ,UADT,EAAM,SAAS,EAAM,UAAU,OAAO,UACtC,OAIhB,EAAQ,6BAA6B,CACpC,GAAI,WACJ,MAAO,EAAO,SACd,QAAS,cACT,SAAU,GACV,MAAO,CAAE,SAAU,QAAS,WAAY,OACxC,SAAW,KACL,EAAgB,EAAM,YAEJ,aADT,EAAM,SAAS,EAAM,UAAU,OAAO,UACtC,OAIhB,IAAK,MAAM,KAAS,EAAO,OAC1B,EAAQ,6BAA6B,CACpC,GAAI,WAAW,IACf,MAAO,EAAgB,EAAQ,GAC/B,QAAS,aAAa,IACtB,SAAU,IAAM,EAChB,MAAO,CAAE,SAAa,IAAc,GAAR,EAAT,KAA0B,WAAY,OACzD,SAAW,IACV,IAAK,EAAgB,EAAM,WAAY,OAAO,EAC9C,MAAM,EAAQ,EAAM,SAAS,EAAM,UAAU,OAAO,SACpD,MAAuB,YAAhB,GAAO,MAAsB,EAAM,OAAO,QAAU,KKa7D,CAA6B,EAAS,KAAK,OAAQ,KAAK,QLJ1D,SAA2C,EAAwB,GAClE,EAAQ,oBAAoB,CAC3B,GAAI,UACJ,MAAO,QACP,MAAO,EAAO,eACd,QAAS,EAAO,eAChB,QAAS,eACT,UAAW,WACX,SAAW,GA+Fb,SAAwB,EAAoB,EAAwB,GACnE,IAAK,EAAgB,EAAM,WAAY,OAAO,EAAO,UACrD,MAAM,EAAU,EAAQ,6BAA6B,4BACrD,IAAK,MAAM,KAAS,EACnB,GAAI,EAAM,SAAS,GAAQ,OAAO,EAAM,MAEzC,OAAO,EAAO,UArG6B,CAAe,EAAO,EAAS,GACzE,YAAA,CAAc,EAAW,EAAK,MAYhC,SACC,EACA,EACA,EACA,GAEA,EAAU,UAAU,IAAI,0BAExB,MAAM,EAAqB,EAAQ,WACnC,IAAK,EAAgB,EAAM,WAAY,OAEvC,MAAM,EAA8B,EAAQ,eAEtC,EAAuB,SAAS,cAAc,OACpD,EAAK,UAAY,+BACjB,EAAK,aAAa,OAAQ,WAC1B,EAAK,aAAa,aAAc,EAAO,gBAEvC,MAAM,EAAU,EAAQ,6BAA6B,4BACrD,IAAK,MAAM,KAAS,EAAS,CAC5B,MAAM,EAAkB,EAAM,SAAS,GACvC,EAAK,YACJ,EACC,EAAM,MACN,EACC,IACA,EAAE,iBACF,EAAE,kBACF,EAAQ,eAAe,EAAM,SAC7B,EAAQ,CAAE,eAAgB,KAE3B,EAAM,QAKT,EAAU,YAAY,GA/CpB,CAAmB,EAAW,EAAK,EAAQ,IAE5C,SAAW,GACM,EAAQ,6BAA6B,4BACtC,KAAM,GAAuB,cAAb,EAAM,IAAsB,EAAM,SAAS,MKT3E,CAA2B,EAAS,KAAK,QAG1C,iBAAA,CAA0B,GACzB,EAAQ,iBAAiB,CACxB,KAAM,QACN,MAAO,QACP,QAAS,CAAE,MAAO,CAAC,SACnB,aAAc,CAAC,YACf,KAAA,CAAM,GACL,MAAM,EAAK,EAAmB,KAAM,EAAK,IAEzC,OADA,EAAG,UAAU,IAAI,iBACV,GAER,OAAA,CAAO,EAAO,IACN,6BAA6B,GAAW,cAEhD,UAAW,CACV,CACC,IAAK,KACL,SAAU,GACV,SAAW,KAAQ,EAAG,UAAU,SAAS,kBAAmB,CAAA,IAG9D,SAAU,CAAE,KAAM,CAAC,MAAO,MAAO,CAAC,YAGnC,EAAQ,iBAAiB,CACxB,KAAM,WACN,MAAO,QACP,QAAS,CAAE,MAAO,CAAC,SACnB,aAAc,CAAC,YACf,KAAA,CAAM,GACL,MAAM,EAAK,EAAmB,KAAM,EAAK,IAEzC,OADA,EAAG,UAAU,IAAI,oBACV,GAER,OAAA,CAAO,EAAO,IACN,gCAAgC,GAAW,cAEnD,UAAW,CACV,CACC,IAAK,KACL,SAAU,GACV,SAAW,KAAQ,EAAG,UAAU,SAAS,qBAAsB,CAAA,IAGjE,SAAU,CAAE,KAAM,CAAC,MAAO,MAAO,CAAC,YAGnC,EAAQ,iBAAiB,CACxB,KAAM,UACN,MAAO,QACP,QAAS,CAAE,MAAO,CAAC,SACnB,aAAc,CAAC,YACf,MAAO,CACN,MAAO,CAAE,QAAS,IAEnB,MAAM,GAGE,EADK,EADE,EAAK,OAAO,OAAS,IACA,KACJ,EAAK,IAErC,MAAA,CAAO,EAAM,GAEZ,MAAM,EAAc,EADL,EAAK,OAAO,OAAS,IACO,KAC3C,MAAO,IAAI,KAAO,GAAW,WAAW,MAEzC,UAAW,CACV,CAAE,IAAK,KAAM,SAAA,KAAA,CAAmB,MAAO,KACvC,CAAE,IAAK,KAAM,SAAA,KAAA,CAAmB,MAAO,KACvC,CAAE,IAAK,KAAM,SAAA,KAAA,CAAmB,MAAO,KACvC,CAAE,IAAK,KAAM,SAAA,KAAA,CAAmB,MAAO,KACvC,CAAE,IAAK,KAAM,SAAA,KAAA,CAAmB,MAAO,KACvC,CAAE,IAAK,KAAM,SAAA,KAAA,CAAmB,MAAO,MAExC,SAAU,CAAE,KAAM,CAAC,KAAM,KAAM,KAAM,KAAM,KAAM"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{a as e,s as t}from"./PluginHelpers-C3aCCGfX.mjs";import{a as o,t as r}from"./ColorValidation-okAvytHQ.mjs";import{t as a}from"./InlineStyleMarkSpec-Cc-b1tlm.mjs";import{t as i}from"./color-picker-C89H4SVX.mjs";import{a as s,i as l,t as f}from"./ColorPickerPopup-_Gp09pdx.mjs";var c={label:"Highlight",tooltip:"Highlight Color",resetLabel:"None",ariaLabelPrefix:"Highlight color"},h=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-BK4O36ep.mjs"),"./locales/de.ts":()=>import("./de-BDRaxLyi.mjs"),"./locales/es.ts":()=>import("./es-NcrWuNe1.mjs"),"./locales/fr.ts":()=>import("./fr-BEd3ZHO4.mjs"),"./locales/hi.ts":()=>import("./hi-PUX7dDPm.mjs"),"./locales/pt.ts":()=>import("./pt-D19IWOM_.mjs"),"./locales/ru.ts":()=>import("./ru--JPEpdcJ.mjs"),"./locales/zh.ts":()=>import("./zh-D_VJDQl4.mjs")});async function m(e){return t(h,e,c)}var g=["#fff176","#aed581","#4dd0e1","#64b5f6","#ce93d8","#f48fb1","#ffab91","#ff8a65","#e6ee9c","#80cbc4","#fff9c4","#dcedc8","#e0f7fa","#e3f2fd","#f3e5f5","#fce4ec","#fff3e0","#fbe9e7","#f9fbe7","#e0f2f1","#fff59d","#c5e1a5","#80deea","#90caf9","#e1bee7","#f8bbd0","#ffcc80","#ffab91","#e6ee9c","#a5d6a7","#ffee58","#9ccc65","#26c6da","#42a5f5","#ab47bc","#ec407a","#ffa726","#ff7043","#d4e157","#66bb6a","#ffffff","#fafafa","#f5f5f5","#eeeeee","#e0e0e0","#bdbdbd","#e8eaf6","#efebe9","#eceff1","#fafafa"],p=class{id="highlight";name="Highlight";priority=24;config;colors;locale;constructor(e){this.config={...e},this.colors=o(e?.colors,g,"HighlightPlugin")}async init(t){this.locale=await e(t,this.config.locale,c,m),t.registerStyleSheet(i),this.registerMarkSpec(t),this.registerCommands(t),this.registerToolbarItem(t)}registerMarkSpec(e){e.registerMarkSpec(a({type:"highlight",rank:4,valueAttr:"color",domStyleProperty:"backgroundColor",cssProperty:"background-color",validate:r,validateOnParse:!0}))}registerCommands(e){e.registerCommand("removeHighlight",()=>s(e,e.getState(),"highlight"))}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="17" width="18" height="6"',' rx="0.5" fill="#fff176"/>',"</svg>"].join("");e.registerToolbarItem({id:"highlight",group:"format",icon:t,label:this.locale.label,tooltip:this.locale.tooltip,command:"removeHighlight",popupType:"custom",renderPopup:(e,t,o)=>{f(e,t,{markType:"highlight",colors:this.colors,columns:10,resetLabel:this.locale.resetLabel,resetCommand:"removeHighlight",ariaLabelPrefix:this.locale.ariaLabelPrefix,onClose:o})},isActive:e=>l(e,"highlight")})}};export{c as n,m as r,p as t};
|
|
2
|
+
//# sourceMappingURL=HighlightPlugin-dHxnAuoW.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HighlightPlugin-dHxnAuoW.mjs","names":[],"sources":["../../src/plugins/highlight/HighlightLocale.ts","../../src/plugins/highlight/HighlightPalette.ts","../../src/plugins/highlight/HighlightPlugin.ts"],"sourcesContent":["/** Locale interface and default English locale for the HighlightPlugin. */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface HighlightLocale {\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 HIGHLIGHT_LOCALE_EN: HighlightLocale = {\n\tlabel: 'Highlight',\n\ttooltip: 'Highlight Color',\n\tresetLabel: 'None',\n\tariaLabelPrefix: 'Highlight color',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<HighlightLocale> = import.meta.glob<{\n\tdefault: HighlightLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadHighlightLocale(lang: string): Promise<HighlightLocale> {\n\treturn loadLocaleModule(localeModules, lang, HIGHLIGHT_LOCALE_EN);\n}\n","/**\n * Default highlight color palette (10 columns x 5 rows), optimized for\n * background highlighting. Used by HighlightPlugin when no `colors` override is\n * provided.\n */\nexport const HIGHLIGHT_PALETTE: readonly string[] = [\n\t// Row 1 — Classic highlighter colors (bright, vivid)\n\t'#fff176',\n\t'#aed581',\n\t'#4dd0e1',\n\t'#64b5f6',\n\t'#ce93d8',\n\t'#f48fb1',\n\t'#ffab91',\n\t'#ff8a65',\n\t'#e6ee9c',\n\t'#80cbc4',\n\t// Row 2 — Light pastels\n\t'#fff9c4',\n\t'#dcedc8',\n\t'#e0f7fa',\n\t'#e3f2fd',\n\t'#f3e5f5',\n\t'#fce4ec',\n\t'#fff3e0',\n\t'#fbe9e7',\n\t'#f9fbe7',\n\t'#e0f2f1',\n\t// Row 3 — Medium pastels\n\t'#fff59d',\n\t'#c5e1a5',\n\t'#80deea',\n\t'#90caf9',\n\t'#e1bee7',\n\t'#f8bbd0',\n\t'#ffcc80',\n\t'#ffab91',\n\t'#e6ee9c',\n\t'#a5d6a7',\n\t// Row 4 — Bold pastels\n\t'#ffee58',\n\t'#9ccc65',\n\t'#26c6da',\n\t'#42a5f5',\n\t'#ab47bc',\n\t'#ec407a',\n\t'#ffa726',\n\t'#ff7043',\n\t'#d4e157',\n\t'#66bb6a',\n\t// Row 5 — Grays and neutral highlights\n\t'#ffffff',\n\t'#fafafa',\n\t'#f5f5f5',\n\t'#eeeeee',\n\t'#e0e0e0',\n\t'#bdbdbd',\n\t'#e8eaf6',\n\t'#efebe9',\n\t'#eceff1',\n\t'#fafafa',\n];\n","/**\n * HighlightPlugin: registers a highlight (background-color) mark with attrs,\n * toolbar button with a color picker popup, and removeHighlight command.\n */\n\nimport { COLOR_PICKER_CSS } from '../../editor/styles/color-picker.js';\nimport type { EditorState } from '../../state/EditorState.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 { createInlineStyleMarkSpec } from '../shared/InlineStyleMarkSpec.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport {\n\tHIGHLIGHT_LOCALE_EN,\n\ttype HighlightLocale,\n\tloadHighlightLocale,\n} from './HighlightLocale.js';\nimport { HIGHLIGHT_PALETTE } from './HighlightPalette.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\thighlight: { color: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface HighlightConfig {\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?: HighlightLocale;\n}\n\n// --- Plugin ---\n\nexport class HighlightPlugin implements Plugin {\n\treadonly id = 'highlight';\n\treadonly name = 'Highlight';\n\treadonly priority = 24;\n\n\tprivate readonly config: HighlightConfig;\n\tprivate readonly colors: readonly string[];\n\tprivate locale!: HighlightLocale;\n\n\tconstructor(config?: Partial<HighlightConfig>) {\n\t\tthis.config = { ...config };\n\t\tthis.colors = resolveColors(config?.colors, HIGHLIGHT_PALETTE, 'HighlightPlugin');\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\tHIGHLIGHT_LOCALE_EN,\n\t\t\tloadHighlightLocale,\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\tcreateInlineStyleMarkSpec({\n\t\t\t\ttype: 'highlight',\n\t\t\t\trank: 4,\n\t\t\t\tvalueAttr: 'color',\n\t\t\t\tdomStyleProperty: 'backgroundColor',\n\t\t\t\tcssProperty: 'background-color',\n\t\t\t\tvalidate: isValidCSSColor,\n\t\t\t\tvalidateOnParse: true,\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('removeHighlight', () => {\n\t\t\treturn removeColorMark(context, context.getState(), 'highlight');\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=\"17\" width=\"18\" height=\"6\"',\n\t\t\t' rx=\"0.5\" fill=\"#fff176\"/>',\n\t\t\t'</svg>',\n\t\t].join('');\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'highlight',\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: 'removeHighlight',\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: 'highlight',\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: 'removeHighlight',\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, 'highlight'),\n\t\t});\n\t}\n}\n"],"mappings":"2RAeA,IAAa,EAAuC,CACnD,MAAO,YACP,QAAS,kBACT,WAAY,OACZ,gBAAiB,mBAKZ,iBAAkD,OAAA,OAAA,CAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,uBAIxD,eAAsB,EAAoB,GACzC,OAAO,EAAiB,EAAe,EAAM,GCxB9C,IAAa,EAAuC,CAEnD,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WCjBY,EAAb,MACC,GAAc,YACd,KAAgB,YAChB,SAAoB,GAEpB,OACA,OACA,OAEA,WAAA,CAAY,GACX,KAAK,OAAS,IAAK,GACnB,KAAK,OAAS,EAAc,GAAQ,OAAQ,EAAmB,mBAGhE,UAAM,CAAK,GACV,KAAK,aAAe,EACnB,EACA,KAAK,OAAO,OACZ,EACA,GAGD,EAAQ,mBAAmB,GAC3B,KAAK,iBAAiB,GACtB,KAAK,iBAAiB,GACtB,KAAK,oBAAoB,GAG1B,gBAAA,CAAyB,GACxB,EAAQ,iBACP,EAA0B,CACzB,KAAM,YACN,KAAM,EACN,UAAW,QACX,iBAAkB,kBAClB,YAAa,mBACb,SAAU,EACV,iBAAiB,KAKpB,gBAAA,CAAyB,GACxB,EAAQ,gBAAgB,kBAAA,IAChB,EAAgB,EAAS,EAAQ,WAAY,cAItD,mBAAA,CAA4B,GAG3B,MAAM,EAAe,CACpB,0CACA,wBACA,gGACA,2CACA,6BACA,UACC,KAAK,IAEP,EAAQ,oBAAoB,CAC3B,GAAI,YACJ,MAAO,SACP,OACA,MAAO,KAAK,OAAO,MACnB,QAAS,KAAK,OAAO,QACrB,QAAS,kBACT,UAAW,SACX,YAAA,CAAc,EAAW,EAAK,KAC7B,EAAuB,EAAW,EAAK,CACtC,SAAU,YACV,OAAQ,KAAK,OACb,QAAS,GACT,WAAY,KAAK,OAAO,WACxB,aAAc,kBACd,gBAAiB,KAAK,OAAO,gBAC7B,aAGF,SAAW,GAAuB,EAAkB,EAAO"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as t}from"./Document-znhIcvM9.mjs";import{o,t as r,u as e}from"./Selection-aeiSsvhe.mjs";import{a as s}from"./TypeBrands-BZDKMjR-.mjs";import{n as i}from"./DomUtils-RKbAVBQz.mjs";import{o as l}from"./BlockInsertion-C7jFEeYB.mjs";import{a,s as n}from"./PluginHelpers-C3aCCGfX.mjs";import{t as c}from"./ShortcutFormatting-DZK70CN9.mjs";var m={label:"Horizontal Rule",tooltip:t=>`Horizontal Rule (${t})`},p=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-ClgA1KQM.mjs"),"./locales/de.ts":()=>import("./de-DCx3Shj3.mjs"),"./locales/es.ts":()=>import("./es-B9z2Xwj0.mjs"),"./locales/fr.ts":()=>import("./fr-COx4cSxc.mjs"),"./locales/hi.ts":()=>import("./hi-DWwLzOX5.mjs"),"./locales/pt.ts":()=>import("./pt-CYkKDsLa.mjs"),"./locales/ru.ts":()=>import("./ru-Dd_P7hP7.mjs"),"./locales/zh.ts":()=>import("./zh-DTz9l6mp.mjs")});async function u(t){return n(p,t,m)}var h={},d=class{id="horizontal-rule";name="Horizontal Rule";priority=40;config;locale;constructor(t){this.config={...h,...t}}async init(t){this.locale=await a(t,this.config.locale,m,u),this.registerNodeSpec(t),this.registerCommands(t),this.registerKeymap(t),this.registerInputRule(t),this.registerToolbarItem(t)}registerNodeSpec(t){t.registerNodeSpec({type:"horizontal_rule",group:"block",isVoid:!0,toDOM:t=>i("hr",t.id),toHTML:()=>"<hr>",parseHTML:[{tag:"hr"}],sanitize:{tags:["hr"]}})}registerCommands(t){t.registerCommand("insertHorizontalRule",()=>this.insertHorizontalRule(t))}registerKeymap(t){t.registerKeymap({"Mod-Shift-H":()=>t.executeCommand("insertHorizontalRule")})}registerInputRule(i){i.registerInputRule({pattern:/^-{3,} $/,handler(i,l,a,n){const c=i.selection;if(!e(c))return null;if(!o(c))return null;const m=i.getBlock(c.anchor.blockId);if(!m||"paragraph"!==m.type)return null;const p=function(t){const o=t.selection;return e(o)?t.doc.children.findIndex(t=>t.id===o.anchor.blockId):-1}(i);if(-1===p)return null;const u=t(s("paragraph"));return i.transaction("input").deleteTextAt(c.anchor.blockId,0,n).setBlockType(c.anchor.blockId,s("horizontal_rule")).insertNode([],p+1,u).setSelection(r(u.id,0)).build()}})}registerToolbarItem(t){t.registerToolbarItem({id:"horizontal-rule",group:"block",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11h16v2H4z"/></svg>',label:this.locale.label,tooltip:this.locale.tooltip(c("Mod-Shift-H")),command:"insertHorizontalRule",isActive:()=>!1})}insertHorizontalRule(o){const i=o.getState(),a=i.selection;if(!e(a))return!1;const n=i.transaction("command"),c=l(i,n,a.anchor.blockId,t(s("horizontal_rule")));return!!c&&(n.setSelection(r(c.id,0)),o.dispatch(n.build()),!0)}};export{m as n,u as r,d as t};
|
|
2
|
+
//# sourceMappingURL=HorizontalRulePlugin-BYPaI4TR.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HorizontalRulePlugin-BYPaI4TR.mjs","names":[],"sources":["../../src/plugins/horizontal-rule/HorizontalRuleLocale.ts","../../src/plugins/horizontal-rule/HorizontalRulePlugin.ts"],"sourcesContent":["/** Locale interface and default English locale for the HorizontalRulePlugin. */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface HorizontalRuleLocale {\n\treadonly label: string;\n\treadonly tooltip: (shortcut: string) => string;\n}\n\n// --- Default English Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_EN: HorizontalRuleLocale = {\n\tlabel: 'Horizontal Rule',\n\ttooltip: (shortcut: string) => `Horizontal Rule (${shortcut})`,\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<HorizontalRuleLocale> = import.meta.glob<{\n\tdefault: HorizontalRuleLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadHorizontalRuleLocale(lang: string): Promise<HorizontalRuleLocale> {\n\treturn loadLocaleModule(localeModules, lang, HORIZONTAL_RULE_LOCALE_EN);\n}\n","/**\n * HorizontalRulePlugin: registers a horizontal rule (divider) void block type\n * with NodeSpec, insert command, input rule, keyboard shortcut, and toolbar button.\n */\n\nimport { insertBlockObjectOnOwnLine } from '../../commands/BlockInsertion.js';\nimport { createBlockNode } from '../../model/Document.js';\nimport { createCollapsedSelection, isCollapsed, isTextSelection } from '../../model/Selection.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport { createBlockElement } from '../../view/DomUtils.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport {\n\tHORIZONTAL_RULE_LOCALE_EN,\n\ttype HorizontalRuleLocale,\n\tloadHorizontalRuleLocale,\n} from './HorizontalRuleLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\thorizontal_rule: Record<string, never>;\n\t}\n}\n\n// --- Configuration ---\n\nexport interface HorizontalRuleConfig {\n\t/** Locale override for user-facing strings. */\n\treadonly locale?: HorizontalRuleLocale;\n}\n\nconst DEFAULT_CONFIG: HorizontalRuleConfig = {};\n\n// --- Helpers ---\n\n/** Finds the index of the cursor's block among top-level document children. */\nfunction findBlockIndexForCursor(state: EditorState): number {\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return -1;\n\treturn state.doc.children.findIndex((b) => b.id === sel.anchor.blockId);\n}\n\n// --- Plugin ---\n\nexport class HorizontalRulePlugin implements Plugin {\n\treadonly id = 'horizontal-rule';\n\treadonly name = 'Horizontal Rule';\n\treadonly priority = 40;\n\n\tprivate readonly config: HorizontalRuleConfig;\n\tprivate locale!: HorizontalRuleLocale;\n\n\tconstructor(config?: Partial<HorizontalRuleConfig>) {\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\tHORIZONTAL_RULE_LOCALE_EN,\n\t\t\tloadHorizontalRuleLocale,\n\t\t);\n\t\tthis.registerNodeSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymap(context);\n\t\tthis.registerInputRule(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerNodeSpec(context: PluginContext): void {\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'horizontal_rule',\n\t\t\tgroup: 'block',\n\t\t\tisVoid: true,\n\t\t\ttoDOM(node) {\n\t\t\t\treturn createBlockElement('hr', node.id);\n\t\t\t},\n\t\t\ttoHTML() {\n\t\t\t\treturn '<hr>';\n\t\t\t},\n\t\t\tparseHTML: [{ tag: 'hr' }],\n\t\t\tsanitize: { tags: ['hr'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('insertHorizontalRule', () => {\n\t\t\treturn this.insertHorizontalRule(context);\n\t\t});\n\t}\n\n\tprivate registerKeymap(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-H': () => context.executeCommand('insertHorizontalRule'),\n\t\t});\n\t}\n\n\tprivate registerInputRule(context: PluginContext): void {\n\t\tcontext.registerInputRule({\n\t\t\tpattern: /^-{3,} $/,\n\t\t\thandler(state, _match, _start, end) {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\tif (!isTextSelection(sel)) return null;\n\t\t\t\tif (!isCollapsed(sel)) return null;\n\n\t\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\t\tif (!block || block.type !== 'paragraph') return null;\n\n\t\t\t\tconst blockIndex: number = findBlockIndexForCursor(state);\n\t\t\t\tif (blockIndex === -1) return null;\n\n\t\t\t\tconst newParagraph = createBlockNode(nodeType('paragraph'));\n\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.deleteTextAt(sel.anchor.blockId, 0, end)\n\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('horizontal_rule'))\n\t\t\t\t\t.insertNode([], blockIndex + 1, newParagraph)\n\t\t\t\t\t.setSelection(createCollapsedSelection(newParagraph.id, 0))\n\t\t\t\t\t.build();\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon =\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 11h16v2H4z\"/></svg>';\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'horizontal-rule',\n\t\t\tgroup: 'block',\n\t\t\ticon,\n\t\t\tlabel: this.locale.label,\n\t\t\ttooltip: this.locale.tooltip(formatShortcut('Mod-Shift-H')),\n\t\t\tcommand: 'insertHorizontalRule',\n\t\t\tisActive: () => false,\n\t\t});\n\t}\n\n\t/**\n\t * Inserts a horizontal rule after the current block,\n\t * followed by a new paragraph for continued editing.\n\t */\n\tprivate insertHorizontalRule(context: PluginContext): boolean {\n\t\tconst state: EditorState = context.getState();\n\t\tconst sel = state.selection;\n\t\tif (!isTextSelection(sel)) return false;\n\n\t\tconst builder = state.transaction('command');\n\t\tconst trailing = insertBlockObjectOnOwnLine(\n\t\t\tstate,\n\t\t\tbuilder,\n\t\t\tsel.anchor.blockId,\n\t\t\tcreateBlockNode(nodeType('horizontal_rule')),\n\t\t);\n\t\tif (!trailing) return false;\n\n\t\tbuilder.setSelection(createCollapsedSelection(trailing.id, 0));\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n}\n"],"mappings":"uVAaA,IAAa,EAAkD,CAC9D,MAAO,kBACP,QAAU,GAAqB,oBAAoB,MAK9C,iBAAuD,OAAA,OAAA,CAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,qBAAA,kBAAA,IAAA,OAAA,uBAI7D,eAAsB,EAAyB,GAC9C,OAAO,EAAiB,EAAe,EAAM,GCU9C,IAAM,EAAuC,CAAA,EAahC,EAAb,MACC,GAAc,kBACd,KAAgB,kBAChB,SAAoB,GAEpB,OACA,OAEA,WAAA,CAAY,GACX,KAAK,OAAS,IAAK,KAAmB,GAGvC,UAAM,CAAK,GACV,KAAK,aAAe,EACnB,EACA,KAAK,OAAO,OACZ,EACA,GAED,KAAK,iBAAiB,GACtB,KAAK,iBAAiB,GACtB,KAAK,eAAe,GACpB,KAAK,kBAAkB,GACvB,KAAK,oBAAoB,GAG1B,gBAAA,CAAyB,GACxB,EAAQ,iBAAiB,CACxB,KAAM,kBACN,MAAO,QACP,QAAQ,EACR,MAAM,GACE,EAAmB,KAAM,EAAK,IAEtC,OAAA,IACQ,OAER,UAAW,CAAC,CAAE,IAAK,OACnB,SAAU,CAAE,KAAM,CAAC,SAIrB,gBAAA,CAAyB,GACxB,EAAQ,gBAAgB,uBAAA,IAChB,KAAK,qBAAqB,IAInC,cAAA,CAAuB,GACtB,EAAQ,eAAe,CACtB,cAAA,IAAqB,EAAQ,eAAe,0BAI9C,iBAAA,CAA0B,GACzB,EAAQ,kBAAkB,CACzB,QAAS,WACT,OAAA,CAAQ,EAAO,EAAQ,EAAQ,GAC9B,MAAM,EAAM,EAAM,UAClB,IAAK,EAAgB,GAAM,OAAO,KAClC,IAAK,EAAY,GAAM,OAAO,KAE9B,MAAM,EAAQ,EAAM,SAAS,EAAI,OAAO,SACxC,IAAK,GAAwB,cAAf,EAAM,KAAsB,OAAO,KAEjD,MAAM,EAzEV,SAAiC,GAChC,MAAM,EAAM,EAAM,UAClB,OAAK,EAAgB,GACd,EAAM,IAAI,SAAS,UAAW,GAAM,EAAE,KAAO,EAAI,OAAO,UAD7B,EAuEJ,CAAwB,GACnD,IAAmB,IAAf,EAAmB,OAAO,KAE9B,MAAM,EAAe,EAAgB,EAAS,cAE9C,OAAO,EACL,YAAY,SACZ,aAAa,EAAI,OAAO,QAAS,EAAG,GACpC,aAAa,EAAI,OAAO,QAAS,EAAS,oBAC1C,WAAW,GAAI,EAAa,EAAG,GAC/B,aAAa,EAAyB,EAAa,GAAI,IACvD,WAKL,mBAAA,CAA4B,GAI3B,EAAQ,oBAAoB,CAC3B,GAAI,kBACJ,MAAO,QACP,KALA,8FAMA,MAAO,KAAK,OAAO,MACnB,QAAS,KAAK,OAAO,QAAQ,EAAe,gBAC5C,QAAS,uBACT,SAAA,KAAgB,IAQlB,oBAAA,CAA6B,GAC5B,MAAM,EAAqB,EAAQ,WAC7B,EAAM,EAAM,UAClB,IAAK,EAAgB,GAAM,OAAO,EAElC,MAAM,EAAU,EAAM,YAAY,WAC5B,EAAW,EAChB,EACA,EACA,EAAI,OAAO,QACX,EAAgB,EAAS,qBAE1B,QAAK,IAEL,EAAQ,aAAa,EAAyB,EAAS,GAAI,IAC3D,EAAQ,SAAS,EAAQ,UAClB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{S as t,r as e,u as n}from"./Document-znhIcvM9.mjs";import{c as i,l as o,r}from"./Selection-aeiSsvhe.mjs";import{a}from"./TypeBrands-BZDKMjR-.mjs";import{n as s}from"./DomUtils-RKbAVBQz.mjs";import{r as l}from"./HTMLUtils-brwcaufP.mjs";import{t as c}from"./NodeSelectionCommands-dUmbRoZ2.mjs";import{t as d}from"./Platform-wPvKFB9m.mjs";import{o as g}from"./BlockInsertion-C7jFEeYB.mjs";import{o as m,r as p,s as u}from"./StyleRuntime-Bwde5icB.mjs";import{n as h}from"./TypedKeys-E3jOGByL.mjs";import{a as f,s as b}from"./PluginHelpers-C3aCCGfX.mjs";import{t as v}from"./ShortcutFormatting-DZK70CN9.mjs";function x(s,l){const c=s.getState(),d=c.selection,m={src:l.src,alt:l.alt??"",align:l.align??"center",...void 0!==l.width?{width:l.width}:{},...void 0!==l.height?{height:l.height}:{}};if(i(d))return!1;const p=o(d)?d.nodeId:d.anchor.blockId,u=function(t,e){if("table_cell"===t.getBlock(e)?.type)return e;const n=t.getNodePath(e);if(n)for(const i of n)if("table_cell"===t.getBlock(i)?.type)return i}(c,p);return u?function(i,o,s,l){const c=i.getNodePath(s);if(!c)return!1;const d=e(a("image"),[],void 0,l),g=i.getBlock(s);if(!g)return!1;const m=i.transaction("command"),p=n(g);for(let e=p.length-1;e>=0;e--){const n=g.children.findIndex(n=>t(n)&&n.id===p[e]?.id);-1!==n&&m.removeNode(c,n)}return m.insertNode(c,0,d),m.setSelection(r(d.id,[...c,d.id])),o.dispatch(m.build()),!0}(c,s,u,m):function(t,n,i,o){const s=e(a("image"),[],void 0,o),l=t.transaction("command");return!!g(t,l,i,s)&&(l.setSelection(r(s.id,[])),n.dispatch(l.build()),!0)}(c,s,p,m)}function _(t,e,n){const i=t.getState(),r=i.selection;if(!o(r))return!1;const a=i.getBlock(r.nodeId);if(!a||"image"!==a.type)return!1;const s=a.attrs?.width,l=a.attrs?.height;if(void 0===s||void 0===l)return!1;const c=l>0?s/l:1,d=Math.max(50,Math.min(n,s+e)),g=Math.round(d/c);return(d!==s||g!==l)&&function(t,e){const n=t.getState(),i=n.selection;if(!o(i))return!1;const r=n.getBlock(i.nodeId);if(!r||"image"!==r.type)return!1;const a=n.getNodePath(i.nodeId);if(!a)return!1;const s={...r.attrs??{},...e},l=n.transaction("command").setNodeAttr(a,s).build();return t.dispatch(l),!0}(t,{width:d,height:g})}var w={insertImage:"Insert Image",insertImageTooltip:"Insert Image",uploadFromComputer:"Upload from computer",uploadAria:"Upload image from computer",separator:"or",urlPlaceholder:"https://...",urlAria:"Image URL",insertButton:"Insert",insertAria:"Insert image",imageAria:(t,e,n)=>{const i=[t||"Image"];return void 0!==e&&void 0!==n&&i.push(`${e} by ${n} pixels`),i.join(", ")},resetToNaturalSize:"Image reset to natural size.",uploadFailed:"Upload failed.",uploading:"Uploading...",resizeHandleLabel:t=>`Resize ${t}`,imageSelected:"Image selected.",altTextPrefix:"Alt text: ",imageSizeAnnounce:(t,e)=>`Size: ${t} by ${e} pixels.`,resizeHint:(t,e)=>`${t} / ${e} to resize.`,imageResized:(t,e)=>`Image resized to ${t} by ${e} pixels.`,keyboardResizeHint:(t,e)=>`${t} / ${e} to resize`},z=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-Y9KjJLX8.mjs"),"./locales/de.ts":()=>import("./de-BfZ5qXWz.mjs"),"./locales/es.ts":()=>import("./es-BSyxBRjn.mjs"),"./locales/fr.ts":()=>import("./fr-BruEqDw1.mjs"),"./locales/hi.ts":()=>import("./hi-DLLBZu67.mjs"),"./locales/pt.ts":()=>import("./pt-ALzIyTiI.mjs"),"./locales/ru.ts":()=>import("./ru-NBxCkjlP.mjs"),"./locales/zh.ts":()=>import("./zh-CfMPFWUg.mjs")});async function y(t){return b(z,t,w)}var S={start:"notectl-image--start",center:"notectl-image--center",end:"notectl-image--end"},I={nw:"nwse-resize",ne:"nesw-resize",sw:"nesw-resize",se:"nwse-resize"},k={nw:-1,ne:1,sw:-1,se:1},L={nw:"nesw-resize",ne:"nwse-resize",sw:"nwse-resize",se:"nesw-resize"},C=null;function A(){C&&(C.remove(),C=null)}function N(t,e,n,i=w){return(o,r,a)=>{const s=document.createElement("figure");s.className="notectl-image",s.setAttribute("data-block-id",o.id),s.setAttribute("data-void","true"),s.setAttribute("data-selectable","true");const l=document.createElement("div");l.className="notectl-image__container";const c=document.createElement("img");c.className="notectl-image__img",c.draggable=!1;const g=document.createElement("div");g.className="notectl-image__overlay",l.appendChild(c),l.appendChild(g),s.appendChild(l);let h=o.id,f=null;function b(t){const n=t.attrs?.src??"",o=t.attrs?.alt??"",r=t.attrs?.width,a=t.attrs?.height,l=t.attrs?.align??"center";c.src!==n&&(c.src=n),c.alt=o,u(c,"width",void 0!==r?`${r}px`:""),u(c,"height",void 0!==a?`${a}px`:"");for(const e of Object.values(S))s.classList.remove(e);const d=S[l];d&&s.classList.add(d);const m=e.get(t.id)??"idle",p="uploading"===m;g.classList.toggle("notectl-image__overlay--uploading",p),g.classList.toggle("notectl-image__overlay--error","error"===m),g.textContent=p?i.uploading:"error"===m?i.uploadFailed:"",p?s.setAttribute("aria-busy","true"):s.removeAttribute("aria-busy"),function(t){const e=t.attrs?.alt??"",n=t.attrs?.width,o=t.attrs?.height;s.setAttribute("aria-label",i.imageAria(e,n,o))}(t)}b(o);let x=!1;function _(e,n,i,o){let l=0,g=0,u=1,h=k[n];const f=e=>{const n=e.clientX-l,i=(r=g+n*h,Math.max(50,Math.min(t.maxWidth,r)));var r;const a=Math.round(i/u);m(c,{width:`${i}px`,height:`${a}px`}),o.textContent=`${Math.round(i)} × ${a}`},b=t=>{document.removeEventListener("pointermove",f),document.removeEventListener("pointerup",b),s.classList.remove("notectl-image--resizing"),o.classList.remove("notectl-image__size-indicator--visible"),A();const e=Math.round(c.getBoundingClientRect().width);!function(t,e,n){const i=r(),o=i.getBlock(t);if(!o)return;const s=o.attrs?.width,l=o.attrs?.height;if(s===e&&l===n)return;const c=i.getNodePath(t);if(!c)return;const d={...o.attrs??{},width:e,height:n};a(i.transaction("command").setNodeAttr(c,d).build())}(i,e,Math.round(e/u)),t.target?.releasePointerCapture?.(t.pointerId)};e.addEventListener("pointerdown",t=>{t.preventDefault(),t.stopPropagation();const e="rtl"===d(s);h=function(t,e){const n=k[t];return e?-n:n}(n,e),l=t.clientX,g=c.getBoundingClientRect().width;const i=c.getBoundingClientRect().height;u=i>0?g/i:1,s.classList.add("notectl-image--resizing"),o.textContent=`${Math.round(g)} × ${Math.round(i)}`,o.classList.add("notectl-image__size-indicator--visible"),function(t,e){A(),C=document.createElement("style");const n=e?p(e):void 0;n&&C.setAttribute("nonce",n),C.textContent=`*{cursor:${t}!important;user-select:none!important}`,document.head.appendChild(C)}(e?L[n]:I[n],s),t.target.setPointerCapture(t.pointerId),document.addEventListener("pointermove",f),document.addEventListener("pointerup",b)})}function w(){A(),f&&(f.remove(),f=null)}return c.addEventListener("load",()=>{if(x)return;const e=r(),n=e.getBlock(h);if(!n||"image"!==n.type)return;const i=void 0!==n.attrs?.width,o=void 0!==n.attrs?.height;if(i&&o)return void(x=!0);const s=c.naturalWidth,l=c.naturalHeight;if(0===s||0===l)return;const d=Math.min(s,t.maxWidth),g=s>0?l/s:1,m=Math.round(d*g),p=e.getNodePath(h);if(!p)return;const u={...n.attrs??{},width:d,height:m};a(e.transaction("command").setNodeAttr(p,u).build()),x=!0}),{dom:s,contentDOM:null,update:t=>"image"===t.type&&(h=t.id,s.setAttribute("data-block-id",t.id),b(t),!0),selectNode(){s.classList.add("notectl-image--selected"),function(e){if(!t.resizable||f)return;f=document.createElement("div"),f.className="notectl-image__resize-overlay",f.setAttribute("data-notectl-no-print","");const o=document.createElement("div");o.className="notectl-image__size-indicator",f.appendChild(o);for(const t of["nw","ne","sw","se"]){const n=document.createElement("div");n.className=`notectl-image__resize-handle notectl-image__resize-handle--${t}`,n.setAttribute("aria-hidden","true"),_(n,t,e,o),f.appendChild(n)}if(n){const t=function(t,e){const n=t.shrinkWidth??null,i=t.growWidth??null;return n&&i?e.keyboardResizeHint(v(n),v(i)):""}(n,i);if(t){const e=document.createElement("div");e.className="notectl-image__keyboard-hint",e.setAttribute("aria-hidden","true"),e.textContent=t,f.appendChild(e)}}l.appendChild(f)}(h)},deselectNode(){s.classList.remove("notectl-image--selected"),w()},destroy(){w()}}}}var j=new h("image:upload"),E={growWidth:"Mod-Shift-ArrowRight",shrinkWidth:"Mod-Shift-ArrowLeft",growWidthLarge:"Mod-Shift-Alt-ArrowRight",shrinkWidthLarge:"Mod-Shift-Alt-ArrowLeft",resetSize:"Mod-Shift-0"},$={maxWidth:800,maxFileSize:10485760,acceptedTypes:["image/png","image/jpeg","image/gif","image/webp","image/svg+xml"],resizable:!0,resizeStep:10,resizeStepLarge:50},R=class{id="image";name="Image";priority=45;config;resolvedKeymap;uploadStates=/* @__PURE__ */new Map;blobUrls=/* @__PURE__ */new Set;context=null;locale;constructor(t){this.config={...$,...t},this.resolvedKeymap={...E,...t?.keymap}}async init(t){this.locale=await f(t,this.config.locale,w,y),t.registerStyleSheet('\n/* Image */\n.notectl-image {\n\tmargin: 8px 0;\n\tuser-select: none;\n\tline-height: 0;\n}\n\n.notectl-image--center {\n\ttext-align: center;\n}\n\n.notectl-image--start {\n\ttext-align: start;\n}\n\n.notectl-image--end {\n\ttext-align: end;\n}\n\n.notectl-image__container {\n\tdisplay: inline-block;\n\tposition: relative;\n\tline-height: 0;\n}\n\n.notectl-image__img {\n\tdisplay: block;\n\tmax-width: 100%;\n\tborder-radius: 4px;\n}\n\n.notectl-image--selected .notectl-image__container {\n\toutline: 2px solid var(--notectl-primary);\n\toutline-offset: 2px;\n\tborder-radius: 6px;\n}\n\n/* Alignment toolbar (appears on image selection) */\n.notectl-image__align-toolbar {\n\tdisplay: flex;\n\tgap: 2px;\n\tposition: absolute;\n\ttop: -36px;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\tbackground: var(--notectl-surface-overlay);\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 6px;\n\tpadding: 2px;\n\tbox-shadow: 0 2px 8px var(--notectl-shadow);\n\tz-index: 10;\n}\n\n.notectl-image__align-btn {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\theight: 28px;\n\tborder: none;\n\tbackground: transparent;\n\tborder-radius: 4px;\n\tcursor: pointer;\n\tcolor: var(--notectl-fg);\n}\n\n.notectl-image__align-btn:hover {\n\tbackground: var(--notectl-hover-bg);\n}\n\n.notectl-image__align-btn--active {\n\tbackground: var(--notectl-active-bg);\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-image__align-btn svg {\n\twidth: 16px;\n\theight: 16px;\n\tfill: currentColor;\n}\n\n/* Upload overlay */\n.notectl-image__overlay {\n\tposition: absolute;\n\tinset: 0;\n\tdisplay: none;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: rgba(255, 255, 255, 0.8);\n\tborder-radius: 4px;\n\tfont-size: 13px;\n\tcolor: var(--notectl-fg-muted);\n}\n\n.notectl-image__overlay--uploading {\n\tdisplay: flex;\n}\n\n.notectl-image__overlay--error {\n\tdisplay: flex;\n\tbackground: var(--notectl-danger-muted);\n\tcolor: var(--notectl-danger);\n}\n\n/* Resize overlay + handles */\n.notectl-image__resize-overlay {\n\tposition: absolute;\n\tinset: 0;\n\tpointer-events: none;\n}\n\n.notectl-image__resize-handle {\n\tposition: absolute;\n\twidth: 10px;\n\theight: 10px;\n\tbackground: var(--notectl-surface-raised);\n\tborder: 2px solid var(--notectl-primary);\n\tborder-radius: 50%;\n\tpointer-events: all;\n\tz-index: 2;\n\ttransition: transform 0.1s, background 0.1s;\n}\n\n.notectl-image__resize-handle:hover {\n\tbackground: var(--notectl-primary);\n\ttransform: scale(1.3);\n}\n\n.notectl-image--resizing .notectl-image__resize-handle {\n\tbackground: var(--notectl-primary);\n}\n\n.notectl-image__resize-handle--nw {\n\ttop: -5px;\n\tinset-inline-start: -5px;\n\tcursor: nwse-resize;\n}\n\n.notectl-image__resize-handle--ne {\n\ttop: -5px;\n\tinset-inline-end: -5px;\n\tcursor: nesw-resize;\n}\n\n.notectl-image__resize-handle--sw {\n\tbottom: -5px;\n\tinset-inline-start: -5px;\n\tcursor: nesw-resize;\n}\n\n.notectl-image__resize-handle--se {\n\tbottom: -5px;\n\tinset-inline-end: -5px;\n\tcursor: nwse-resize;\n}\n\n/* RTL cursor overrides — flip diagonal cursors when in RTL context */\n[dir="rtl"] .notectl-image__resize-handle--nw {\n\tcursor: nesw-resize;\n}\n\n[dir="rtl"] .notectl-image__resize-handle--ne {\n\tcursor: nwse-resize;\n}\n\n[dir="rtl"] .notectl-image__resize-handle--sw {\n\tcursor: nwse-resize;\n}\n\n[dir="rtl"] .notectl-image__resize-handle--se {\n\tcursor: nesw-resize;\n}\n\n/* Size indicator tooltip */\n.notectl-image__size-indicator {\n\tposition: absolute;\n\tbottom: -28px;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\tpadding: 2px 8px;\n\tbackground: var(--notectl-tooltip-bg);\n\tcolor: var(--notectl-tooltip-fg);\n\tfont-size: 11px;\n\tfont-weight: 500;\n\tborder-radius: 4px;\n\twhite-space: nowrap;\n\tpointer-events: none;\n\topacity: 0;\n\ttransition: opacity 0.15s;\n\tz-index: 3;\n}\n\n.notectl-image__size-indicator--visible {\n\topacity: 1;\n}\n\n/* Keyboard resize hint (shown on selection, hidden during drag) */\n.notectl-image__keyboard-hint {\n\tdisplay: none;\n\tposition: absolute;\n\tbottom: -28px;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\tpadding: 2px 8px;\n\tfont-size: 11px;\n\tcolor: var(--notectl-fg-muted);\n\twhite-space: nowrap;\n\tpointer-events: none;\n\tz-index: 3;\n}\n\n.notectl-image--selected .notectl-image__keyboard-hint {\n\tdisplay: block;\n}\n\n.notectl-image--resizing .notectl-image__keyboard-hint {\n\tdisplay: none;\n}\n\n/* Resizing feedback */\n.notectl-image--resizing .notectl-image__img {\n\topacity: 0.85;\n}\n'),t.registerStyleSheet("\n.notectl-image-popup {\n\tpadding: 8px;\n\tmin-width: 240px;\n}\n\n.notectl-image-popup__file-input {\n\tposition: absolute;\n\twidth: 0;\n\theight: 0;\n\toverflow: hidden;\n\topacity: 0;\n}\n\n.notectl-image-popup__upload-btn {\n\tdisplay: block;\n\twidth: 100%;\n\tpadding: 8px 12px;\n\tcursor: pointer;\n\ttext-align: center;\n\tbox-sizing: border-box;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-raised);\n\tcolor: var(--notectl-fg);\n}\n\n.notectl-image-popup__separator {\n\tdisplay: flex;\n\talign-items: center;\n\tmargin: 8px 0;\n\tcolor: var(--notectl-fg-muted);\n\tfont-size: 12px;\n}\n\n.notectl-image-popup__separator-line {\n\tflex: 1;\n\theight: 1px;\n\tbackground: var(--notectl-border);\n}\n\n.notectl-image-popup__separator-text {\n\tpadding: 0 8px;\n}\n\n.notectl-image-popup__url-input {\n\twidth: 100%;\n\tpadding: 6px 8px;\n\tbox-sizing: border-box;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-overlay);\n\tcolor: var(--notectl-fg);\n}\n\n.notectl-image-popup__insert-btn {\n\twidth: 100%;\n\tpadding: 8px 12px;\n\tmargin-top: 4px;\n\tcursor: pointer;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-raised);\n\tcolor: var(--notectl-fg);\n}\n"),this.context=t,this.registerNodeSpec(t),this.registerNodeView(t),function(t){t.registerCommand("insertImage",()=>x(t,{src:""})),t.registerCommand("removeImage",()=>function(t){const e=t.getState(),n=e.selection;if(!o(n))return!1;const i=e.getBlock(n.nodeId);if(!i||"image"!==i.type)return!1;const a=e.getNodePath(n.nodeId);if(!a||0===a.length)return!1;const s=c(e,r(n.nodeId,a));return!!s&&(t.dispatch(s),!0)}(t))}(t),this.registerResizeCommands(t),this.registerResizeKeymaps(t),this.registerFileHandler(t),this.registerToolbarItem(t)}destroy(){for(const t of this.blobUrls)URL.revokeObjectURL(t);this.blobUrls.clear(),this.uploadStates.clear(),this.context=null}onStateChange(t,e,n){if(!this.context)return;for(const r of this.uploadStates.keys())e.getBlock(r)||this.uploadStates.delete(r);const i=this.isImageSelected(t),o=this.isImageSelected(e);!i&&o&&this.announceImageSelection(e)}registerNodeSpec(t){const e=this.locale;t.registerNodeSpec({type:"image",group:"block",isVoid:!0,selectable:!0,attrs:{src:{default:""},alt:{default:""},align:{default:"center"}},toDOM(t){const n=s("figure",t.id);n.className="notectl-image",n.setAttribute("data-void","true"),n.setAttribute("data-selectable","true");const i=document.createElement("div");i.className="notectl-image__container";const o=t.attrs?.alt??"",r=t.attrs?.width,a=t.attrs?.height,l=document.createElement("img");l.className="notectl-image__img",l.src=t.attrs?.src??"",l.alt=o,l.draggable=!1,void 0!==r&&u(l,"width",`${r}px`),void 0!==a&&u(l,"height",`${a}px`);const c={start:"notectl-image--start",center:"notectl-image--center",end:"notectl-image--end"}[t.attrs?.align??"center"];return c&&n.classList.add(c),n.setAttribute("aria-label",e.imageAria(o,r,a)),i.appendChild(l),n.appendChild(i),n},toHTML(t){const e=l(t.attrs?.src??""),n=l(t.attrs?.alt??""),i=t.attrs?.width,o=t.attrs?.height;return`<figure><img src="${e}" alt="${n}"${(void 0!==i?` width="${i}"`:"")+(void 0!==o?` height="${o}"`:"")}></figure>`},parseHTML:[{tag:"figure",getAttrs(t){const e=t.querySelector("img");if(!e)return!1;const n={src:e.getAttribute("src")??"",alt:e.getAttribute("alt")??"",align:"center"},i=e.getAttribute("width"),o=e.getAttribute("height");i&&(n.width=Number.parseInt(i,10)),o&&(n.height=Number.parseInt(o,10));const r=t.style?.textAlign??"";return"start"===r||"end"===r||"center"===r?n.align=r:"left"===r?n.align="start":"right"===r?n.align="end":t.classList.contains("notectl-align-start")||t.classList.contains("notectl-align-left")||t.classList.contains("notectl-image--start")||t.classList.contains("notectl-image--left")?n.align="start":t.classList.contains("notectl-align-end")||t.classList.contains("notectl-align-right")||t.classList.contains("notectl-image--end")||t.classList.contains("notectl-image--right")?n.align="end":t.classList.contains("notectl-align-center")&&(n.align="center"),n}},{tag:"img",getAttrs(t){const e={src:t.getAttribute("src")??"",alt:t.getAttribute("alt")??"",align:"center"},n=t.getAttribute("width"),i=t.getAttribute("height");return n&&(e.width=Number.parseInt(n,10)),i&&(e.height=Number.parseInt(i,10)),e}}],sanitize:{tags:["figure","img"],attrs:["src","alt","width","height","class","style"]}})}registerNodeView(t){t.registerNodeView("image",N(this.config,this.uploadStates,this.resolvedKeymap,this.locale))}registerResizeCommands(t){const e=this.config.resizeStep??10,n=this.config.resizeStepLarge??50,i=this.config.maxWidth;t.registerCommand("resizeImageGrow",()=>{const n=_(t,e,i);return n&&this.announceCurrentSize(t),n}),t.registerCommand("resizeImageShrink",()=>{const n=_(t,-e,i);return n&&this.announceCurrentSize(t),n}),t.registerCommand("resizeImageGrowLarge",()=>{const e=_(t,n,i);return e&&this.announceCurrentSize(t),e}),t.registerCommand("resizeImageShrinkLarge",()=>{const e=_(t,-n,i);return e&&this.announceCurrentSize(t),e}),t.registerCommand("resetImageSize",()=>{const e=function(t){const e=t.getState(),n=e.selection;if(!o(n))return!1;const i=e.getBlock(n.nodeId);if(!i||"image"!==i.type)return!1;const r=e.getNodePath(n.nodeId);if(!r)return!1;const a={...i.attrs??{}},s=Object.fromEntries(Object.entries(a).filter(([t])=>"width"!==t&&"height"!==t)),l=e.transaction("command").setNodeAttr(r,s).build();return t.dispatch(l),!0}(t);return e&&t.announce(this.locale.resetToNaturalSize),e})}registerResizeKeymaps(t){const e={};for(const[n,i]of Object.entries({growWidth:"resizeImageGrow",shrinkWidth:"resizeImageShrink",growWidthLarge:"resizeImageGrowLarge",shrinkWidthLarge:"resizeImageShrinkLarge",resetSize:"resetImageSize"})){const o=this.resolvedKeymap[n]??null;o&&(e[o]=()=>t.executeCommand(i))}Object.keys(e).length>0&&t.registerKeymap(e)}registerFileHandler(t){t.registerFileHandler("image/*",async(e,n)=>!!this.isAcceptedType(e.type)&&(this.handleFileInsert(t,e),!0))}handleFileInsert(t,e){if(e.size>this.config.maxFileSize)return;const n=URL.createObjectURL(e);if(this.blobUrls.add(n),!x(t,{src:n}))return URL.revokeObjectURL(n),void this.blobUrls.delete(n);const i=t.getState().selection;if(!o(i))return;const r=i.nodeId;this.uploadStates.set(r,"uploading"),t.getService(j)?this.uploadFile(t,e,r,n):this.uploadStates.set(r,"complete")}async uploadFile(t,e,n,i){const o=t.getService(j);if(o)try{const r=await o.upload(e);this.uploadStates.set(n,"complete");const a=t.getState(),s=a.getBlock(n);if(!s)return;const l=a.getNodePath(n);if(!l)return;const c={...s.attrs??{},src:r.url,...void 0!==r.width?{width:r.width}:{},...void 0!==r.height?{height:r.height}:{}},d=a.transaction("command").setNodeAttr(l,c).build();t.dispatch(d),URL.revokeObjectURL(i),this.blobUrls.delete(i)}catch{this.uploadStates.set(n,"error"),t.announce(this.locale.uploadFailed)}}registerToolbarItem(t){t.registerToolbarItem({id:"image",group:"insert",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></svg>',label:this.locale.insertImage,tooltip:this.locale.insertImageTooltip,command:"insertImage",popupType:"custom",renderPopup:(t,e,n)=>{!function(t,e,n){t.classList.add("notectl-image-popup"),function(t,e,n){const i=document.createElement("input");i.type="file",i.accept=n.acceptedTypes.join(","),i.className="notectl-image-popup__file-input";const o=document.createElement("button");o.type="button",o.textContent=n.locale.uploadFromComputer,o.setAttribute("aria-label",n.locale.uploadAria),o.className="notectl-image-popup__upload-btn",o.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),i.click()}),i.addEventListener("change",()=>{const t=i.files?.[0];t&&(n.onFileInsert(e,t),n.onClose(),e.getContainer().focus())}),t.appendChild(i),t.appendChild(o)}(t,e,n),function(t,e){const n=document.createElement("div");n.className="notectl-image-popup__separator";const i=document.createElement("span");i.className="notectl-image-popup__separator-line";const o=document.createElement("span");o.textContent=e.separator,o.className="notectl-image-popup__separator-text";const r=document.createElement("span");r.className="notectl-image-popup__separator-line",n.appendChild(i),n.appendChild(o),n.appendChild(r),t.appendChild(n)}(t,n.locale),function(t,e,n){const i=document.createElement("input");i.type="url",i.placeholder=n.locale.urlPlaceholder,i.setAttribute("aria-label",n.locale.urlAria),i.className="notectl-image-popup__url-input";const o=document.createElement("button");o.type="button",o.textContent=n.locale.insertButton,o.setAttribute("aria-label",n.locale.insertAria),o.className="notectl-image-popup__insert-btn";const r=()=>{const t=i.value.trim();t&&(x(e,{src:t}),n.onClose(),e.getContainer().focus())};o.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),r()}),i.addEventListener("keydown",t=>{"Enter"===t.key&&(t.preventDefault(),r())}),t.appendChild(i),t.appendChild(o),requestAnimationFrame(()=>i.focus())}(t,e,n)}(t,e,{acceptedTypes:this.config.acceptedTypes,locale:this.locale,onFileInsert:(t,e)=>this.handleFileInsert(t,e),onClose:n})}})}isAcceptedType(t){return this.config.acceptedTypes.some(e=>e===t||e.endsWith("/*")&&t.startsWith(e.slice(0,-1)))}isImageSelected(t){const e=t.selection;return!!o(e)&&"image"===t.getBlock(e.nodeId)?.type}announceImageSelection(t){if(!this.context)return;const e=t.selection;if(!o(e))return;const n=t.getBlock(e.nodeId);if(!n||"image"!==n.type)return;const i=n.attrs?.alt??"",r=n.attrs?.width,a=n.attrs?.height,s=[this.locale.imageSelected];i&&s.push(`${this.locale.altTextPrefix}${i}.`),void 0!==r&&void 0!==a&&s.push(this.locale.imageSizeAnnounce(r,a));const l=this.resolvedKeymap.shrinkWidth??null,c=this.resolvedKeymap.growWidth??null;l&&c&&s.push(this.locale.resizeHint(v(l),v(c))),this.context.announce(s.join(" "))}announceCurrentSize(t){const e=t.getState(),n=e.selection;if(!o(n))return;const i=e.getBlock(n.nodeId);if(!i||"image"!==i.type)return;const r=i.attrs?.width,a=i.attrs?.height;void 0!==r&&void 0!==a&&t.announce(this.locale.imageResized(r,a))}};export{y as a,w as i,E as n,j as r,R as t};
|
|
2
|
+
//# sourceMappingURL=ImagePlugin-kgokm-a1.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImagePlugin-kgokm-a1.mjs","names":[],"sources":["../../src/editor/styles/image.ts","../../src/plugins/image/ImageCommands.ts","../../src/plugins/image/ImageLocale.ts","../../src/plugins/image/ImageNodeView.ts","../../src/plugins/image/ImagePopup.ts","../../src/plugins/image/ImagePopupStyles.ts","../../src/plugins/image/ImageUpload.ts","../../src/plugins/image/ImagePlugin.ts"],"sourcesContent":["/** Image styles — display, alignment, resize handles, upload overlay. */\nexport const IMAGE_CSS = `\n/* Image */\n.notectl-image {\n\tmargin: 8px 0;\n\tuser-select: none;\n\tline-height: 0;\n}\n\n.notectl-image--center {\n\ttext-align: center;\n}\n\n.notectl-image--start {\n\ttext-align: start;\n}\n\n.notectl-image--end {\n\ttext-align: end;\n}\n\n.notectl-image__container {\n\tdisplay: inline-block;\n\tposition: relative;\n\tline-height: 0;\n}\n\n.notectl-image__img {\n\tdisplay: block;\n\tmax-width: 100%;\n\tborder-radius: 4px;\n}\n\n.notectl-image--selected .notectl-image__container {\n\toutline: 2px solid var(--notectl-primary);\n\toutline-offset: 2px;\n\tborder-radius: 6px;\n}\n\n/* Alignment toolbar (appears on image selection) */\n.notectl-image__align-toolbar {\n\tdisplay: flex;\n\tgap: 2px;\n\tposition: absolute;\n\ttop: -36px;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\tbackground: var(--notectl-surface-overlay);\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 6px;\n\tpadding: 2px;\n\tbox-shadow: 0 2px 8px var(--notectl-shadow);\n\tz-index: 10;\n}\n\n.notectl-image__align-btn {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\theight: 28px;\n\tborder: none;\n\tbackground: transparent;\n\tborder-radius: 4px;\n\tcursor: pointer;\n\tcolor: var(--notectl-fg);\n}\n\n.notectl-image__align-btn:hover {\n\tbackground: var(--notectl-hover-bg);\n}\n\n.notectl-image__align-btn--active {\n\tbackground: var(--notectl-active-bg);\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-image__align-btn svg {\n\twidth: 16px;\n\theight: 16px;\n\tfill: currentColor;\n}\n\n/* Upload overlay */\n.notectl-image__overlay {\n\tposition: absolute;\n\tinset: 0;\n\tdisplay: none;\n\talign-items: center;\n\tjustify-content: center;\n\tbackground: rgba(255, 255, 255, 0.8);\n\tborder-radius: 4px;\n\tfont-size: 13px;\n\tcolor: var(--notectl-fg-muted);\n}\n\n.notectl-image__overlay--uploading {\n\tdisplay: flex;\n}\n\n.notectl-image__overlay--error {\n\tdisplay: flex;\n\tbackground: var(--notectl-danger-muted);\n\tcolor: var(--notectl-danger);\n}\n\n/* Resize overlay + handles */\n.notectl-image__resize-overlay {\n\tposition: absolute;\n\tinset: 0;\n\tpointer-events: none;\n}\n\n.notectl-image__resize-handle {\n\tposition: absolute;\n\twidth: 10px;\n\theight: 10px;\n\tbackground: var(--notectl-surface-raised);\n\tborder: 2px solid var(--notectl-primary);\n\tborder-radius: 50%;\n\tpointer-events: all;\n\tz-index: 2;\n\ttransition: transform 0.1s, background 0.1s;\n}\n\n.notectl-image__resize-handle:hover {\n\tbackground: var(--notectl-primary);\n\ttransform: scale(1.3);\n}\n\n.notectl-image--resizing .notectl-image__resize-handle {\n\tbackground: var(--notectl-primary);\n}\n\n.notectl-image__resize-handle--nw {\n\ttop: -5px;\n\tinset-inline-start: -5px;\n\tcursor: nwse-resize;\n}\n\n.notectl-image__resize-handle--ne {\n\ttop: -5px;\n\tinset-inline-end: -5px;\n\tcursor: nesw-resize;\n}\n\n.notectl-image__resize-handle--sw {\n\tbottom: -5px;\n\tinset-inline-start: -5px;\n\tcursor: nesw-resize;\n}\n\n.notectl-image__resize-handle--se {\n\tbottom: -5px;\n\tinset-inline-end: -5px;\n\tcursor: nwse-resize;\n}\n\n/* RTL cursor overrides — flip diagonal cursors when in RTL context */\n[dir=\"rtl\"] .notectl-image__resize-handle--nw {\n\tcursor: nesw-resize;\n}\n\n[dir=\"rtl\"] .notectl-image__resize-handle--ne {\n\tcursor: nwse-resize;\n}\n\n[dir=\"rtl\"] .notectl-image__resize-handle--sw {\n\tcursor: nwse-resize;\n}\n\n[dir=\"rtl\"] .notectl-image__resize-handle--se {\n\tcursor: nesw-resize;\n}\n\n/* Size indicator tooltip */\n.notectl-image__size-indicator {\n\tposition: absolute;\n\tbottom: -28px;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\tpadding: 2px 8px;\n\tbackground: var(--notectl-tooltip-bg);\n\tcolor: var(--notectl-tooltip-fg);\n\tfont-size: 11px;\n\tfont-weight: 500;\n\tborder-radius: 4px;\n\twhite-space: nowrap;\n\tpointer-events: none;\n\topacity: 0;\n\ttransition: opacity 0.15s;\n\tz-index: 3;\n}\n\n.notectl-image__size-indicator--visible {\n\topacity: 1;\n}\n\n/* Keyboard resize hint (shown on selection, hidden during drag) */\n.notectl-image__keyboard-hint {\n\tdisplay: none;\n\tposition: absolute;\n\tbottom: -28px;\n\tleft: 50%;\n\ttransform: translateX(-50%);\n\tpadding: 2px 8px;\n\tfont-size: 11px;\n\tcolor: var(--notectl-fg-muted);\n\twhite-space: nowrap;\n\tpointer-events: none;\n\tz-index: 3;\n}\n\n.notectl-image--selected .notectl-image__keyboard-hint {\n\tdisplay: block;\n}\n\n.notectl-image--resizing .notectl-image__keyboard-hint {\n\tdisplay: none;\n}\n\n/* Resizing feedback */\n.notectl-image--resizing .notectl-image__img {\n\topacity: 0.85;\n}\n`;\n","/**\n * Image plugin commands: insert, remove, and attribute updates.\n * Supports both root-level and nested contexts (e.g. images inside table cells).\n */\n\nimport { insertBlockObjectOnOwnLine } from '../../commands/BlockInsertion.js';\nimport { deleteNodeSelection } from '../../commands/NodeSelectionCommands.js';\nimport type { BlockAttrs, BlockNode } from '../../model/Document.js';\nimport { createBlockNode, getBlockChildren, isBlockNode } from '../../model/Document.js';\nimport { createNodeSelection, isGapCursor, isNodeSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { PluginContext } from '../Plugin.js';\nimport type { ImageAttrs } from './ImageUpload.js';\n\n/**\n * Inserts an image block. When the cursor is inside a table cell,\n * the image is inserted as a child of the cell. Otherwise it is\n * inserted after the current block at document root.\n */\nexport function insertImage(\n\tcontext: PluginContext,\n\tattrs: Partial<ImageAttrs> & { readonly src: string },\n): boolean {\n\tconst state = context.getState();\n\tconst sel = state.selection;\n\n\tconst imageAttrs: BlockAttrs = {\n\t\tsrc: attrs.src,\n\t\talt: attrs.alt ?? '',\n\t\talign: attrs.align ?? 'center',\n\t\t...(attrs.width !== undefined ? { width: attrs.width } : {}),\n\t\t...(attrs.height !== undefined ? { height: attrs.height } : {}),\n\t};\n\n\tif (isGapCursor(sel)) return false;\n\n\tconst anchorBlockId: BlockId = isNodeSelection(sel) ? sel.nodeId : sel.anchor.blockId;\n\n\t// Check if we're inside a table cell\n\tconst cellId: BlockId | undefined = findTableCellAncestor(state, anchorBlockId);\n\tif (cellId) {\n\t\treturn insertImageIntoCell(state, context, cellId, imageAttrs);\n\t}\n\n\treturn insertImageAtRoot(state, context, anchorBlockId, imageAttrs);\n}\n\n/** Finds a table_cell ancestor for the given block (or the block itself). */\nfunction findTableCellAncestor(state: EditorState, bid: BlockId): BlockId | undefined {\n\tconst block: BlockNode | undefined = state.getBlock(bid);\n\tif (block?.type === 'table_cell') return bid;\n\n\tconst path: BlockId[] | undefined = state.getNodePath(bid);\n\tif (!path) return undefined;\n\n\tfor (const id of path) {\n\t\tconst node: BlockNode | undefined = state.getBlock(id);\n\t\tif (node?.type === 'table_cell') return id;\n\t}\n\treturn undefined;\n}\n\n/** Inserts an image on its own line at document root, after the anchor block. */\nfunction insertImageAtRoot(\n\tstate: EditorState,\n\tcontext: PluginContext,\n\tanchorBlockId: BlockId,\n\timageAttrs: BlockAttrs,\n): boolean {\n\tconst imageBlock: BlockNode = createBlockNode(nodeType('image'), [], undefined, imageAttrs);\n\tconst builder = state.transaction('command');\n\tconst trailing = insertBlockObjectOnOwnLine(state, builder, anchorBlockId, imageBlock);\n\tif (!trailing) return false;\n\n\tbuilder.setSelection(createNodeSelection(imageBlock.id, []));\n\tcontext.dispatch(builder.build());\n\treturn true;\n}\n\n/** Inserts an image as a child of a table cell. */\nfunction insertImageIntoCell(\n\tstate: EditorState,\n\tcontext: PluginContext,\n\tcellId: BlockId,\n\timageAttrs: BlockAttrs,\n): boolean {\n\tconst cellPath: BlockId[] | undefined = state.getNodePath(cellId);\n\tif (!cellPath) return false;\n\n\tconst imageBlock: BlockNode = createBlockNode(nodeType('image'), [], undefined, imageAttrs);\n\n\t// Remove existing block children first (if any)\n\tconst cell: BlockNode | undefined = state.getBlock(cellId);\n\tif (!cell) return false;\n\n\tconst builder = state.transaction('command');\n\tconst blockChildren: readonly BlockNode[] = getBlockChildren(cell);\n\tfor (let i = blockChildren.length - 1; i >= 0; i--) {\n\t\t// Find the raw index in children array\n\t\tconst rawIndex: number = cell.children.findIndex(\n\t\t\t(c) => isBlockNode(c) && c.id === blockChildren[i]?.id,\n\t\t);\n\t\tif (rawIndex !== -1) {\n\t\t\tbuilder.removeNode(cellPath, rawIndex);\n\t\t}\n\t}\n\n\t// Insert image at index 0 (before any text nodes)\n\tbuilder.insertNode(cellPath, 0, imageBlock);\n\tbuilder.setSelection(createNodeSelection(imageBlock.id, [...cellPath, imageBlock.id]));\n\n\tcontext.dispatch(builder.build());\n\treturn true;\n}\n\n/** Removes the currently selected image block (works for nested images too). */\nexport function removeImage(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst sel = state.selection;\n\tif (!isNodeSelection(sel)) return false;\n\n\tconst block: BlockNode | undefined = state.getBlock(sel.nodeId);\n\tif (!block || block.type !== 'image') return false;\n\n\tconst nodePath: BlockId[] | undefined = state.getNodePath(sel.nodeId);\n\tif (!nodePath || nodePath.length === 0) return false;\n\n\tconst tr = deleteNodeSelection(state, createNodeSelection(sel.nodeId, nodePath));\n\tif (!tr) return false;\n\tcontext.dispatch(tr);\n\treturn true;\n}\n\n/** Updates attributes on the currently selected image block. */\nexport function setImageAttr(context: PluginContext, attrs: Partial<ImageAttrs>): boolean {\n\tconst state = context.getState();\n\tconst sel = state.selection;\n\tif (!isNodeSelection(sel)) return false;\n\n\tconst block: BlockNode | undefined = state.getBlock(sel.nodeId);\n\tif (!block || block.type !== 'image') return false;\n\n\tconst path: BlockId[] | undefined = state.getNodePath(sel.nodeId);\n\tif (!path) return false;\n\n\tconst merged: BlockAttrs = { ...(block.attrs ?? {}), ...attrs };\n\tconst tr = state.transaction('command').setNodeAttr(path, merged).build();\n\n\tcontext.dispatch(tr);\n\treturn true;\n}\n\n/** Minimum image width in pixels (shared with NodeView). */\nexport const MIN_IMAGE_WIDTH = 50;\n\n/**\n * Resizes the currently selected image by a pixel delta, preserving aspect ratio.\n * Returns false if no image is selected or the image has no width/height attributes.\n */\nexport function resizeImageByDelta(\n\tcontext: PluginContext,\n\tdelta: number,\n\tmaxWidth: number,\n): boolean {\n\tconst state = context.getState();\n\tconst sel = state.selection;\n\tif (!isNodeSelection(sel)) return false;\n\n\tconst block: BlockNode | undefined = state.getBlock(sel.nodeId);\n\tif (!block || block.type !== 'image') return false;\n\n\tconst currentWidth: number | undefined = block.attrs?.width as number | undefined;\n\tconst currentHeight: number | undefined = block.attrs?.height as number | undefined;\n\tif (currentWidth === undefined || currentHeight === undefined) return false;\n\n\tconst aspectRatio: number = currentHeight > 0 ? currentWidth / currentHeight : 1;\n\tconst clampedWidth: number = Math.max(MIN_IMAGE_WIDTH, Math.min(maxWidth, currentWidth + delta));\n\tconst newHeight: number = Math.round(clampedWidth / aspectRatio);\n\n\tif (clampedWidth === currentWidth && newHeight === currentHeight) return false;\n\n\treturn setImageAttr(context, { width: clampedWidth, height: newHeight });\n}\n\n/** Resets the currently selected image to its natural size by removing width/height. */\nexport function resetImageSize(context: PluginContext): boolean {\n\tconst state = context.getState();\n\tconst sel = state.selection;\n\tif (!isNodeSelection(sel)) return false;\n\n\tconst block: BlockNode | undefined = state.getBlock(sel.nodeId);\n\tif (!block || block.type !== 'image') return false;\n\n\tconst path: BlockId[] | undefined = state.getNodePath(sel.nodeId);\n\tif (!path) return false;\n\n\tconst attrs: BlockAttrs = { ...(block.attrs ?? {}) };\n\tconst cleaned: BlockAttrs = Object.fromEntries(\n\t\tObject.entries(attrs).filter(([k]) => k !== 'width' && k !== 'height'),\n\t);\n\n\tconst tr = state.transaction('command').setNodeAttr(path, cleaned).build();\n\tcontext.dispatch(tr);\n\treturn true;\n}\n\n/** Registers all image commands on the plugin context. */\nexport function registerImageCommands(context: PluginContext): void {\n\tcontext.registerCommand('insertImage', () => {\n\t\treturn insertImage(context, { src: '' });\n\t});\n\n\tcontext.registerCommand('removeImage', () => {\n\t\treturn removeImage(context);\n\t});\n}\n","/** Locale interface and default English locale for the ImagePlugin. */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface ImageLocale {\n\treadonly insertImage: string;\n\treadonly insertImageTooltip: string;\n\treadonly uploadFromComputer: string;\n\treadonly uploadAria: string;\n\treadonly separator: string;\n\treadonly urlPlaceholder: string;\n\treadonly urlAria: string;\n\treadonly insertButton: string;\n\treadonly insertAria: string;\n\treadonly imageAria: (alt: string, width?: number, height?: number) => string;\n\treadonly resetToNaturalSize: string;\n\treadonly uploadFailed: string;\n\treadonly uploading: string;\n\treadonly resizeHandleLabel: (position: string) => string;\n\treadonly imageSelected: string;\n\treadonly altTextPrefix: string;\n\treadonly imageSizeAnnounce: (w: number, h: number) => string;\n\treadonly resizeHint: (shrink: string, grow: string) => string;\n\treadonly imageResized: (w: number, h: number) => string;\n\treadonly keyboardResizeHint: (shrink: string, grow: string) => string;\n}\n\n// --- Default English Locale ---\n\nexport const IMAGE_LOCALE_EN: ImageLocale = {\n\tinsertImage: 'Insert Image',\n\tinsertImageTooltip: 'Insert Image',\n\tuploadFromComputer: 'Upload from computer',\n\tuploadAria: 'Upload image from computer',\n\tseparator: 'or',\n\turlPlaceholder: 'https://...',\n\turlAria: 'Image URL',\n\tinsertButton: 'Insert',\n\tinsertAria: 'Insert image',\n\timageAria: (alt: string, width?: number, height?: number) => {\n\t\tconst parts: string[] = [alt || 'Image'];\n\t\tif (width !== undefined && height !== undefined) {\n\t\t\tparts.push(`${width} by ${height} pixels`);\n\t\t}\n\t\treturn parts.join(', ');\n\t},\n\tresetToNaturalSize: 'Image reset to natural size.',\n\tuploadFailed: 'Upload failed.',\n\tuploading: 'Uploading...',\n\tresizeHandleLabel: (position: string) => `Resize ${position}`,\n\timageSelected: 'Image selected.',\n\taltTextPrefix: 'Alt text: ',\n\timageSizeAnnounce: (w: number, h: number) => `Size: ${w} by ${h} pixels.`,\n\tresizeHint: (shrink: string, grow: string) => `${shrink} / ${grow} to resize.`,\n\timageResized: (w: number, h: number) => `Image resized to ${w} by ${h} pixels.`,\n\tkeyboardResizeHint: (shrink: string, grow: string) => `${shrink} / ${grow} to resize`,\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<ImageLocale> = import.meta.glob<{\n\tdefault: ImageLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadImageLocale(lang: string): Promise<ImageLocale> {\n\treturn loadLocaleModule(localeModules, lang, IMAGE_LOCALE_EN);\n}\n","/**\n * NodeView factory for image blocks.\n * Renders <figure> with <img>, handles selection state, upload overlay,\n * resize with 4 corner handles + live size indicator, and a keyboard-hint\n * showing resize shortcuts when the image is selected.\n */\n\nimport type { BlockAttrs, BlockNode } from '../../model/Document.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { getTextDirection } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport {\n\tgetStyleNonceForNode,\n\tsetStyleProperties,\n\tsetStyleProperty,\n} from '../../style/StyleRuntime.js';\nimport type { NodeView, NodeViewFactory } from '../../view/NodeView.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { IMAGE_LOCALE_EN, type ImageLocale } from './ImageLocale.js';\nimport type { ImageKeymap, ImagePluginConfig, UploadState } from './ImageUpload.js';\n\nconst ALIGNMENT_CLASSES: Record<string, string> = {\n\tstart: 'notectl-image--start',\n\tcenter: 'notectl-image--center',\n\tend: 'notectl-image--end',\n};\n\nconst MIN_IMAGE_WIDTH = 50;\n\ntype HandlePosition = 'nw' | 'ne' | 'sw' | 'se';\n\nconst HANDLE_CURSORS: Readonly<Record<HandlePosition, string>> = {\n\tnw: 'nwse-resize',\n\tne: 'nesw-resize',\n\tsw: 'nesw-resize',\n\tse: 'nwse-resize',\n};\n\n/** +1 means dragging right increases width; -1 means dragging left does. */\nconst HANDLE_X_SIGN: Readonly<Record<HandlePosition, 1 | -1>> = {\n\tnw: -1,\n\tne: 1,\n\tsw: -1,\n\tse: 1,\n};\n\nconst HANDLE_POSITIONS_LTR: Readonly<Record<HandlePosition, string>> = {\n\tnw: 'top-left',\n\tne: 'top-right',\n\tsw: 'bottom-left',\n\tse: 'bottom-right',\n};\n\nconst HANDLE_POSITIONS_RTL: Readonly<Record<HandlePosition, string>> = {\n\tnw: 'top-right',\n\tne: 'top-left',\n\tsw: 'bottom-right',\n\tse: 'bottom-left',\n};\n\nconst RTL_CURSOR_MAP: Readonly<Record<HandlePosition, string>> = {\n\tnw: 'nesw-resize',\n\tne: 'nwse-resize',\n\tsw: 'nwse-resize',\n\tse: 'nesw-resize',\n};\n\n/** Returns the direction-aware ARIA label for a resize handle. */\nexport function getHandleLabel(\n\tposition: HandlePosition,\n\tisRtl: boolean,\n\tlocale: ImageLocale = IMAGE_LOCALE_EN,\n): string {\n\tconst positionName: string = (isRtl ? HANDLE_POSITIONS_RTL : HANDLE_POSITIONS_LTR)[position];\n\treturn locale.resizeHandleLabel(positionName);\n}\n\n/** Returns the X-sign for resize drag, flipped in RTL. */\nexport function getResizeXSign(position: HandlePosition, isRtl: boolean): 1 | -1 {\n\tconst sign: 1 | -1 = HANDLE_X_SIGN[position];\n\treturn isRtl ? (-sign as 1 | -1) : sign;\n}\n\n// --- Global cursor override during resize ---\n\nlet activeCursorStyle: HTMLStyleElement | null = null;\n\nfunction setGlobalResizeCursor(cursor: string, referenceNode?: Node): void {\n\tclearGlobalResizeCursor();\n\tactiveCursorStyle = document.createElement('style');\n\tconst nonce = referenceNode ? getStyleNonceForNode(referenceNode) : undefined;\n\tif (nonce) {\n\t\tactiveCursorStyle.setAttribute('nonce', nonce);\n\t}\n\tactiveCursorStyle.textContent = `*{cursor:${cursor}!important;user-select:none!important}`;\n\tdocument.head.appendChild(activeCursorStyle);\n}\n\nfunction clearGlobalResizeCursor(): void {\n\tif (activeCursorStyle) {\n\t\tactiveCursorStyle.remove();\n\t\tactiveCursorStyle = null;\n\t}\n}\n\n/** Builds the keyboard-hint text from the resolved keymap. */\nfunction buildKeyboardHintText(\n\tresolvedKeymap: Readonly<Record<keyof ImageKeymap, string | null>>,\n\tlocale: ImageLocale,\n): string {\n\tconst shrink: string | null = resolvedKeymap.shrinkWidth ?? null;\n\tconst grow: string | null = resolvedKeymap.growWidth ?? null;\n\tif (!shrink || !grow) return '';\n\treturn locale.keyboardResizeHint(formatShortcut(shrink), formatShortcut(grow));\n}\n\n/** Creates a NodeViewFactory for image blocks. */\nexport function createImageNodeViewFactory(\n\tconfig: ImagePluginConfig,\n\tuploadStates: Map<BlockId, UploadState>,\n\tresolvedKeymap?: Readonly<Record<keyof ImageKeymap, string | null>>,\n\tlocale: ImageLocale = IMAGE_LOCALE_EN,\n): NodeViewFactory {\n\treturn (\n\t\tnode: BlockNode,\n\t\tgetState: () => EditorState,\n\t\tdispatch: (tr: Transaction) => void,\n\t): NodeView => {\n\t\t// --- DOM Construction ---\n\t\tconst figure: HTMLElement = document.createElement('figure');\n\t\tfigure.className = 'notectl-image';\n\t\tfigure.setAttribute('data-block-id', node.id);\n\t\tfigure.setAttribute('data-void', 'true');\n\t\tfigure.setAttribute('data-selectable', 'true');\n\n\t\tconst container: HTMLDivElement = document.createElement('div');\n\t\tcontainer.className = 'notectl-image__container';\n\n\t\tconst img: HTMLImageElement = document.createElement('img');\n\t\timg.className = 'notectl-image__img';\n\t\timg.draggable = false;\n\n\t\tconst overlay: HTMLDivElement = document.createElement('div');\n\t\toverlay.className = 'notectl-image__overlay';\n\n\t\tcontainer.appendChild(img);\n\t\tcontainer.appendChild(overlay);\n\t\tfigure.appendChild(container);\n\n\t\tlet currentNodeId: BlockId = node.id;\n\t\tlet resizeOverlay: HTMLDivElement | null = null;\n\n\t\t// --- ARIA Label ---\n\n\t\tfunction updateAriaLabel(n: BlockNode): void {\n\t\t\tconst alt: string = (n.attrs?.alt as string | undefined) ?? '';\n\t\t\tconst width: number | undefined = n.attrs?.width as number | undefined;\n\t\t\tconst height: number | undefined = n.attrs?.height as number | undefined;\n\t\t\tfigure.setAttribute('aria-label', locale.imageAria(alt, width, height));\n\t\t}\n\n\t\t// --- Attribute Application ---\n\n\t\tfunction applyAttrs(n: BlockNode): void {\n\t\t\tconst src: string = (n.attrs?.src as string | undefined) ?? '';\n\t\t\tconst alt: string = (n.attrs?.alt as string | undefined) ?? '';\n\t\t\tconst width: number | undefined = n.attrs?.width as number | undefined;\n\t\t\tconst height: number | undefined = n.attrs?.height as number | undefined;\n\t\t\tconst align: string = (n.attrs?.align as string | undefined) ?? 'center';\n\n\t\t\t// Only update src when it changes to avoid re-triggering load events\n\t\t\tif (img.src !== src) img.src = src;\n\t\t\timg.alt = alt;\n\n\t\t\tif (width !== undefined) {\n\t\t\t\tsetStyleProperty(img, 'width', `${width}px`);\n\t\t\t} else {\n\t\t\t\tsetStyleProperty(img, 'width', '');\n\t\t\t}\n\t\t\tif (height !== undefined) {\n\t\t\t\tsetStyleProperty(img, 'height', `${height}px`);\n\t\t\t} else {\n\t\t\t\tsetStyleProperty(img, 'height', '');\n\t\t\t}\n\n\t\t\tfor (const cls of Object.values(ALIGNMENT_CLASSES)) {\n\t\t\t\tfigure.classList.remove(cls);\n\t\t\t}\n\t\t\tconst alignClass: string | undefined = ALIGNMENT_CLASSES[align];\n\t\t\tif (alignClass) {\n\t\t\t\tfigure.classList.add(alignClass);\n\t\t\t}\n\n\t\t\tconst uploadState: UploadState = uploadStates.get(n.id) ?? 'idle';\n\t\t\tconst isUploading: boolean = uploadState === 'uploading';\n\t\t\toverlay.classList.toggle('notectl-image__overlay--uploading', isUploading);\n\t\t\toverlay.classList.toggle('notectl-image__overlay--error', uploadState === 'error');\n\n\t\t\tif (isUploading) {\n\t\t\t\toverlay.textContent = locale.uploading;\n\t\t\t} else if (uploadState === 'error') {\n\t\t\t\toverlay.textContent = locale.uploadFailed;\n\t\t\t} else {\n\t\t\t\toverlay.textContent = '';\n\t\t\t}\n\n\t\t\tif (isUploading) {\n\t\t\t\tfigure.setAttribute('aria-busy', 'true');\n\t\t\t} else {\n\t\t\t\tfigure.removeAttribute('aria-busy');\n\t\t\t}\n\n\t\t\tupdateAriaLabel(n);\n\t\t}\n\n\t\tapplyAttrs(node);\n\n\t\t// --- Commit natural dimensions on first load ---\n\n\t\tlet dimensionsCommitted = false;\n\n\t\timg.addEventListener('load', () => {\n\t\t\tif (dimensionsCommitted) return;\n\n\t\t\tconst state: EditorState = getState();\n\t\t\tconst block: BlockNode | undefined = state.getBlock(currentNodeId);\n\t\t\tif (!block || block.type !== 'image') return;\n\n\t\t\tconst hasWidth: boolean = block.attrs?.width !== undefined;\n\t\t\tconst hasHeight: boolean = block.attrs?.height !== undefined;\n\t\t\tif (hasWidth && hasHeight) {\n\t\t\t\tdimensionsCommitted = true;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst naturalW: number = img.naturalWidth;\n\t\t\tconst naturalH: number = img.naturalHeight;\n\t\t\tif (naturalW === 0 || naturalH === 0) return;\n\n\t\t\tconst clampedW: number = Math.min(naturalW, config.maxWidth);\n\t\t\tconst ratio: number = naturalW > 0 ? naturalH / naturalW : 1;\n\t\t\tconst clampedH: number = Math.round(clampedW * ratio);\n\n\t\t\tconst path: BlockId[] | undefined = state.getNodePath(currentNodeId);\n\t\t\tif (!path) return;\n\n\t\t\tconst merged: BlockAttrs = {\n\t\t\t\t...(block.attrs ?? {}),\n\t\t\t\twidth: clampedW,\n\t\t\t\theight: clampedH,\n\t\t\t};\n\n\t\t\tconst tr: Transaction = state.transaction('command').setNodeAttr(path, merged).build();\n\t\t\tdispatch(tr);\n\t\t\tdimensionsCommitted = true;\n\t\t});\n\n\t\t// --- Resize Logic ---\n\n\t\tfunction clampWidth(width: number): number {\n\t\t\treturn Math.max(MIN_IMAGE_WIDTH, Math.min(config.maxWidth, width));\n\t\t}\n\n\t\tfunction commitResize(nodeId: BlockId, width: number, height: number): void {\n\t\t\tconst state: EditorState = getState();\n\t\t\tconst block: BlockNode | undefined = state.getBlock(nodeId);\n\t\t\tif (!block) return;\n\n\t\t\tconst prevWidth: number | undefined = block.attrs?.width as number | undefined;\n\t\t\tconst prevHeight: number | undefined = block.attrs?.height as number | undefined;\n\t\t\tif (prevWidth === width && prevHeight === height) return;\n\n\t\t\tconst path: BlockId[] | undefined = state.getNodePath(nodeId);\n\t\t\tif (!path) return;\n\n\t\t\tconst merged: BlockAttrs = {\n\t\t\t\t...(block.attrs ?? {}),\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t};\n\n\t\t\tconst tr: Transaction = state.transaction('command').setNodeAttr(path, merged).build();\n\t\t\tdispatch(tr);\n\t\t}\n\n\t\tfunction attachHandleListeners(\n\t\t\thandle: HTMLDivElement,\n\t\t\tposition: HandlePosition,\n\t\t\tnodeId: BlockId,\n\t\t\tsizeIndicator: HTMLDivElement,\n\t\t): void {\n\t\t\tlet startX = 0;\n\t\t\tlet startWidth = 0;\n\t\t\tlet aspectRatio = 1;\n\t\t\tlet xSign: 1 | -1 = HANDLE_X_SIGN[position];\n\n\t\t\tconst onPointerMove = (e: PointerEvent): void => {\n\t\t\t\tconst deltaX: number = e.clientX - startX;\n\t\t\t\tconst newWidth: number = clampWidth(startWidth + deltaX * xSign);\n\t\t\t\tconst newHeight: number = Math.round(newWidth / aspectRatio);\n\n\t\t\t\tsetStyleProperties(img, {\n\t\t\t\t\twidth: `${newWidth}px`,\n\t\t\t\t\theight: `${newHeight}px`,\n\t\t\t\t});\n\n\t\t\t\tsizeIndicator.textContent = `${Math.round(newWidth)} \\u00D7 ${newHeight}`;\n\t\t\t};\n\n\t\t\tconst onPointerUp = (e: PointerEvent): void => {\n\t\t\t\tdocument.removeEventListener('pointermove', onPointerMove);\n\t\t\t\tdocument.removeEventListener('pointerup', onPointerUp);\n\n\t\t\t\tfigure.classList.remove('notectl-image--resizing');\n\t\t\t\tsizeIndicator.classList.remove('notectl-image__size-indicator--visible');\n\t\t\t\tclearGlobalResizeCursor();\n\n\t\t\t\tconst finalWidth: number = Math.round(img.getBoundingClientRect().width);\n\t\t\t\tconst finalHeight: number = Math.round(finalWidth / aspectRatio);\n\n\t\t\t\tcommitResize(nodeId, finalWidth, finalHeight);\n\n\t\t\t\t(e.target as HTMLElement | null)?.releasePointerCapture?.(e.pointerId);\n\t\t\t};\n\n\t\t\thandle.addEventListener('pointerdown', (e: PointerEvent) => {\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\n\t\t\t\tconst isRtl: boolean = getTextDirection(figure) === 'rtl';\n\t\t\t\txSign = getResizeXSign(position, isRtl);\n\n\t\t\t\tstartX = e.clientX;\n\t\t\t\tstartWidth = img.getBoundingClientRect().width;\n\t\t\t\tconst imgHeight: number = img.getBoundingClientRect().height;\n\t\t\t\taspectRatio = imgHeight > 0 ? startWidth / imgHeight : 1;\n\n\t\t\t\tfigure.classList.add('notectl-image--resizing');\n\t\t\t\tsizeIndicator.textContent = `${Math.round(startWidth)} \\u00D7 ${Math.round(imgHeight)}`;\n\t\t\t\tsizeIndicator.classList.add('notectl-image__size-indicator--visible');\n\t\t\t\tconst cursor: string = isRtl ? RTL_CURSOR_MAP[position] : HANDLE_CURSORS[position];\n\t\t\t\tsetGlobalResizeCursor(cursor, figure);\n\n\t\t\t\t(e.target as HTMLElement).setPointerCapture(e.pointerId);\n\t\t\t\tdocument.addEventListener('pointermove', onPointerMove);\n\t\t\t\tdocument.addEventListener('pointerup', onPointerUp);\n\t\t\t});\n\t\t}\n\n\t\tfunction createResizeOverlay(nodeId: BlockId): void {\n\t\t\tif (!config.resizable || resizeOverlay) return;\n\n\t\t\tresizeOverlay = document.createElement('div');\n\t\t\tresizeOverlay.className = 'notectl-image__resize-overlay';\n\t\t\tresizeOverlay.setAttribute('data-notectl-no-print', '');\n\n\t\t\tconst sizeIndicator: HTMLDivElement = document.createElement('div');\n\t\t\tsizeIndicator.className = 'notectl-image__size-indicator';\n\t\t\tresizeOverlay.appendChild(sizeIndicator);\n\n\t\t\tconst positions: readonly HandlePosition[] = ['nw', 'ne', 'sw', 'se'];\n\t\t\tfor (const pos of positions) {\n\t\t\t\tconst handle: HTMLDivElement = document.createElement('div');\n\t\t\t\thandle.className = `notectl-image__resize-handle notectl-image__resize-handle--${pos}`;\n\t\t\t\t// Pointer-only visual grips. Keyboard resize is provided via shortcuts\n\t\t\t\t// with live-region announcements (see registerResizeKeymaps), so these\n\t\t\t\t// decorative handles are hidden from assistive technology rather than\n\t\t\t\t// exposed with a misleading `separator` role.\n\t\t\t\thandle.setAttribute('aria-hidden', 'true');\n\t\t\t\tattachHandleListeners(handle, pos, nodeId, sizeIndicator);\n\t\t\t\tresizeOverlay.appendChild(handle);\n\t\t\t}\n\n\t\t\t// Keyboard hint (hidden from screenreaders, visual only)\n\t\t\tif (resolvedKeymap) {\n\t\t\t\tconst hintText: string = buildKeyboardHintText(resolvedKeymap, locale);\n\t\t\t\tif (hintText) {\n\t\t\t\t\tconst hint: HTMLDivElement = document.createElement('div');\n\t\t\t\t\thint.className = 'notectl-image__keyboard-hint';\n\t\t\t\t\thint.setAttribute('aria-hidden', 'true');\n\t\t\t\t\thint.textContent = hintText;\n\t\t\t\t\tresizeOverlay.appendChild(hint);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcontainer.appendChild(resizeOverlay);\n\t\t}\n\n\t\tfunction removeResizeOverlay(): void {\n\t\t\tclearGlobalResizeCursor();\n\t\t\tif (resizeOverlay) {\n\t\t\t\tresizeOverlay.remove();\n\t\t\t\tresizeOverlay = null;\n\t\t\t}\n\t\t}\n\n\t\t// --- NodeView Interface ---\n\n\t\treturn {\n\t\t\tdom: figure,\n\t\t\tcontentDOM: null,\n\n\t\t\tupdate(updatedNode: BlockNode): boolean {\n\t\t\t\tif (updatedNode.type !== 'image') return false;\n\t\t\t\tcurrentNodeId = updatedNode.id;\n\t\t\t\tfigure.setAttribute('data-block-id', updatedNode.id);\n\t\t\t\tapplyAttrs(updatedNode);\n\t\t\t\treturn true;\n\t\t\t},\n\n\t\t\tselectNode(): void {\n\t\t\t\tfigure.classList.add('notectl-image--selected');\n\t\t\t\tcreateResizeOverlay(currentNodeId);\n\t\t\t},\n\n\t\t\tdeselectNode(): void {\n\t\t\t\tfigure.classList.remove('notectl-image--selected');\n\t\t\t\tremoveResizeOverlay();\n\t\t\t},\n\n\t\t\tdestroy(): void {\n\t\t\t\tremoveResizeOverlay();\n\t\t\t\t// Do NOT revoke blob URLs here — the URL may still be referenced\n\t\t\t\t// by the clipboard (cut/paste) or undo history. Blob URLs are\n\t\t\t\t// automatically released when the document is unloaded.\n\t\t\t},\n\t\t};\n\t};\n}\n","/**\n * Renders the image insert popup with file upload and URL input,\n * following the same pattern as FontSizePopup.\n */\n\nimport type { PluginContext } from '../Plugin.js';\nimport { insertImage } from './ImageCommands.js';\nimport type { ImageLocale } from './ImageLocale.js';\n\n// --- Config ---\n\nexport interface ImagePopupConfig {\n\treadonly acceptedTypes: readonly string[];\n\treadonly locale: ImageLocale;\n\treadonly onFileInsert: (context: PluginContext, file: File) => void;\n\treadonly onClose: () => void;\n}\n\n// --- Public Entry Point ---\n\n/** Builds the image insert popup DOM inside the given container. */\nexport function renderImagePopup(\n\tcontainer: HTMLElement,\n\tcontext: PluginContext,\n\tconfig: ImagePopupConfig,\n): void {\n\tcontainer.classList.add('notectl-image-popup');\n\n\tappendFileUploadSection(container, context, config);\n\tappendSeparator(container, config.locale);\n\tappendUrlSection(container, context, config);\n}\n\n// --- File Upload Section ---\n\nfunction appendFileUploadSection(\n\tcontainer: HTMLElement,\n\tcontext: PluginContext,\n\tconfig: ImagePopupConfig,\n): void {\n\tconst fileInput: HTMLInputElement = document.createElement('input');\n\tfileInput.type = 'file';\n\tfileInput.accept = config.acceptedTypes.join(',');\n\tfileInput.className = 'notectl-image-popup__file-input';\n\n\tconst uploadBtn: HTMLButtonElement = document.createElement('button');\n\tuploadBtn.type = 'button';\n\tuploadBtn.textContent = config.locale.uploadFromComputer;\n\tuploadBtn.setAttribute('aria-label', config.locale.uploadAria);\n\tuploadBtn.className = 'notectl-image-popup__upload-btn';\n\n\tuploadBtn.addEventListener('mousedown', (e: MouseEvent) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t\tfileInput.click();\n\t});\n\n\tfileInput.addEventListener('change', () => {\n\t\tconst file: File | undefined = fileInput.files?.[0];\n\t\tif (file) {\n\t\t\tconfig.onFileInsert(context, file);\n\t\t\tconfig.onClose();\n\t\t\tcontext.getContainer().focus();\n\t\t}\n\t});\n\n\tcontainer.appendChild(fileInput);\n\tcontainer.appendChild(uploadBtn);\n}\n\n// --- Separator ---\n\nfunction appendSeparator(container: HTMLElement, locale: ImageLocale): void {\n\tconst separator: HTMLDivElement = document.createElement('div');\n\tseparator.className = 'notectl-image-popup__separator';\n\n\tconst line1: HTMLSpanElement = document.createElement('span');\n\tline1.className = 'notectl-image-popup__separator-line';\n\n\tconst orText: HTMLSpanElement = document.createElement('span');\n\torText.textContent = locale.separator;\n\torText.className = 'notectl-image-popup__separator-text';\n\n\tconst line2: HTMLSpanElement = document.createElement('span');\n\tline2.className = 'notectl-image-popup__separator-line';\n\n\tseparator.appendChild(line1);\n\tseparator.appendChild(orText);\n\tseparator.appendChild(line2);\n\tcontainer.appendChild(separator);\n}\n\n// --- URL Input Section ---\n\nfunction appendUrlSection(\n\tcontainer: HTMLElement,\n\tcontext: PluginContext,\n\tconfig: ImagePopupConfig,\n): void {\n\tconst urlInput: HTMLInputElement = document.createElement('input');\n\turlInput.type = 'url';\n\turlInput.placeholder = config.locale.urlPlaceholder;\n\turlInput.setAttribute('aria-label', config.locale.urlAria);\n\turlInput.className = 'notectl-image-popup__url-input';\n\n\tconst insertBtn: HTMLButtonElement = document.createElement('button');\n\tinsertBtn.type = 'button';\n\tinsertBtn.textContent = config.locale.insertButton;\n\tinsertBtn.setAttribute('aria-label', config.locale.insertAria);\n\tinsertBtn.className = 'notectl-image-popup__insert-btn';\n\n\tconst applyUrl = (): void => {\n\t\tconst src: string = urlInput.value.trim();\n\t\tif (src) {\n\t\t\tinsertImage(context, { src });\n\t\t\tconfig.onClose();\n\t\t\tcontext.getContainer().focus();\n\t\t}\n\t};\n\n\tinsertBtn.addEventListener('mousedown', (e: MouseEvent) => {\n\t\te.preventDefault();\n\t\te.stopPropagation();\n\t\tapplyUrl();\n\t});\n\n\turlInput.addEventListener('keydown', (e: KeyboardEvent) => {\n\t\tif (e.key === 'Enter') {\n\t\t\te.preventDefault();\n\t\t\tapplyUrl();\n\t\t}\n\t});\n\n\tcontainer.appendChild(urlInput);\n\tcontainer.appendChild(insertBtn);\n\n\trequestAnimationFrame(() => urlInput.focus());\n}\n","/** Image insert popup styles (file upload + URL input). */\nexport const IMAGE_POPUP_CSS = `\n.notectl-image-popup {\n\tpadding: 8px;\n\tmin-width: 240px;\n}\n\n.notectl-image-popup__file-input {\n\tposition: absolute;\n\twidth: 0;\n\theight: 0;\n\toverflow: hidden;\n\topacity: 0;\n}\n\n.notectl-image-popup__upload-btn {\n\tdisplay: block;\n\twidth: 100%;\n\tpadding: 8px 12px;\n\tcursor: pointer;\n\ttext-align: center;\n\tbox-sizing: border-box;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-raised);\n\tcolor: var(--notectl-fg);\n}\n\n.notectl-image-popup__separator {\n\tdisplay: flex;\n\talign-items: center;\n\tmargin: 8px 0;\n\tcolor: var(--notectl-fg-muted);\n\tfont-size: 12px;\n}\n\n.notectl-image-popup__separator-line {\n\tflex: 1;\n\theight: 1px;\n\tbackground: var(--notectl-border);\n}\n\n.notectl-image-popup__separator-text {\n\tpadding: 0 8px;\n}\n\n.notectl-image-popup__url-input {\n\twidth: 100%;\n\tpadding: 6px 8px;\n\tbox-sizing: border-box;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-overlay);\n\tcolor: var(--notectl-fg);\n}\n\n.notectl-image-popup__insert-btn {\n\twidth: 100%;\n\tpadding: 8px 12px;\n\tmargin-top: 4px;\n\tcursor: pointer;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-raised);\n\tcolor: var(--notectl-fg);\n}\n`;\n","/**\n * Image plugin types, configuration, and service key.\n */\n\nimport { ServiceKey } from '../Plugin.js';\nimport type { ImageLocale } from './ImageLocale.js';\n\n// --- Image Attributes ---\n\nexport interface ImageAttrs {\n\treadonly src: string;\n\treadonly alt: string;\n\treadonly width?: number;\n\treadonly height?: number;\n\treadonly align: 'start' | 'center' | 'end';\n}\n\n// --- Upload Types ---\n\nexport interface ImageUploadResult {\n\treadonly url: string;\n\treadonly width?: number;\n\treadonly height?: number;\n}\n\nexport interface ImageUploadService {\n\tupload(file: File): Promise<ImageUploadResult>;\n}\n\nexport const IMAGE_UPLOAD_SERVICE = new ServiceKey<ImageUploadService>('image:upload');\n\nexport type UploadState = 'idle' | 'uploading' | 'complete' | 'error';\n\n// --- Keyboard Bindings ---\n\n/**\n * Configurable keyboard bindings for image resize actions.\n * Omit a slot to use the default; set to `null` to disable the binding.\n *\n * Key descriptor format: `'Mod-Shift-ArrowRight'`, etc.\n * `Mod` resolves to Cmd on macOS, Ctrl on Windows/Linux.\n */\nexport interface ImageKeymap {\n\treadonly growWidth?: string | null;\n\treadonly shrinkWidth?: string | null;\n\treadonly growWidthLarge?: string | null;\n\treadonly shrinkWidthLarge?: string | null;\n\treadonly resetSize?: string | null;\n}\n\nexport const DEFAULT_IMAGE_KEYMAP: Readonly<Record<keyof ImageKeymap, string>> = {\n\tgrowWidth: 'Mod-Shift-ArrowRight',\n\tshrinkWidth: 'Mod-Shift-ArrowLeft',\n\tgrowWidthLarge: 'Mod-Shift-Alt-ArrowRight',\n\tshrinkWidthLarge: 'Mod-Shift-Alt-ArrowLeft',\n\tresetSize: 'Mod-Shift-0',\n};\n\n// --- Configuration ---\n\nexport interface ImagePluginConfig {\n\treadonly maxWidth: number;\n\treadonly maxFileSize: number;\n\treadonly acceptedTypes: readonly string[];\n\treadonly resizable: boolean;\n\t/** Pixels to grow/shrink per small resize step. @default 10 */\n\treadonly resizeStep?: number;\n\t/** Pixels to grow/shrink per large resize step. @default 50 */\n\treadonly resizeStepLarge?: number;\n\t/** Customize keyboard bindings for image resize actions. */\n\treadonly keymap?: ImageKeymap;\n\t/** Locale override for user-facing strings. */\n\treadonly locale?: ImageLocale;\n}\n\nexport const DEFAULT_IMAGE_CONFIG: ImagePluginConfig = {\n\tmaxWidth: 800,\n\tmaxFileSize: 10 * 1024 * 1024,\n\tacceptedTypes: ['image/png', 'image/jpeg', 'image/gif', 'image/webp', 'image/svg+xml'],\n\tresizable: true,\n\tresizeStep: 10,\n\tresizeStepLarge: 50,\n};\n","/**\n * ImagePlugin: registers an image void block type with NodeSpec,\n * NodeView, commands, file handler, toolbar button, and accessible\n * keyboard resize with screenreader announcements.\n */\n\nimport { IMAGE_CSS } from '../../editor/styles/image.js';\nimport type { BlockAttrs, BlockNode } from '../../model/Document.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport { isNodeSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Transaction } from '../../state/Transaction.js';\nimport { setStyleProperty } from '../../style/StyleRuntime.js';\nimport { createBlockElement } from '../../view/DomUtils.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport {\n\tinsertImage,\n\tregisterImageCommands,\n\tresetImageSize,\n\tresizeImageByDelta,\n} from './ImageCommands.js';\nimport { IMAGE_LOCALE_EN, type ImageLocale, loadImageLocale } from './ImageLocale.js';\nimport { createImageNodeViewFactory } from './ImageNodeView.js';\nimport { renderImagePopup } from './ImagePopup.js';\nimport { IMAGE_POPUP_CSS } from './ImagePopupStyles.js';\nimport {\n\tDEFAULT_IMAGE_CONFIG,\n\tDEFAULT_IMAGE_KEYMAP,\n\tIMAGE_UPLOAD_SERVICE,\n\ttype ImageKeymap,\n\ttype ImagePluginConfig,\n\ttype UploadState,\n} from './ImageUpload.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\timage: {\n\t\t\tsrc: string;\n\t\t\talt: string;\n\t\t\twidth?: number;\n\t\t\theight?: number;\n\t\t\talign: 'start' | 'center' | 'end';\n\t\t};\n\t}\n}\n\n// --- Plugin ---\n\nexport class ImagePlugin implements Plugin {\n\treadonly id = 'image';\n\treadonly name = 'Image';\n\treadonly priority = 45;\n\n\tprivate readonly config: ImagePluginConfig;\n\tprivate readonly resolvedKeymap: Readonly<Record<keyof ImageKeymap, string | null>>;\n\tprivate readonly uploadStates = new Map<BlockId, UploadState>();\n\tprivate readonly blobUrls = new Set<string>();\n\tprivate context: PluginContext | null = null;\n\tprivate locale!: ImageLocale;\n\n\tconstructor(config?: Partial<ImagePluginConfig>) {\n\t\tthis.config = { ...DEFAULT_IMAGE_CONFIG, ...config };\n\t\tthis.resolvedKeymap = { ...DEFAULT_IMAGE_KEYMAP, ...config?.keymap };\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\tIMAGE_LOCALE_EN,\n\t\t\tloadImageLocale,\n\t\t);\n\t\tcontext.registerStyleSheet(IMAGE_CSS);\n\t\tcontext.registerStyleSheet(IMAGE_POPUP_CSS);\n\t\tthis.context = context;\n\t\tthis.registerNodeSpec(context);\n\t\tthis.registerNodeView(context);\n\t\tregisterImageCommands(context);\n\t\tthis.registerResizeCommands(context);\n\t\tthis.registerResizeKeymaps(context);\n\t\tthis.registerFileHandler(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tdestroy(): void {\n\t\tfor (const url of this.blobUrls) {\n\t\t\tURL.revokeObjectURL(url);\n\t\t}\n\t\tthis.blobUrls.clear();\n\t\tthis.uploadStates.clear();\n\t\tthis.context = null;\n\t}\n\n\tonStateChange(oldState: EditorState, newState: EditorState, _tr: Transaction): void {\n\t\tif (!this.context) return;\n\n\t\t// Clean up upload states for removed blocks (searches full tree)\n\t\tfor (const id of this.uploadStates.keys()) {\n\t\t\tif (!newState.getBlock(id)) {\n\t\t\t\tthis.uploadStates.delete(id);\n\t\t\t}\n\t\t}\n\n\t\t// Announce image selection for screenreaders\n\t\tconst oldIsImage: boolean = this.isImageSelected(oldState);\n\t\tconst nowIsImage: boolean = this.isImageSelected(newState);\n\n\t\tif (!oldIsImage && nowIsImage) {\n\t\t\tthis.announceImageSelection(newState);\n\t\t}\n\t}\n\n\tprivate registerNodeSpec(context: PluginContext): void {\n\t\tconst locale = this.locale;\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'image',\n\t\t\tgroup: 'block',\n\t\t\tisVoid: true,\n\t\t\tselectable: true,\n\t\t\tattrs: {\n\t\t\t\tsrc: { default: '' },\n\t\t\t\talt: { default: '' },\n\t\t\t\talign: { default: 'center' },\n\t\t\t},\n\t\t\ttoDOM(node) {\n\t\t\t\tconst figure = createBlockElement('figure', node.id);\n\t\t\t\tfigure.className = 'notectl-image';\n\t\t\t\tfigure.setAttribute('data-void', 'true');\n\t\t\t\tfigure.setAttribute('data-selectable', 'true');\n\n\t\t\t\tconst imgContainer: HTMLDivElement = document.createElement('div');\n\t\t\t\timgContainer.className = 'notectl-image__container';\n\n\t\t\t\tconst alt: string = (node.attrs?.alt as string | undefined) ?? '';\n\t\t\t\tconst width: number | undefined = node.attrs?.width as number | undefined;\n\t\t\t\tconst height: number | undefined = node.attrs?.height as number | undefined;\n\n\t\t\t\tconst img: HTMLImageElement = document.createElement('img');\n\t\t\t\timg.className = 'notectl-image__img';\n\t\t\t\timg.src = (node.attrs?.src as string | undefined) ?? '';\n\t\t\t\timg.alt = alt;\n\t\t\t\timg.draggable = false;\n\n\t\t\t\tif (width !== undefined) setStyleProperty(img, 'width', `${width}px`);\n\t\t\t\tif (height !== undefined) setStyleProperty(img, 'height', `${height}px`);\n\n\t\t\t\tconst align: string = (node.attrs?.align as string | undefined) ?? 'center';\n\t\t\t\tconst alignClass: string | undefined = {\n\t\t\t\t\tstart: 'notectl-image--start',\n\t\t\t\t\tcenter: 'notectl-image--center',\n\t\t\t\t\tend: 'notectl-image--end',\n\t\t\t\t}[align];\n\t\t\t\tif (alignClass) figure.classList.add(alignClass);\n\n\t\t\t\tfigure.setAttribute('aria-label', locale.imageAria(alt, width, height));\n\n\t\t\t\timgContainer.appendChild(img);\n\t\t\t\tfigure.appendChild(imgContainer);\n\t\t\t\treturn figure;\n\t\t\t},\n\t\t\ttoHTML(node) {\n\t\t\t\tconst src: string = escapeHTML((node.attrs?.src as string | undefined) ?? '');\n\t\t\t\tconst alt: string = escapeHTML((node.attrs?.alt as string | undefined) ?? '');\n\t\t\t\tconst width: number | undefined = node.attrs?.width as number | undefined;\n\t\t\t\tconst height: number | undefined = node.attrs?.height as number | undefined;\n\n\t\t\t\tconst sizeAttrs: string =\n\t\t\t\t\t(width !== undefined ? ` width=\"${width}\"` : '') +\n\t\t\t\t\t(height !== undefined ? ` height=\"${height}\"` : '');\n\n\t\t\t\t// Alignment is handled by the serializer's alignment injection,\n\t\t\t\t// which works in both inline-style and CSS-class modes.\n\t\t\t\treturn `<figure><img src=\"${src}\" alt=\"${alt}\"${sizeAttrs}></figure>`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'figure',\n\t\t\t\t\tgetAttrs(el) {\n\t\t\t\t\t\tconst img: HTMLImageElement | null = el.querySelector('img');\n\t\t\t\t\t\tif (!img) return false;\n\t\t\t\t\t\tconst attrs: Record<string, string | number | boolean> = {\n\t\t\t\t\t\t\tsrc: img.getAttribute('src') ?? '',\n\t\t\t\t\t\t\talt: img.getAttribute('alt') ?? '',\n\t\t\t\t\t\t\talign: 'center',\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst width: string | null = img.getAttribute('width');\n\t\t\t\t\t\tconst height: string | null = img.getAttribute('height');\n\t\t\t\t\t\tif (width) attrs.width = Number.parseInt(width, 10);\n\t\t\t\t\t\tif (height) attrs.height = Number.parseInt(height, 10);\n\n\t\t\t\t\t\t// Check inline style first, then class names (new + legacy)\n\t\t\t\t\t\tconst textAlign: string = el.style?.textAlign ?? '';\n\t\t\t\t\t\tif (textAlign === 'start' || textAlign === 'end' || textAlign === 'center') {\n\t\t\t\t\t\t\tattrs.align = textAlign;\n\t\t\t\t\t\t} else if (textAlign === 'left') {\n\t\t\t\t\t\t\tattrs.align = 'start';\n\t\t\t\t\t\t} else if (textAlign === 'right') {\n\t\t\t\t\t\t\tattrs.align = 'end';\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tel.classList.contains('notectl-align-start') ||\n\t\t\t\t\t\t\tel.classList.contains('notectl-align-left') ||\n\t\t\t\t\t\t\tel.classList.contains('notectl-image--start') ||\n\t\t\t\t\t\t\tel.classList.contains('notectl-image--left')\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tattrs.align = 'start';\n\t\t\t\t\t\t} else if (\n\t\t\t\t\t\t\tel.classList.contains('notectl-align-end') ||\n\t\t\t\t\t\t\tel.classList.contains('notectl-align-right') ||\n\t\t\t\t\t\t\tel.classList.contains('notectl-image--end') ||\n\t\t\t\t\t\t\tel.classList.contains('notectl-image--right')\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tattrs.align = 'end';\n\t\t\t\t\t\t} else if (el.classList.contains('notectl-align-center')) {\n\t\t\t\t\t\t\tattrs.align = 'center';\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn attrs;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttag: 'img',\n\t\t\t\t\tgetAttrs(el) {\n\t\t\t\t\t\tconst attrs: Record<string, string | number | boolean> = {\n\t\t\t\t\t\t\tsrc: el.getAttribute('src') ?? '',\n\t\t\t\t\t\t\talt: el.getAttribute('alt') ?? '',\n\t\t\t\t\t\t\talign: 'center',\n\t\t\t\t\t\t};\n\t\t\t\t\t\tconst width: string | null = el.getAttribute('width');\n\t\t\t\t\t\tconst height: string | null = el.getAttribute('height');\n\t\t\t\t\t\tif (width) attrs.width = Number.parseInt(width, 10);\n\t\t\t\t\t\tif (height) attrs.height = Number.parseInt(height, 10);\n\t\t\t\t\t\treturn attrs;\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: {\n\t\t\t\ttags: ['figure', 'img'],\n\t\t\t\tattrs: ['src', 'alt', 'width', 'height', 'class', 'style'],\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerNodeView(context: PluginContext): void {\n\t\tcontext.registerNodeView(\n\t\t\t'image',\n\t\t\tcreateImageNodeViewFactory(this.config, this.uploadStates, this.resolvedKeymap, this.locale),\n\t\t);\n\t}\n\n\tprivate registerResizeCommands(context: PluginContext): void {\n\t\tconst step: number = this.config.resizeStep ?? 10;\n\t\tconst stepLarge: number = this.config.resizeStepLarge ?? 50;\n\t\tconst maxWidth: number = this.config.maxWidth;\n\n\t\tcontext.registerCommand('resizeImageGrow', () => {\n\t\t\tconst result: boolean = resizeImageByDelta(context, step, maxWidth);\n\t\t\tif (result) this.announceCurrentSize(context);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('resizeImageShrink', () => {\n\t\t\tconst result: boolean = resizeImageByDelta(context, -step, maxWidth);\n\t\t\tif (result) this.announceCurrentSize(context);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('resizeImageGrowLarge', () => {\n\t\t\tconst result: boolean = resizeImageByDelta(context, stepLarge, maxWidth);\n\t\t\tif (result) this.announceCurrentSize(context);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('resizeImageShrinkLarge', () => {\n\t\t\tconst result: boolean = resizeImageByDelta(context, -stepLarge, maxWidth);\n\t\t\tif (result) this.announceCurrentSize(context);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('resetImageSize', () => {\n\t\t\tconst result: boolean = resetImageSize(context);\n\t\t\tif (result) context.announce(this.locale.resetToNaturalSize);\n\t\t\treturn result;\n\t\t});\n\t}\n\n\tprivate registerResizeKeymaps(context: PluginContext): void {\n\t\tconst bindings: Record<string, () => boolean> = {};\n\t\tconst commands: Record<keyof ImageKeymap, string> = {\n\t\t\tgrowWidth: 'resizeImageGrow',\n\t\t\tshrinkWidth: 'resizeImageShrink',\n\t\t\tgrowWidthLarge: 'resizeImageGrowLarge',\n\t\t\tshrinkWidthLarge: 'resizeImageShrinkLarge',\n\t\t\tresetSize: 'resetImageSize',\n\t\t};\n\n\t\tfor (const [slot, commandName] of Object.entries(commands)) {\n\t\t\tconst binding: string | null = this.resolvedKeymap[slot as keyof ImageKeymap] ?? null;\n\t\t\tif (binding) {\n\t\t\t\tbindings[binding] = () => context.executeCommand(commandName);\n\t\t\t}\n\t\t}\n\n\t\tif (Object.keys(bindings).length > 0) {\n\t\t\tcontext.registerKeymap(bindings);\n\t\t}\n\t}\n\n\tprivate registerFileHandler(context: PluginContext): void {\n\t\tcontext.registerFileHandler('image/*', async (file, _position) => {\n\t\t\tif (!this.isAcceptedType(file.type)) return false;\n\t\t\tthis.handleFileInsert(context, file);\n\t\t\treturn true;\n\t\t});\n\t}\n\n\tprivate handleFileInsert(context: PluginContext, file: File): void {\n\t\tif (file.size > this.config.maxFileSize) return;\n\n\t\tconst blobUrl: string = URL.createObjectURL(file);\n\t\tthis.blobUrls.add(blobUrl);\n\n\t\tconst inserted: boolean = insertImage(context, { src: blobUrl });\n\t\tif (!inserted) {\n\t\t\tURL.revokeObjectURL(blobUrl);\n\t\t\tthis.blobUrls.delete(blobUrl);\n\t\t\treturn;\n\t\t}\n\n\t\t// Find the newly inserted image block\n\t\tconst state: EditorState = context.getState();\n\t\tconst sel = state.selection;\n\t\tif (!isNodeSelection(sel)) return;\n\t\tconst imageBlockId: BlockId = sel.nodeId;\n\n\t\tthis.uploadStates.set(imageBlockId, 'uploading');\n\n\t\t// Upload if service is registered\n\t\tconst uploadService = context.getService(IMAGE_UPLOAD_SERVICE);\n\t\tif (uploadService) {\n\t\t\tthis.uploadFile(context, file, imageBlockId, blobUrl);\n\t\t} else {\n\t\t\tthis.uploadStates.set(imageBlockId, 'complete');\n\t\t}\n\t}\n\n\tprivate async uploadFile(\n\t\tcontext: PluginContext,\n\t\tfile: File,\n\t\timageBlockId: BlockId,\n\t\tblobUrl: string,\n\t): Promise<void> {\n\t\tconst uploadService = context.getService(IMAGE_UPLOAD_SERVICE);\n\t\tif (!uploadService) return;\n\n\t\ttry {\n\t\t\tconst result = await uploadService.upload(file);\n\t\t\tthis.uploadStates.set(imageBlockId, 'complete');\n\n\t\t\t// Replace blob URL with uploaded URL\n\t\t\tconst state: EditorState = context.getState();\n\t\t\tconst block: BlockNode | undefined = state.getBlock(imageBlockId);\n\t\t\tif (!block) return;\n\n\t\t\tconst path: BlockId[] | undefined = state.getNodePath(imageBlockId);\n\t\t\tif (!path) return;\n\n\t\t\tconst merged: BlockAttrs = {\n\t\t\t\t...(block.attrs ?? {}),\n\t\t\t\tsrc: result.url,\n\t\t\t\t...(result.width !== undefined ? { width: result.width } : {}),\n\t\t\t\t...(result.height !== undefined ? { height: result.height } : {}),\n\t\t\t};\n\n\t\t\tconst tr: Transaction = state.transaction('command').setNodeAttr(path, merged).build();\n\t\t\tcontext.dispatch(tr);\n\n\t\t\t// Clean up blob URL\n\t\t\tURL.revokeObjectURL(blobUrl);\n\t\t\tthis.blobUrls.delete(blobUrl);\n\t\t} catch {\n\t\t\tthis.uploadStates.set(imageBlockId, 'error');\n\t\t\tcontext.announce(this.locale.uploadFailed);\n\t\t}\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon =\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z\"/></svg>';\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'image',\n\t\t\tgroup: 'insert',\n\t\t\ticon,\n\t\t\tlabel: this.locale.insertImage,\n\t\t\ttooltip: this.locale.insertImageTooltip,\n\t\t\tcommand: 'insertImage',\n\t\t\tpopupType: 'custom',\n\t\t\trenderPopup: (container, ctx, onClose) => {\n\t\t\t\trenderImagePopup(container, ctx, {\n\t\t\t\t\tacceptedTypes: this.config.acceptedTypes,\n\t\t\t\t\tlocale: this.locale,\n\t\t\t\t\tonFileInsert: (c, file) => this.handleFileInsert(c, file),\n\t\t\t\t\tonClose,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate isAcceptedType(mimeType: string): boolean {\n\t\treturn this.config.acceptedTypes.some(\n\t\t\t(accepted) =>\n\t\t\t\taccepted === mimeType ||\n\t\t\t\t(accepted.endsWith('/*') && mimeType.startsWith(accepted.slice(0, -1))),\n\t\t);\n\t}\n\n\tprivate isImageSelected(state: EditorState): boolean {\n\t\tconst sel = state.selection;\n\t\tif (!isNodeSelection(sel)) return false;\n\t\tconst block: BlockNode | undefined = state.getBlock(sel.nodeId);\n\t\treturn block?.type === 'image';\n\t}\n\n\tprivate announceImageSelection(state: EditorState): void {\n\t\tif (!this.context) return;\n\t\tconst sel = state.selection;\n\t\tif (!isNodeSelection(sel)) return;\n\n\t\tconst block: BlockNode | undefined = state.getBlock(sel.nodeId);\n\t\tif (!block || block.type !== 'image') return;\n\n\t\tconst alt: string = (block.attrs?.alt as string | undefined) ?? '';\n\t\tconst width: number | undefined = block.attrs?.width as number | undefined;\n\t\tconst height: number | undefined = block.attrs?.height as number | undefined;\n\n\t\tconst parts: string[] = [this.locale.imageSelected];\n\t\tif (alt) parts.push(`${this.locale.altTextPrefix}${alt}.`);\n\t\tif (width !== undefined && height !== undefined) {\n\t\t\tparts.push(this.locale.imageSizeAnnounce(width, height));\n\t\t}\n\n\t\tconst shrinkKey: string | null = this.resolvedKeymap.shrinkWidth ?? null;\n\t\tconst growKey: string | null = this.resolvedKeymap.growWidth ?? null;\n\t\tif (shrinkKey && growKey) {\n\t\t\tparts.push(this.locale.resizeHint(formatShortcut(shrinkKey), formatShortcut(growKey)));\n\t\t}\n\n\t\tthis.context.announce(parts.join(' '));\n\t}\n\n\tprivate announceCurrentSize(context: PluginContext): void {\n\t\tconst state = context.getState();\n\t\tconst sel = state.selection;\n\t\tif (!isNodeSelection(sel)) return;\n\n\t\tconst block: BlockNode | undefined = state.getBlock(sel.nodeId);\n\t\tif (!block || block.type !== 'image') return;\n\n\t\tconst width: number | undefined = block.attrs?.width as number | undefined;\n\t\tconst height: number | undefined = block.attrs?.height as number | undefined;\n\t\tif (width !== undefined && height !== undefined) {\n\t\t\tcontext.announce(this.locale.imageResized(width, height));\n\t\t}\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{d as t}from"./Document-znhIcvM9.mjs";import{o as e,t as o,u as r}from"./Selection-aeiSsvhe.mjs";import{i as s}from"./TypeBrands-BZDKMjR-.mjs";import{a as n,s as i}from"./PluginHelpers-C3aCCGfX.mjs";import{t as l}from"./ShortcutFormatting-DZK70CN9.mjs";import{t as a}from"./SimpleMark-CezTJnXh.mjs";var c={label:"Inline Code",tooltip:t=>`Inline Code (${t})`},d=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-DSwUyX47.mjs"),"./locales/de.ts":()=>import("./de-BGOpZ8Ls.mjs"),"./locales/es.ts":()=>import("./es-CnQUZlfY.mjs"),"./locales/fr.ts":()=>import("./fr-DXjOwGew.mjs"),"./locales/hi.ts":()=>import("./hi-BgqI_gOH.mjs"),"./locales/pt.ts":()=>import("./pt-Eml9QiUL.mjs"),"./locales/ru.ts":()=>import("./ru-BDQ62WuE.mjs"),"./locales/zh.ts":()=>import("./zh-DRKs6Q0a.mjs")});async function m(t){return i(d,t,c)}var p={toolbar:!0,keymap:"Mod-E",inputRule:!0},u=new Set(["bold","italic","underline","strikethrough","highlight","font","fontSize","superscript","subscript"]),f=class{id="inline-code";name="Inline Code";priority=22;config;locale;constructor(t){this.config={...p,...t}}async init(t){this.locale=await n(t,this.config.locale,c,m),t.registerStyleSheet("\n.notectl-content code {\n\tfont-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'Fira Code', monospace;\n\tfont-size: 0.9em;\n\tpadding: 0.15em 0.35em;\n\tborder-radius: 4px;\n\tbackground-color: var(--notectl-code-bg);\n\tcolor: var(--notectl-code-color);\n\tword-break: break-word;\n}\n@media (forced-colors: active) {\n\t.notectl-content code {\n\t\tborder: 1px solid LinkText;\n\t}\n}\n"),this.registerMark(t),!1!==this.config.inputRule&&this.registerInputRule(t),this.registerExclusivityMiddleware(t)}registerMark(t){a(t,{markSpec:{type:"code",rank:3,toDOM:()=>document.createElement("code"),toHTMLString:(t,e)=>`<code>${e}</code>`,parseHTML:[{tag:"code",getAttrs:t=>"PRE"!==t.parentElement?.tagName&&{}},{tag:"span",getAttrs:t=>{const e=t.style.fontFamily.replace(/['"]/g,"").trim();return!!/^monospace$/i.test(e)&&{}}}],sanitize:{tags:["code"]}},command:"toggleInlineCode",keyBinding:null!==this.config.keymap?this.config.keymap??"Mod-E":null,toolbar:!1!==this.config.toolbar?{id:"inline_code",group:"format",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0L19.2 12l-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/></svg>',label:this.locale.label,tooltip:this.locale.tooltip(l(this.config.keymap??"Mod-E"))}:void 0})}registerInputRule(t){t.registerInputRule({pattern:/(?:^|[^`])(`([^`]+)`)$/,handler(t,n,i,l){const a=t.selection;if(!r(a))return null;if(!e(a))return null;const c=t.getBlock(a.anchor.blockId);if(!c||"code_block"===c.type)return null;const d=n[2],m=n[1];if(!d||!m)return null;const p=l-m.length;return t.transaction("input").deleteTextAt(a.anchor.blockId,p,l).insertText(a.anchor.blockId,p,d,[{type:s("code")}]).setSelection(o(a.anchor.blockId,p+d.length)).build()}})}registerExclusivityMiddleware(e){e.registerMiddleware((e,o,r)=>{let n=!1;const i=[];for(const a of e.steps){if("addMark"!==a.type){i.push(a);continue}const e=a.mark.type;if("code"===e){const e=o.getBlock(a.blockId);if(e){const o=t(e,a.from,a.to),r=/* @__PURE__ */new Set;for(const t of o)if("text"===t.kind)for(const e of t.marks)u.has(e.type)&&r.add(e.type);for(const t of r)n=!0,i.push({type:"removeMark",blockId:a.blockId,from:a.from,to:a.to,mark:{type:s(t)},...a.path?{path:a.path}:{}})}i.push(a);continue}if(u.has(e)){const e=o.getBlock(a.blockId);if(e&&t(e,a.from,a.to).some(t=>"text"===t.kind&&t.marks.some(t=>"code"===t.type))){n=!0;continue}}i.push(a)}let l=e.storedMarksAfter;if(l){const t=l.some(t=>"code"===t.type),e=l.some(t=>u.has(t.type));t&&e&&(l=l.filter(t=>!u.has(t.type)),n=!0)}r(n?{...e,steps:i,storedMarksAfter:l}:e)},{name:"inline-code:mark-exclusivity",priority:50})}};export{c as n,m as r,f as t};
|
|
2
|
+
//# sourceMappingURL=InlineCodePlugin-Bl1jyDwk.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InlineCodePlugin-Bl1jyDwk.mjs","names":[],"sources":["../../src/plugins/inline-code/InlineCodeLocale.ts","../../src/plugins/inline-code/InlineCodePlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the InlineCodePlugin.\n */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface InlineCodeLocale {\n\treadonly label: string;\n\treadonly tooltip: (shortcut: string) => string;\n}\n\n// --- Default English Locale ---\n\nexport const INLINE_CODE_LOCALE_EN: InlineCodeLocale = {\n\tlabel: 'Inline Code',\n\ttooltip: (shortcut: string) => `Inline Code (${shortcut})`,\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<InlineCodeLocale> = import.meta.glob<{\n\tdefault: InlineCodeLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadInlineCodeLocale(lang: string): Promise<InlineCodeLocale> {\n\treturn loadLocaleModule(localeModules, lang, INLINE_CODE_LOCALE_EN);\n}\n","/**\n * InlineCodePlugin: registers an inline code mark with MarkSpec,\n * toggle command, keyboard shortcut (Mod-E), backtick InputRule,\n * toolbar button, and mark exclusivity middleware.\n */\n\nimport type { BlockNode, Mark } from '../../model/Document.js';\nimport { getBlockContentSegmentsInRange } from '../../model/Document.js';\nimport { createCollapsedSelection, isCollapsed, isTextSelection } from '../../model/Selection.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport type { Step } from '../../state/Steps.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { registerSimpleMark } from '../shared/SimpleMark.js';\nimport {\n\tINLINE_CODE_LOCALE_EN,\n\ttype InlineCodeLocale,\n\tloadInlineCodeLocale,\n} from './InlineCodeLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tcode: Record<string, never>;\n\t}\n}\n\n// --- Configuration ---\n\nexport interface InlineCodeConfig {\n\t/** Show toolbar button. Default: true */\n\treadonly toolbar?: boolean;\n\t/** Override keyboard shortcut. Set to null to disable. Default: 'Mod-E' */\n\treadonly keymap?: string | null;\n\t/** Enable backtick InputRule. Default: true */\n\treadonly inputRule?: boolean;\n\t/** Override locale strings */\n\treadonly locale?: InlineCodeLocale;\n}\n\nconst DEFAULT_CONFIG: InlineCodeConfig = {\n\ttoolbar: true,\n\tkeymap: 'Mod-E',\n\tinputRule: true,\n};\n\n// --- CSS ---\n\nconst INLINE_CODE_CSS = `\n.notectl-content code {\n\tfont-family: ui-monospace, 'SF Mono', 'Cascadia Code', 'Fira Code', monospace;\n\tfont-size: 0.9em;\n\tpadding: 0.15em 0.35em;\n\tborder-radius: 4px;\n\tbackground-color: var(--notectl-code-bg);\n\tcolor: var(--notectl-code-color);\n\tword-break: break-word;\n}\n@media (forced-colors: active) {\n\t.notectl-content code {\n\t\tborder: 1px solid LinkText;\n\t}\n}\n`;\n\n// --- Mark Exclusivity ---\n\nconst EXCLUDED_WITH_CODE: ReadonlySet<string> = new Set([\n\t'bold',\n\t'italic',\n\t'underline',\n\t'strikethrough',\n\t'highlight',\n\t'font',\n\t'fontSize',\n\t'superscript',\n\t'subscript',\n]);\n\n// --- Plugin ---\n\nexport class InlineCodePlugin implements Plugin {\n\treadonly id = 'inline-code';\n\treadonly name = 'Inline Code';\n\treadonly priority = 22;\n\n\tprivate readonly config: InlineCodeConfig;\n\tprivate locale!: InlineCodeLocale;\n\n\tconstructor(config?: Partial<InlineCodeConfig>) {\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\tINLINE_CODE_LOCALE_EN,\n\t\t\tloadInlineCodeLocale,\n\t\t);\n\t\tcontext.registerStyleSheet(INLINE_CODE_CSS);\n\t\tthis.registerMark(context);\n\n\t\tif (this.config.inputRule !== false) {\n\t\t\tthis.registerInputRule(context);\n\t\t}\n\t\tthis.registerExclusivityMiddleware(context);\n\t}\n\n\tprivate registerMark(context: PluginContext): void {\n\t\tconst icon =\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0L19.2 12l-4.6-4.6L16 6l6 6-6 6-1.4-1.4z\"/></svg>';\n\n\t\tregisterSimpleMark(context, {\n\t\t\tmarkSpec: {\n\t\t\t\ttype: 'code',\n\t\t\t\trank: 3,\n\t\t\t\ttoDOM() {\n\t\t\t\t\treturn document.createElement('code');\n\t\t\t\t},\n\t\t\t\ttoHTMLString: (_mark, content) => `<code>${content}</code>`,\n\t\t\t\tparseHTML: [\n\t\t\t\t\t{\n\t\t\t\t\t\ttag: 'code',\n\t\t\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\t\t\tif (el.parentElement?.tagName === 'PRE') return false;\n\t\t\t\t\t\t\treturn {};\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\ttag: 'span',\n\t\t\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\t\t\tconst fontFamily: string = el.style.fontFamily.replace(/['\"]/g, '').trim();\n\t\t\t\t\t\t\tif (/^monospace$/i.test(fontFamily)) return {};\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tsanitize: { tags: ['code'] },\n\t\t\t},\n\t\t\tcommand: 'toggleInlineCode',\n\t\t\tkeyBinding: this.config.keymap !== null ? (this.config.keymap ?? 'Mod-E') : null,\n\t\t\ttoolbar:\n\t\t\t\tthis.config.toolbar !== false\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tid: 'inline_code',\n\t\t\t\t\t\t\tgroup: 'format',\n\t\t\t\t\t\t\ticon,\n\t\t\t\t\t\t\tlabel: this.locale.label,\n\t\t\t\t\t\t\ttooltip: this.locale.tooltip(formatShortcut(this.config.keymap ?? 'Mod-E')),\n\t\t\t\t\t\t}\n\t\t\t\t\t: undefined,\n\t\t});\n\t}\n\n\tprivate registerInputRule(context: PluginContext): void {\n\t\tconst pattern: RegExp = /(?:^|[^`])(`([^`]+)`)$/;\n\n\t\tcontext.registerInputRule({\n\t\t\tpattern,\n\t\t\thandler(state, match, _start, end) {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\tif (!isTextSelection(sel)) return null;\n\t\t\t\tif (!isCollapsed(sel)) return null;\n\n\t\t\t\tconst block: BlockNode | undefined = state.getBlock(sel.anchor.blockId);\n\t\t\t\tif (!block || block.type === 'code_block') return null;\n\n\t\t\t\tconst innerText: string | undefined = match[2];\n\t\t\t\tconst backtickExpr: string | undefined = match[1];\n\t\t\t\tif (!innerText || !backtickExpr) return null;\n\n\t\t\t\tconst backtickExprStart: number = end - backtickExpr.length;\n\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.deleteTextAt(sel.anchor.blockId, backtickExprStart, end)\n\t\t\t\t\t.insertText(sel.anchor.blockId, backtickExprStart, innerText, [\n\t\t\t\t\t\t{ type: markType('code') },\n\t\t\t\t\t])\n\t\t\t\t\t.setSelection(\n\t\t\t\t\t\tcreateCollapsedSelection(sel.anchor.blockId, backtickExprStart + innerText.length),\n\t\t\t\t\t)\n\t\t\t\t\t.build();\n\t\t\t},\n\t\t});\n\t}\n\n\t/**\n\t * Prevents formatting marks from coexisting with the code mark.\n\t * Bold, italic, underline, etc. are stripped when code is applied,\n\t * and code is blocked on text that already has formatting marks.\n\t * The link mark is allowed to coexist.\n\t */\n\tprivate registerExclusivityMiddleware(context: PluginContext): void {\n\t\tcontext.registerMiddleware(\n\t\t\t(tr, state, next) => {\n\t\t\t\tlet patched = false;\n\t\t\t\tconst patchedSteps: Step[] = [];\n\n\t\t\t\tfor (const step of tr.steps) {\n\t\t\t\t\tif (step.type !== 'addMark') {\n\t\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst stepMarkType: string = step.mark.type;\n\n\t\t\t\t\tif (stepMarkType === 'code') {\n\t\t\t\t\t\t// Adding code mark: inject removeMark steps for excluded marks\n\t\t\t\t\t\tconst block: BlockNode | undefined = state.getBlock(step.blockId);\n\t\t\t\t\t\tif (block) {\n\t\t\t\t\t\t\tconst segments = getBlockContentSegmentsInRange(block, step.from, step.to);\n\t\t\t\t\t\t\tconst marksToRemove: Set<string> = new Set();\n\t\t\t\t\t\t\tfor (const seg of segments) {\n\t\t\t\t\t\t\t\tif (seg.kind !== 'text') continue;\n\t\t\t\t\t\t\t\tfor (const m of seg.marks) {\n\t\t\t\t\t\t\t\t\tif (EXCLUDED_WITH_CODE.has(m.type)) {\n\t\t\t\t\t\t\t\t\t\tmarksToRemove.add(m.type);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfor (const mt of marksToRemove) {\n\t\t\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t\t\t\tpatchedSteps.push({\n\t\t\t\t\t\t\t\t\ttype: 'removeMark',\n\t\t\t\t\t\t\t\t\tblockId: step.blockId,\n\t\t\t\t\t\t\t\t\tfrom: step.from,\n\t\t\t\t\t\t\t\t\tto: step.to,\n\t\t\t\t\t\t\t\t\tmark: { type: markType(mt) },\n\t\t\t\t\t\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (EXCLUDED_WITH_CODE.has(stepMarkType)) {\n\t\t\t\t\t\t// Adding a formatting mark: block if target range has code mark\n\t\t\t\t\t\tconst block: BlockNode | undefined = state.getBlock(step.blockId);\n\t\t\t\t\t\tif (block) {\n\t\t\t\t\t\t\tconst segments = getBlockContentSegmentsInRange(block, step.from, step.to);\n\t\t\t\t\t\t\tconst hasCode: boolean = segments.some(\n\t\t\t\t\t\t\t\t(seg) => seg.kind === 'text' && seg.marks.some((m) => m.type === 'code'),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (hasCode) {\n\t\t\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t\t\t\tcontinue; // skip this step\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t}\n\n\t\t\t\t// Handle stored marks\n\t\t\t\tlet storedMarksAfter: readonly Mark[] | null = tr.storedMarksAfter;\n\t\t\t\tif (storedMarksAfter) {\n\t\t\t\t\tconst hasCode: boolean = storedMarksAfter.some((m) => m.type === 'code');\n\t\t\t\t\tconst hasExcluded: boolean = storedMarksAfter.some((m) => EXCLUDED_WITH_CODE.has(m.type));\n\n\t\t\t\t\tif (hasCode && hasExcluded) {\n\t\t\t\t\t\t// Keep code, strip formatting marks\n\t\t\t\t\t\tstoredMarksAfter = storedMarksAfter.filter((m) => !EXCLUDED_WITH_CODE.has(m.type));\n\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tnext(patched ? { ...tr, steps: patchedSteps, storedMarksAfter } : tr);\n\t\t\t},\n\t\t\t{ name: 'inline-code:mark-exclusivity', priority: 50 },\n\t\t);\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as t}from"./HTMLUtils-brwcaufP.mjs";import{s as r}from"./StyleRuntime-Bwde5icB.mjs";function e(e){const{type:n,rank:s,valueAttr:a,domStyleProperty:o,cssProperty:i,validate:l,validateOnParse:u,transformParsed:p}=e,m=t=>String(t.attrs?.[a]??"");return{type:n,rank:s,attrs:{[a]:{default:""}},toDOM(t){const e=document.createElement("span"),n=m(t);return n&&r(e,o,n),e},toHTMLString:(r,e,n)=>{const s=m(r);if(!s||!l(s))return e;const a=`${i}: ${t(s)}`;return`<span${n?.styleAttr(a)??` style="${a}"`}>${e}</span>`},toHTMLStyle:r=>{const e=m(r);return e&&l(e)?`${i}: ${t(e)}`:null},parseHTML:[{tag:"span",getAttrs:t=>{const r=t.style[o]??"";if(!r)return!1;if(u&&!l(r))return!1;const e=p?p(r):r;return{[a]:e}}}],sanitize:{tags:["span"]}}}export{e as t};
|
|
2
|
+
//# sourceMappingURL=InlineStyleMarkSpec-Cc-b1tlm.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InlineStyleMarkSpec-Cc-b1tlm.mjs","names":[],"sources":["../../src/plugins/shared/InlineStyleMarkSpec.ts"],"sourcesContent":["/**\n * Factory for inline marks that carry a single CSS style declaration (text\n * color, highlight, font family, font size). These marks share the same DOM\n * rendering, HTML import/export, and `<span>`-based parse shape and differ only\n * in the attribute name, CSS property, and validation.\n */\n\nimport type { Mark } from '../../model/Document.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport type { MarkSpec } from '../../model/MarkSpec.js';\nimport type { HTMLExportContext } from '../../model/NodeSpec.js';\nimport { setStyleProperty } from '../../style/StyleRuntime.js';\n\nexport interface InlineStyleMarkConfig {\n\t/** Mark type name, e.g. `'textColor'`. */\n\treadonly type: string;\n\t/** Nesting rank (lower renders closer to the text). */\n\treadonly rank: number;\n\t/** Attribute key holding the value, e.g. `'color'` / `'family'` / `'size'`. */\n\treadonly valueAttr: string;\n\t/** camelCase DOM style property, e.g. `'backgroundColor'`. */\n\treadonly domStyleProperty: string;\n\t/** kebab-case CSS property for HTML export, e.g. `'background-color'`. */\n\treadonly cssProperty: string;\n\t/** Validates a value for HTML export (and optionally on parse). */\n\treadonly validate: (value: string) => boolean;\n\t/** When true, `validate` is also enforced while parsing HTML. */\n\treadonly validateOnParse?: boolean;\n\t/** Optional transform applied to a parsed value (e.g. CSS quote normalization). */\n\treadonly transformParsed?: (value: string) => string;\n}\n\n/** Builds a MarkSpec for a single-CSS-property inline mark. */\nexport function createInlineStyleMarkSpec(config: InlineStyleMarkConfig): MarkSpec {\n\tconst {\n\t\ttype,\n\t\trank,\n\t\tvalueAttr,\n\t\tdomStyleProperty,\n\t\tcssProperty,\n\t\tvalidate,\n\t\tvalidateOnParse,\n\t\ttransformParsed,\n\t} = config;\n\n\tconst readValue = (mark: Mark): string => String(mark.attrs?.[valueAttr] ?? '');\n\n\treturn {\n\t\ttype,\n\t\trank,\n\t\tattrs: { [valueAttr]: { default: '' } },\n\t\ttoDOM(mark) {\n\t\t\tconst span: HTMLElement = document.createElement('span');\n\t\t\tconst value: string = readValue(mark);\n\t\t\tif (value) {\n\t\t\t\tsetStyleProperty(span, domStyleProperty, value);\n\t\t\t}\n\t\t\treturn span;\n\t\t},\n\t\ttoHTMLString: (mark: Mark, content: string, ctx?: HTMLExportContext) => {\n\t\t\tconst value: string = readValue(mark);\n\t\t\tif (!value || !validate(value)) return content;\n\t\t\tconst decl: string = `${cssProperty}: ${escapeHTML(value)}`;\n\t\t\tconst attr: string = ctx?.styleAttr(decl) ?? ` style=\"${decl}\"`;\n\t\t\treturn `<span${attr}>${content}</span>`;\n\t\t},\n\t\ttoHTMLStyle: (mark: Mark) => {\n\t\t\tconst value: string = readValue(mark);\n\t\t\tif (!value || !validate(value)) return null;\n\t\t\treturn `${cssProperty}: ${escapeHTML(value)}`;\n\t\t},\n\t\tparseHTML: [\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst raw: string =\n\t\t\t\t\t\t(el.style as unknown as Record<string, string>)[domStyleProperty] ?? '';\n\t\t\t\t\tif (!raw) return false;\n\t\t\t\t\tif (validateOnParse && !validate(raw)) return false;\n\t\t\t\t\tconst value: string = transformParsed ? transformParsed(raw) : raw;\n\t\t\t\t\treturn { [valueAttr]: value };\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['span'] },\n\t};\n}\n"],"mappings":"6FAiCA,SAAgB,EAA0B,GACzC,MAAM,KACL,EAAA,KACA,EAAA,UACA,EAAA,iBACA,EAAA,YACA,EAAA,SACA,EAAA,gBACA,EAAA,gBACA,GACG,EAEE,EAAa,GAAuB,OAAO,EAAK,QAAQ,IAAc,IAE5E,MAAO,CACN,OACA,OACA,MAAO,CAAA,CAAG,GAAY,CAAE,QAAS,KACjC,KAAA,CAAM,GACL,MAAM,EAAoB,SAAS,cAAc,QAC3C,EAAgB,EAAU,GAIhC,OAHI,GACH,EAAiB,EAAM,EAAkB,GAEnC,GAER,aAAA,CAAe,EAAY,EAAiB,KAC3C,MAAM,EAAgB,EAAU,GAChC,IAAK,IAAU,EAAS,GAAQ,OAAO,EACvC,MAAM,EAAe,GAAG,MAAgB,EAAW,KAEnD,MAAO,QADc,GAAK,UAAU,IAAS,WAAW,QACjC,YAExB,YAAc,IACb,MAAM,EAAgB,EAAU,GAChC,OAAK,GAAU,EAAS,GACjB,GAAG,MAAgB,EAAW,KADE,MAGxC,UAAW,CACV,CACC,IAAK,OACL,SAAW,IACV,MAAM,EACJ,EAAG,MAA4C,IAAqB,GACtE,IAAK,EAAK,OAAO,EACjB,GAAI,IAAoB,EAAS,GAAM,OAAO,EAC9C,MAAM,EAAgB,EAAkB,EAAgB,GAAO,EAC/D,MAAO,CAAA,CAAG,GAAY,MAIzB,SAAU,CAAE,KAAM,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function r(r,t){for(let n=0;n<r.length;n++){const e=r[n];e&&e.setAttribute("tabindex",n===t?"0":"-1")}}function t(r,t,n){const e=r.length;return 0===e?-1:(t+n+e)%e}function n(r,t,n,e,o,c=!1){switch(c?function(r){return"ArrowLeft"===r?"ArrowRight":"ArrowRight"===r?"ArrowLeft":r}(o):o){case"ArrowUp":return[r>1?r-1:n,t];case"ArrowDown":return[r<n?r+1:1,t];case"ArrowLeft":return[r,t>1?t-1:e];case"ArrowRight":return[r,t<e?t+1:1]}}export{t as n,n as r,r as t};
|
|
2
|
+
//# sourceMappingURL=KeyboardNav-DZXdTg-_.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KeyboardNav-DZXdTg-_.mjs","names":[],"sources":["../../src/plugins/shared/KeyboardNav.ts"],"sourcesContent":["/**\n * Generic keyboard navigation helpers reused by toolbar and popup UIs.\n */\n\n/**\n * Applies roving tabindex: sets tabindex=\"0\" on the focused item,\n * tabindex=\"-1\" on all others.\n */\nexport function applyRovingTabindex(items: readonly HTMLElement[], focusedIndex: number): void {\n\tfor (let i = 0; i < items.length; i++) {\n\t\tconst item: HTMLElement | undefined = items[i];\n\t\tif (item) {\n\t\t\titem.setAttribute('tabindex', i === focusedIndex ? '0' : '-1');\n\t\t}\n\t}\n}\n\n/** Navigates dropdown items with arrow keys (wraps around). */\nexport function findNextDropdownItem(\n\titems: readonly HTMLElement[],\n\tcurrent: number,\n\tdirection: 1 | -1,\n): number {\n\tconst len = items.length;\n\tif (len === 0) return -1;\n\treturn (current + direction + len) % len;\n}\n\n/** Flips horizontal arrow keys for RTL contexts. */\nfunction flipHorizontalKey(\n\tkey: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight',\n): 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' {\n\tif (key === 'ArrowLeft') return 'ArrowRight';\n\tif (key === 'ArrowRight') return 'ArrowLeft';\n\treturn key;\n}\n\n/**\n * Navigates a grid of cells with arrow keys.\n * Returns the new [row, col] position.\n * When `isRtl` is true, horizontal arrows are flipped to match visual direction.\n */\nexport function navigateGrid(\n\trow: number,\n\tcol: number,\n\tmaxRows: number,\n\tmaxCols: number,\n\tkey: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight',\n\tisRtl = false,\n): [number, number] {\n\tconst resolved: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight' = isRtl\n\t\t? flipHorizontalKey(key)\n\t\t: key;\n\n\tswitch (resolved) {\n\t\tcase 'ArrowUp':\n\t\t\treturn [row > 1 ? row - 1 : maxRows, col];\n\t\tcase 'ArrowDown':\n\t\t\treturn [row < maxRows ? row + 1 : 1, col];\n\t\tcase 'ArrowLeft':\n\t\t\treturn [row, col > 1 ? col - 1 : maxCols];\n\t\tcase 'ArrowRight':\n\t\t\treturn [row, col < maxCols ? col + 1 : 1];\n\t}\n}\n"],"mappings":"AAQA,SAAgB,EAAoB,EAA+B,GAClE,IAAK,IAAI,EAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,CACtC,MAAM,EAAgC,EAAM,GACxC,GACH,EAAK,aAAa,WAAY,IAAM,EAAe,IAAM,OAM5D,SAAgB,EACf,EACA,EACA,GAEA,MAAM,EAAM,EAAM,OAClB,OAAY,IAAR,GAAkB,GACd,EAAU,EAAY,GAAO,EAiBtC,SAAgB,EACf,EACA,EACA,EACA,EACA,EACA,GAAQ,GAMR,OAJuE,EArBxE,SACC,GAEA,MAAY,cAAR,EAA4B,aACpB,eAAR,EAA6B,YAC1B,EAiBJ,CAAkB,GAClB,GAGF,IAAK,UACJ,MAAO,CAAC,EAAM,EAAI,EAAM,EAAI,EAAS,GACtC,IAAK,YACJ,MAAO,CAAC,EAAM,EAAU,EAAM,EAAI,EAAG,GACtC,IAAK,YACJ,MAAO,CAAC,EAAK,EAAM,EAAI,EAAM,EAAI,GAClC,IAAK,aACJ,MAAO,CAAC,EAAK,EAAM,EAAU,EAAM,EAAI"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{b as t}from"./Document-znhIcvM9.mjs";import{o as e,u as r}from"./Selection-aeiSsvhe.mjs";import{i as n}from"./TypeBrands-BZDKMjR-.mjs";import{a as i,r as o}from"./HTMLUtils-brwcaufP.mjs";import{i as s,r as a,t as l}from"./AttributedMarkCommands-CxhdUsuE.mjs";import{a as c,n as p,s as m}from"./PluginHelpers-C3aCCGfX.mjs";import{t as u}from"./ShortcutFormatting-DZK70CN9.mjs";var d={label:"Link",tooltip:t=>`Insert Link (${t})`,removeLink:"Remove Link",removeLinkAria:"Remove link",urlPlaceholder:"https://...",urlAria:"Link URL",apply:"Apply",applyAria:"Apply link",invalidUrl:"Only http(s), mailto, tel, fragments, and relative paths are allowed."},h=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-CseGhQtS.mjs"),"./locales/de.ts":()=>import("./de-C4gnHDmk.mjs"),"./locales/es.ts":()=>import("./es-DwKejbO9.mjs"),"./locales/fr.ts":()=>import("./fr-CbsiyDEa.mjs"),"./locales/hi.ts":()=>import("./hi-Bg4-z2Os.mjs"),"./locales/pt.ts":()=>import("./pt-D6zY7l2E.mjs"),"./locales/ru.ts":()=>import("./ru-DyWzWBjV.mjs"),"./locales/zh.ts":()=>import("./zh-Cynz1sBa.mjs")});async function k(t){return m(h,t,d)}var g={openInNewTab:!0},f=class{id="link";name="Link";priority=25;config;locale;constructor(t){this.config={...g,...t}}async init(t){this.locale=await c(t,this.config.locale,d,k),this.registerMarkSpec(t),this.registerCommands(t),this.registerKeymap(t),this.registerToolbarItem(t)}registerMarkSpec(t){const e=this.config.openInNewTab;t.registerMarkSpec({type:"link",rank:10,inclusive:!1,attrs:{href:{default:""}},toDOM(t){const r=document.createElement("a"),n=i(String(t.attrs?.href??""));return r.setAttribute("href",n),e&&(r.setAttribute("target","_blank"),r.setAttribute("rel","noopener noreferrer")),r},toHTMLString:(t,r)=>{const n=o(i(String(t.attrs?.href??"")));return e?`<a href="${n}" target="_blank" rel="noopener noreferrer">${r}</a>`:`<a href="${n}">${r}</a>`},parseHTML:[{tag:"a",getAttrs:t=>({href:i(t.getAttribute("href")??"")})}],sanitize:{tags:["a"],attrs:["href","target","rel"]}})}registerCommands(t){t.registerCommand("toggleLink",()=>{const e=t.getState();return this.toggleLink(t,e)}),t.registerCommand("setLink",()=>!1),t.registerCommand("removeLink",()=>{const e=t.getState();return this.removeLink(t,e)})}registerKeymap(t){t.registerKeymap({"Mod-K":()=>t.executeCommand("toggleLink")})}registerToolbarItem(t){t.registerToolbarItem({id:"link",group:"insert",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>',label:this.locale.label,tooltip:this.locale.tooltip(u("Mod-K")),command:"toggleLink",popupType:"custom",renderPopup:(t,e,r)=>{this.renderLinkPopup(t,e,r)},isActive:t=>this.isLinkActive(t),isEnabled:t=>!e(t.selection)})}isLinkActive(t){return a(t,"link")}toggleLink(t,e){return!!this.isLinkActive(e)&&this.removeLink(t,e)}addLink(t,i,o){const s=i.selection;return!!r(s)&&!e(s)&&p(t,l(i,{type:n("link"),attrs:{href:o}}))}removeLink(i,o){const a=o.selection;if(!r(a))return!1;if(e(a)){const e=o.getBlock(a.anchor.blockId);if(!e)return!1;const r=[];let s=0;for(const i of e.children){if(!("text"in i))continue;const e=s+i.text.length;r.push({pos:s,end:e,hasLink:t(i.marks,n("link"))}),s=e}const l=r.findIndex(t=>a.anchor.offset>=t.pos&&a.anchor.offset<=t.end),c=l>=0?r[l]:void 0;if(-1===l||!c?.hasLink)return!1;let p=l;for(;p>0&&r[p-1]?.hasLink;)p--;let m=l;for(;m<r.length-1&&r[m+1]?.hasLink;)m++;const u=r[p],d=r[m];if(!u||!d)return!1;const h=u.pos,k=d.end,g=o.transaction("command");return g.removeMark(a.anchor.blockId,h,k,{type:n("link")}),g.setSelection(a),i.dispatch(g.build()),!0}return p(i,s(o,n("link")))}renderLinkPopup(t,e,r){t.classList.add("notectl-link-popup");const n=e.getState();if(this.isLinkActive(n)){const n=document.createElement("button");n.type="button",n.className="notectl-link-popup__button",n.textContent=this.locale.removeLink,n.setAttribute("aria-label",this.locale.removeLinkAria),n.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),e.executeCommand("removeLink"),r(),e.getContainer().focus()}),t.appendChild(n)}else{const n=document.createElement("input");n.type="url",n.className="notectl-link-popup__input",n.placeholder=this.locale.urlPlaceholder,n.setAttribute("aria-label",this.locale.urlAria);const o=document.createElement("button");o.type="button",o.className="notectl-link-popup__button notectl-link-popup__button--apply",o.textContent=this.locale.apply,o.setAttribute("aria-label",this.locale.applyAria);const s=document.createElement("div");s.className="notectl-link-popup__error",s.setAttribute("role","alert"),s.hidden=!0;const a=()=>{const t=n.value.trim();if(""===t)return;const o=i(t);if(""===o)return s.textContent=this.locale.invalidUrl,s.hidden=!1,n.setAttribute("aria-invalid","true"),void n.focus();s.hidden=!0,n.removeAttribute("aria-invalid"),this.addLink(e,e.getState(),o),r(),e.getContainer().focus()};o.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),a()}),n.addEventListener("keydown",t=>{"Enter"===t.key&&(t.preventDefault(),a())}),n.addEventListener("input",()=>{s.hidden||(s.hidden=!0,n.removeAttribute("aria-invalid"))}),t.appendChild(n),t.appendChild(o),t.appendChild(s),requestAnimationFrame(()=>n.focus())}}};export{d as n,k as r,f as t};
|
|
2
|
+
//# sourceMappingURL=LinkPlugin-Dmcfo3On.mjs.map
|