@notectl/core 2.2.6 → 2.3.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.
Files changed (502) hide show
  1. package/dist/chunks/{AlignmentPlugin-DeD4C4EP.mjs → AlignmentPlugin--xAFlRqE.mjs} +2 -2
  2. package/dist/chunks/{AlignmentPlugin-DeD4C4EP.mjs.map → AlignmentPlugin--xAFlRqE.mjs.map} +1 -1
  3. package/dist/chunks/{AttrRegistry-DcDVyzLm.mjs → AttrRegistry-B3zB02z9.mjs} +2 -2
  4. package/dist/chunks/AttrRegistry-B3zB02z9.mjs.map +1 -0
  5. package/dist/chunks/{AttributedMarkCommands-D4W2Jgpj.mjs → AttributedMarkCommands-bagbH8Qt.mjs} +2 -2
  6. package/dist/chunks/{AttributedMarkCommands-D4W2Jgpj.mjs.map → AttributedMarkCommands-bagbH8Qt.mjs.map} +1 -1
  7. package/dist/chunks/{BidiIsolationPlugin-BddRbDCN.mjs → BidiIsolationPlugin-DBXyXpgm.mjs} +2 -2
  8. package/dist/chunks/{BidiIsolationPlugin-BddRbDCN.mjs.map → BidiIsolationPlugin-DBXyXpgm.mjs.map} +1 -1
  9. package/dist/chunks/BlockInsertion-CJusvrDL.mjs +2 -0
  10. package/dist/chunks/BlockInsertion-CJusvrDL.mjs.map +1 -0
  11. package/dist/chunks/BlockquotePlugin-Bz2glHwX.mjs +2 -0
  12. package/dist/chunks/{BlockquotePlugin-4V7KV_Sb.mjs.map → BlockquotePlugin-Bz2glHwX.mjs.map} +1 -1
  13. package/dist/chunks/{CaretNavigationPlugin-C6XBwp0N.mjs → CaretNavigationPlugin-CNsT0eb4.mjs} +2 -2
  14. package/dist/chunks/{CaretNavigationPlugin-C6XBwp0N.mjs.map → CaretNavigationPlugin-CNsT0eb4.mjs.map} +1 -1
  15. package/dist/chunks/CodeBlockPlugin-C1hrdbSZ.mjs +2 -0
  16. package/dist/chunks/CodeBlockPlugin-C1hrdbSZ.mjs.map +1 -0
  17. package/dist/chunks/{ColorGrid-DPNiXxpD.mjs → ColorGrid-C9RQoEWF.mjs} +2 -2
  18. package/dist/chunks/{ColorGrid-DPNiXxpD.mjs.map → ColorGrid-C9RQoEWF.mjs.map} +1 -1
  19. package/dist/chunks/ColorPickerPopup-DiA68Pzz.mjs +2 -0
  20. package/dist/chunks/{ColorPickerPopup-lcf3jS6G.mjs.map → ColorPickerPopup-DiA68Pzz.mjs.map} +1 -1
  21. package/dist/chunks/Commands-1dFFldi7.mjs +2 -0
  22. package/dist/chunks/Commands-1dFFldi7.mjs.map +1 -0
  23. package/dist/chunks/ContentModel-NpAj7vGW.mjs +2 -0
  24. package/dist/chunks/ContentModel-NpAj7vGW.mjs.map +1 -0
  25. package/dist/chunks/Decoration-BpoEOANl.mjs +2 -0
  26. package/dist/chunks/Decoration-BpoEOANl.mjs.map +1 -0
  27. package/dist/chunks/{DirectionDetection-C7XE0nxW.mjs → DirectionDetection-CDVSEWQ6.mjs} +2 -2
  28. package/dist/chunks/{DirectionDetection-C7XE0nxW.mjs.map → DirectionDetection-CDVSEWQ6.mjs.map} +1 -1
  29. package/dist/chunks/Document-827l3P80.mjs +2 -0
  30. package/dist/chunks/Document-827l3P80.mjs.map +1 -0
  31. package/dist/chunks/DocumentParser-D2tr3ZKn.mjs +2 -0
  32. package/dist/chunks/DocumentParser-D2tr3ZKn.mjs.map +1 -0
  33. package/dist/chunks/EditorEventBoundary-zpYRxryo.mjs +2 -0
  34. package/dist/chunks/EditorEventBoundary-zpYRxryo.mjs.map +1 -0
  35. package/dist/chunks/{FontPlugin-DQMj65Bc.mjs → FontPlugin-By-TGrQo.mjs} +2 -2
  36. package/dist/chunks/{FontPlugin-DQMj65Bc.mjs.map → FontPlugin-By-TGrQo.mjs.map} +1 -1
  37. package/dist/chunks/{FontSizePlugin-9StCjEfN.mjs → FontSizePlugin-Dln-tYXV.mjs} +2 -2
  38. package/dist/chunks/FontSizePlugin-Dln-tYXV.mjs.map +1 -0
  39. package/dist/chunks/FormulaPlugin-By1befrR.mjs +2 -0
  40. package/dist/chunks/FormulaPlugin-By1befrR.mjs.map +1 -0
  41. package/dist/chunks/GapCursorNavigation-BuXngVu-.mjs +2 -0
  42. package/dist/chunks/{GapCursorNavigation-ycNzuQVH.mjs.map → GapCursorNavigation-BuXngVu-.mjs.map} +1 -1
  43. package/dist/chunks/{GapCursorPlugin-Zvxjnr82.mjs → GapCursorPlugin-DAxVzXRs.mjs} +2 -2
  44. package/dist/chunks/{GapCursorPlugin-Zvxjnr82.mjs.map → GapCursorPlugin-DAxVzXRs.mjs.map} +1 -1
  45. package/dist/chunks/HTMLUtils-Bhg3_P8B.mjs +2 -0
  46. package/dist/chunks/HTMLUtils-Bhg3_P8B.mjs.map +1 -0
  47. package/dist/chunks/{HardBreakPlugin-9DOyCyyM.mjs → HardBreakPlugin-DlbSlrdq.mjs} +2 -2
  48. package/dist/chunks/{HardBreakPlugin-9DOyCyyM.mjs.map → HardBreakPlugin-DlbSlrdq.mjs.map} +1 -1
  49. package/dist/chunks/HeadingPlugin-uMAjPOk5.mjs +2 -0
  50. package/dist/chunks/{HeadingPlugin-BuGoM9Rz.mjs.map → HeadingPlugin-uMAjPOk5.mjs.map} +1 -1
  51. package/dist/chunks/{HighlightPlugin-C6pHifVz.mjs → HighlightPlugin-Bj7FPkIQ.mjs} +2 -2
  52. package/dist/chunks/{HighlightPlugin-C6pHifVz.mjs.map → HighlightPlugin-Bj7FPkIQ.mjs.map} +1 -1
  53. package/dist/chunks/HorizontalRulePlugin-DUVmTQpX.mjs +2 -0
  54. package/dist/chunks/HorizontalRulePlugin-DUVmTQpX.mjs.map +1 -0
  55. package/dist/chunks/ImagePlugin-FToCOjd5.mjs +2 -0
  56. package/dist/chunks/{ImagePlugin-KpkuE2LH.mjs.map → ImagePlugin-FToCOjd5.mjs.map} +1 -1
  57. package/dist/chunks/{InlineCodePlugin-DMr4O7c7.mjs → InlineCodePlugin-pISIoGQE.mjs} +2 -2
  58. package/dist/chunks/InlineCodePlugin-pISIoGQE.mjs.map +1 -0
  59. package/dist/chunks/InlineStyleMarkSpec-CjSRj4f_.mjs +2 -0
  60. package/dist/chunks/{InlineStyleMarkSpec-C6LJT7kp.mjs.map → InlineStyleMarkSpec-CjSRj4f_.mjs.map} +1 -1
  61. package/dist/chunks/LinkPlugin-Ct5Z180S.mjs +2 -0
  62. package/dist/chunks/LinkPlugin-Ct5Z180S.mjs.map +1 -0
  63. package/dist/chunks/ListPlugin-DAY5ezNs.mjs +2 -0
  64. package/dist/chunks/ListPlugin-DAY5ezNs.mjs.map +1 -0
  65. package/dist/chunks/MarkInputRule-Bdi8KPus.mjs +2 -0
  66. package/dist/chunks/MarkInputRule-Bdi8KPus.mjs.map +1 -0
  67. package/dist/chunks/MarkdownHTMLRegistry-CKEx7LkR.mjs +2 -0
  68. package/dist/chunks/MarkdownHTMLRegistry-CKEx7LkR.mjs.map +1 -0
  69. package/dist/chunks/MarkdownParser-CWt3M6jR.mjs +2 -0
  70. package/dist/chunks/MarkdownParser-CWt3M6jR.mjs.map +1 -0
  71. package/dist/chunks/MarkdownSerializer-J-i28out.mjs +2 -0
  72. package/dist/chunks/MarkdownSerializer-J-i28out.mjs.map +1 -0
  73. package/dist/chunks/{NodeResolver-ChgLF_IP.mjs → NodeResolver-Dleih-8R.mjs} +2 -2
  74. package/dist/chunks/{NodeResolver-ChgLF_IP.mjs.map → NodeResolver-Dleih-8R.mjs.map} +1 -1
  75. package/dist/chunks/NodeSelectionCommands-1PjwUDTJ.mjs +2 -0
  76. package/dist/chunks/{NodeSelectionCommands-Dj4VxLdD.mjs.map → NodeSelectionCommands-1PjwUDTJ.mjs.map} +1 -1
  77. package/dist/chunks/PluginHelpers-Dx_0hfDe.mjs +2 -0
  78. package/dist/chunks/{PluginHelpers-KDuTlmXm.mjs.map → PluginHelpers-Dx_0hfDe.mjs.map} +1 -1
  79. package/dist/chunks/{PopupManager-DUtaK3WX.mjs → PopupManager-CT-fMZJn.mjs} +2 -2
  80. package/dist/chunks/{PopupManager-DUtaK3WX.mjs.map → PopupManager-CT-fMZJn.mjs.map} +1 -1
  81. package/dist/chunks/PopupPositioning-BFh6Ed1D.mjs +2 -0
  82. package/dist/chunks/{PopupPositioning-BB97-__N.mjs.map → PopupPositioning-BFh6Ed1D.mjs.map} +1 -1
  83. package/dist/chunks/PrintPlugin-7zz9mhhU.mjs +2 -0
  84. package/dist/chunks/PrintPlugin-7zz9mhhU.mjs.map +1 -0
  85. package/dist/chunks/{RangeIterator-o8v3msQe.mjs → RangeIterator-DP7Ud3Gp.mjs} +2 -2
  86. package/dist/chunks/{RangeIterator-o8v3msQe.mjs.map → RangeIterator-DP7Ud3Gp.mjs.map} +1 -1
  87. package/dist/chunks/SchemaRegistry-CkBN-1yW.mjs +2 -0
  88. package/dist/chunks/SchemaRegistry-CkBN-1yW.mjs.map +1 -0
  89. package/dist/chunks/{SimpleMark-CaQtFAau.mjs → SimpleMark-7CQcA4RK.mjs} +2 -2
  90. package/dist/chunks/{SimpleMark-CaQtFAau.mjs.map → SimpleMark-7CQcA4RK.mjs.map} +1 -1
  91. package/dist/chunks/{SmartPastePlugin-Bi_wpTCV.mjs → SmartPastePlugin-CYa_nD9v.mjs} +2 -2
  92. package/dist/chunks/{SmartPastePlugin-Bi_wpTCV.mjs.map → SmartPastePlugin-CYa_nD9v.mjs.map} +1 -1
  93. package/dist/chunks/StrikethroughPlugin-C2oWvGc3.mjs +2 -0
  94. package/dist/chunks/StrikethroughPlugin-C2oWvGc3.mjs.map +1 -0
  95. package/dist/chunks/StyleRuntime-DW6omotc.mjs +2 -0
  96. package/dist/chunks/StyleRuntime-DW6omotc.mjs.map +1 -0
  97. package/dist/chunks/{SuperSubPlugin-DVP7VnIz.mjs → SuperSubPlugin-D1xaKrSu.mjs} +2 -2
  98. package/dist/chunks/{SuperSubPlugin-DVP7VnIz.mjs.map → SuperSubPlugin-D1xaKrSu.mjs.map} +1 -1
  99. package/dist/chunks/TableDimensions-BBhjHNjQ.mjs +2 -0
  100. package/dist/chunks/TableDimensions-BBhjHNjQ.mjs.map +1 -0
  101. package/dist/chunks/TablePlugin-PJe3zwr-.mjs +2 -0
  102. package/dist/chunks/TablePlugin-PJe3zwr-.mjs.map +1 -0
  103. package/dist/chunks/TextColorPlugin-CTd9tfeG.mjs +2 -0
  104. package/dist/chunks/{TextColorPlugin-CEfZQ6Md.mjs.map → TextColorPlugin-CTd9tfeG.mjs.map} +1 -1
  105. package/dist/chunks/TextDirectionAutoPlugin-CPnKVVuI.mjs +2 -0
  106. package/dist/chunks/{TextDirectionAutoPlugin-CzWJjrvG.mjs.map → TextDirectionAutoPlugin-CPnKVVuI.mjs.map} +1 -1
  107. package/dist/chunks/{TextDirectionPlugin-DHB88HKf.mjs → TextDirectionPlugin-Bns_03vL.mjs} +2 -2
  108. package/dist/chunks/{TextDirectionPlugin-DHB88HKf.mjs.map → TextDirectionPlugin-Bns_03vL.mjs.map} +1 -1
  109. package/dist/chunks/TextDirectionService-BcX07mw2.mjs +2 -0
  110. package/dist/chunks/{TextDirectionService-OFOU6r_s.mjs.map → TextDirectionService-BcX07mw2.mjs.map} +1 -1
  111. package/dist/chunks/TextFormattingPlugin-DBVlePqj.mjs +2 -0
  112. package/dist/chunks/TextFormattingPlugin-DBVlePqj.mjs.map +1 -0
  113. package/dist/chunks/{ToolbarPlugin-DVGrFf8v.mjs → ToolbarPlugin-DtfGTO_V.mjs} +2 -2
  114. package/dist/chunks/{ToolbarPlugin-DVGrFf8v.mjs.map → ToolbarPlugin-DtfGTO_V.mjs.map} +1 -1
  115. package/dist/chunks/VideoPlugin-BrR8g6Rz.mjs +2 -0
  116. package/dist/chunks/VideoPlugin-BrR8g6Rz.mjs.map +1 -0
  117. package/dist/chunks/WordBoundary-CFpIJDNP.mjs +2 -0
  118. package/dist/chunks/{WordBoundary-DxeMBRyP.mjs.map → WordBoundary-CFpIJDNP.mjs.map} +1 -1
  119. package/dist/chunks/ar-Dg9PdDet.mjs +2 -0
  120. package/dist/chunks/ar-Dg9PdDet.mjs.map +1 -0
  121. package/dist/chunks/ar-eOA3UmiE.mjs +2 -0
  122. package/dist/chunks/{ar-BTShmP2E.mjs.map → ar-eOA3UmiE.mjs.map} +1 -1
  123. package/dist/chunks/de-DJ5EkXQo.mjs +2 -0
  124. package/dist/chunks/de-DJ5EkXQo.mjs.map +1 -0
  125. package/dist/chunks/{de-C--bRmjW.mjs → de-DRbhnS4T.mjs} +2 -2
  126. package/dist/chunks/{de-C--bRmjW.mjs.map → de-DRbhnS4T.mjs.map} +1 -1
  127. package/dist/chunks/{es-DFUVd7eO.mjs → es-BQ9dox_E.mjs} +2 -2
  128. package/dist/chunks/{es-DFUVd7eO.mjs.map → es-BQ9dox_E.mjs.map} +1 -1
  129. package/dist/chunks/es-CEAJj7aB.mjs +2 -0
  130. package/dist/chunks/es-CEAJj7aB.mjs.map +1 -0
  131. package/dist/chunks/fr-DhWQzZy3.mjs +2 -0
  132. package/dist/chunks/fr-DhWQzZy3.mjs.map +1 -0
  133. package/dist/chunks/{fr-BaXKyPmX.mjs → fr-NVOinLyF.mjs} +2 -2
  134. package/dist/chunks/{fr-BaXKyPmX.mjs.map → fr-NVOinLyF.mjs.map} +1 -1
  135. package/dist/chunks/full-DSWM4cKQ.mjs +2 -0
  136. package/dist/chunks/{full-BBl7mvwH.mjs.map → full-DSWM4cKQ.mjs.map} +1 -1
  137. package/dist/chunks/hi-BsZzSMfL.mjs +2 -0
  138. package/dist/chunks/hi-BsZzSMfL.mjs.map +1 -0
  139. package/dist/chunks/{hi-aH9HZG23.mjs → hi-DrC2H81d.mjs} +2 -2
  140. package/dist/chunks/{hi-aH9HZG23.mjs.map → hi-DrC2H81d.mjs.map} +1 -1
  141. package/dist/chunks/minimal-CFkkPXef.mjs +2 -0
  142. package/dist/chunks/{minimal-CtnR4dqp.mjs.map → minimal-CFkkPXef.mjs.map} +1 -1
  143. package/dist/chunks/pt-BuZ7acHF.mjs +2 -0
  144. package/dist/chunks/pt-BuZ7acHF.mjs.map +1 -0
  145. package/dist/chunks/{pt-Hy-0Xnnc.mjs → pt-CFrcl1v_.mjs} +2 -2
  146. package/dist/chunks/{pt-Hy-0Xnnc.mjs.map → pt-CFrcl1v_.mjs.map} +1 -1
  147. package/dist/chunks/rolldown-runtime-H_PjY6_i.mjs +1 -0
  148. package/dist/chunks/ru-CsP6mLxp.mjs +2 -0
  149. package/dist/chunks/ru-CsP6mLxp.mjs.map +1 -0
  150. package/dist/chunks/{ru-BFpEOrVp.mjs → ru-gxbzqLL8.mjs} +2 -2
  151. package/dist/chunks/{ru-BFpEOrVp.mjs.map → ru-gxbzqLL8.mjs.map} +1 -1
  152. package/dist/chunks/src-DiAOfuOT.mjs +2 -0
  153. package/dist/chunks/src-DiAOfuOT.mjs.map +1 -0
  154. package/dist/chunks/zh-BFZOM3lF.mjs +2 -0
  155. package/dist/chunks/{zh-BjoyjClN.mjs.map → zh-BFZOM3lF.mjs.map} +1 -1
  156. package/dist/chunks/zh-CiIyOm6U.mjs +2 -0
  157. package/dist/chunks/zh-CiIyOm6U.mjs.map +1 -0
  158. package/dist/commands/BlockInsertion.d.ts +5 -3
  159. package/dist/commands/BlockInsertion.d.ts.map +1 -1
  160. package/dist/commands/SelectionDeletion.d.ts +13 -2
  161. package/dist/commands/SelectionDeletion.d.ts.map +1 -1
  162. package/dist/editor/ContentSerializer.d.ts +21 -0
  163. package/dist/editor/ContentSerializer.d.ts.map +1 -1
  164. package/dist/editor/EditorConfig.d.ts +17 -0
  165. package/dist/editor/EditorConfig.d.ts.map +1 -1
  166. package/dist/editor/EditorConfigController.d.ts +10 -0
  167. package/dist/editor/EditorConfigController.d.ts.map +1 -1
  168. package/dist/editor/EditorInitializer.d.ts +4 -0
  169. package/dist/editor/EditorInitializer.d.ts.map +1 -1
  170. package/dist/editor/EditorLocale.d.ts +2 -0
  171. package/dist/editor/EditorLocale.d.ts.map +1 -1
  172. package/dist/editor/MarkdownMode.d.ts +46 -0
  173. package/dist/editor/MarkdownMode.d.ts.map +1 -0
  174. package/dist/editor/NotectlEditor.d.ts +24 -0
  175. package/dist/editor/NotectlEditor.d.ts.map +1 -1
  176. package/dist/editor/locales/ar.d.ts.map +1 -1
  177. package/dist/editor/locales/de.d.ts.map +1 -1
  178. package/dist/editor/locales/es.d.ts.map +1 -1
  179. package/dist/editor/locales/fr.d.ts.map +1 -1
  180. package/dist/editor/locales/hi.d.ts.map +1 -1
  181. package/dist/editor/locales/pt.d.ts.map +1 -1
  182. package/dist/editor/locales/ru.d.ts.map +1 -1
  183. package/dist/editor/locales/zh.d.ts.map +1 -1
  184. package/dist/editor/styles/list.d.ts +1 -1
  185. package/dist/editor/styles/list.d.ts.map +1 -1
  186. package/dist/editor/styles/table.d.ts +1 -1
  187. package/dist/editor/styles/table.d.ts.map +1 -1
  188. package/dist/full.mjs +1 -1
  189. package/dist/html.d.ts +1 -0
  190. package/dist/html.d.ts.map +1 -1
  191. package/dist/html.mjs +1 -1
  192. package/dist/index.d.ts +5 -5
  193. package/dist/index.d.ts.map +1 -1
  194. package/dist/input/ClipboardHandler.d.ts +2 -0
  195. package/dist/input/ClipboardHandler.d.ts.map +1 -1
  196. package/dist/input/InputHandler.d.ts +7 -0
  197. package/dist/input/InputHandler.d.ts.map +1 -1
  198. package/dist/input/InputManager.d.ts +10 -0
  199. package/dist/input/InputManager.d.ts.map +1 -1
  200. package/dist/input/KeyboardHandler.d.ts.map +1 -1
  201. package/dist/input/MarkdownPasteDetector.d.ts +26 -0
  202. package/dist/input/MarkdownPasteDetector.d.ts.map +1 -0
  203. package/dist/input/PasteHTMLHandler.d.ts +18 -1
  204. package/dist/input/PasteHTMLHandler.d.ts.map +1 -1
  205. package/dist/input/PasteHandler.d.ts +30 -0
  206. package/dist/input/PasteHandler.d.ts.map +1 -1
  207. package/dist/input/PasteRichBlockHandler.d.ts.map +1 -1
  208. package/dist/input/SelectionDocument.d.ts +2 -1
  209. package/dist/input/SelectionDocument.d.ts.map +1 -1
  210. package/dist/markdown.d.ts +17 -0
  211. package/dist/markdown.d.ts.map +1 -0
  212. package/dist/markdown.mjs +1 -0
  213. package/dist/model/AttrRegistry.d.ts +2 -2
  214. package/dist/model/AttrRegistry.d.ts.map +1 -1
  215. package/dist/model/ContentModel.d.ts +12 -0
  216. package/dist/model/ContentModel.d.ts.map +1 -1
  217. package/dist/model/Document.d.ts +28 -3
  218. package/dist/model/Document.d.ts.map +1 -1
  219. package/dist/model/HTMLUtils.d.ts +15 -0
  220. package/dist/model/HTMLUtils.d.ts.map +1 -1
  221. package/dist/model/InlineNodeSpec.d.ts +7 -1
  222. package/dist/model/InlineNodeSpec.d.ts.map +1 -1
  223. package/dist/model/InputRule.d.ts +11 -0
  224. package/dist/model/InputRule.d.ts.map +1 -1
  225. package/dist/model/MarkSpec.d.ts +7 -1
  226. package/dist/model/MarkSpec.d.ts.map +1 -1
  227. package/dist/model/MarkdownSyntaxRegistry.d.ts +51 -0
  228. package/dist/model/MarkdownSyntaxRegistry.d.ts.map +1 -0
  229. package/dist/model/NodeSpec.d.ts +47 -1
  230. package/dist/model/NodeSpec.d.ts.map +1 -1
  231. package/dist/model/RichBlockData.d.ts +2 -0
  232. package/dist/model/RichBlockData.d.ts.map +1 -1
  233. package/dist/model/SchemaRegistry.d.ts.map +1 -1
  234. package/dist/model/TableDimensions.d.ts +11 -0
  235. package/dist/model/TableDimensions.d.ts.map +1 -0
  236. package/dist/notectl-core.mjs +1 -1
  237. package/dist/notectl-core.umd.js +1 -1
  238. package/dist/notectl-core.umd.js.map +1 -1
  239. package/dist/platform/EditorEventBoundary.d.ts +12 -0
  240. package/dist/platform/EditorEventBoundary.d.ts.map +1 -0
  241. package/dist/plugins/Plugin.d.ts +7 -0
  242. package/dist/plugins/Plugin.d.ts.map +1 -1
  243. package/dist/plugins/PluginContextFactory.d.ts +2 -0
  244. package/dist/plugins/PluginContextFactory.d.ts.map +1 -1
  245. package/dist/plugins/PluginManager.d.ts +2 -0
  246. package/dist/plugins/PluginManager.d.ts.map +1 -1
  247. package/dist/plugins/alignment.mjs +1 -1
  248. package/dist/plugins/bidi-isolation.mjs +1 -1
  249. package/dist/plugins/blockquote/BlockquotePlugin.d.ts +2 -0
  250. package/dist/plugins/blockquote/BlockquotePlugin.d.ts.map +1 -1
  251. package/dist/plugins/blockquote.mjs +1 -1
  252. package/dist/plugins/caret-navigation.mjs +1 -1
  253. package/dist/plugins/code-block/CodeBlockTypes.d.ts +2 -0
  254. package/dist/plugins/code-block/CodeBlockTypes.d.ts.map +1 -1
  255. package/dist/plugins/code-block.mjs +1 -1
  256. package/dist/plugins/font-size/FontSizeOperations.d.ts.map +1 -1
  257. package/dist/plugins/font-size.mjs +1 -1
  258. package/dist/plugins/font.mjs +1 -1
  259. package/dist/plugins/formula/DisplayMathNodeSpec.d.ts.map +1 -1
  260. package/dist/plugins/formula/FormulaInputRules.d.ts.map +1 -1
  261. package/dist/plugins/formula/FormulaMarkdownSyntax.d.ts +4 -0
  262. package/dist/plugins/formula/FormulaMarkdownSyntax.d.ts.map +1 -0
  263. package/dist/plugins/formula/FormulaPlugin.d.ts.map +1 -1
  264. package/dist/plugins/formula/FormulaTypes.d.ts +2 -0
  265. package/dist/plugins/formula/FormulaTypes.d.ts.map +1 -1
  266. package/dist/plugins/formula/InlineMathNodeSpec.d.ts.map +1 -1
  267. package/dist/plugins/formula.mjs +1 -1
  268. package/dist/plugins/gap-cursor.mjs +1 -1
  269. package/dist/plugins/hard-break.mjs +1 -1
  270. package/dist/plugins/heading/HeadingPlugin.d.ts +2 -0
  271. package/dist/plugins/heading/HeadingPlugin.d.ts.map +1 -1
  272. package/dist/plugins/heading.mjs +1 -1
  273. package/dist/plugins/highlight.mjs +1 -1
  274. package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts +2 -0
  275. package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts.map +1 -1
  276. package/dist/plugins/horizontal-rule.mjs +1 -1
  277. package/dist/plugins/image/ImagePlugin.d.ts +14 -0
  278. package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
  279. package/dist/plugins/image.mjs +1 -1
  280. package/dist/plugins/inline-code/InlineCodePlugin.d.ts.map +1 -1
  281. package/dist/plugins/inline-code.mjs +1 -1
  282. package/dist/plugins/link/LinkPlugin.d.ts +14 -0
  283. package/dist/plugins/link/LinkPlugin.d.ts.map +1 -1
  284. package/dist/plugins/link.mjs +1 -1
  285. package/dist/plugins/list/ListCommands.d.ts +5 -1
  286. package/dist/plugins/list/ListCommands.d.ts.map +1 -1
  287. package/dist/plugins/list/ListInputRules.d.ts.map +1 -1
  288. package/dist/plugins/list/ListItemContext.d.ts +27 -0
  289. package/dist/plugins/list/ListItemContext.d.ts.map +1 -0
  290. package/dist/plugins/list/ListKeyboardHandlers.d.ts.map +1 -1
  291. package/dist/plugins/list/ListPlugin.d.ts +2 -0
  292. package/dist/plugins/list/ListPlugin.d.ts.map +1 -1
  293. package/dist/plugins/list/ListToolbarItems.d.ts.map +1 -1
  294. package/dist/plugins/list.mjs +1 -1
  295. package/dist/plugins/print/PrintContentPreparer.d.ts.map +1 -1
  296. package/dist/plugins/print/PrintDestinationBridge.d.ts +23 -0
  297. package/dist/plugins/print/PrintDestinationBridge.d.ts.map +1 -0
  298. package/dist/plugins/print/PrintHostStyles.d.ts.map +1 -1
  299. package/dist/plugins/print/PrintServiceImpl.d.ts +5 -1
  300. package/dist/plugins/print/PrintServiceImpl.d.ts.map +1 -1
  301. package/dist/plugins/print/PrintStyleCollector.d.ts.map +1 -1
  302. package/dist/plugins/print.mjs +1 -1
  303. package/dist/plugins/shared/MarkInputRule.d.ts +9 -0
  304. package/dist/plugins/shared/MarkInputRule.d.ts.map +1 -0
  305. package/dist/plugins/shared/PopupPositioning.d.ts +2 -0
  306. package/dist/plugins/shared/PopupPositioning.d.ts.map +1 -1
  307. package/dist/plugins/shared/index.d.ts +1 -0
  308. package/dist/plugins/shared/index.d.ts.map +1 -1
  309. package/dist/plugins/shared.mjs +1 -1
  310. package/dist/plugins/smart-paste.mjs +1 -1
  311. package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts +2 -0
  312. package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts.map +1 -1
  313. package/dist/plugins/strikethrough.mjs +1 -1
  314. package/dist/plugins/super-sub.mjs +1 -1
  315. package/dist/plugins/table/TableClipboard.d.ts +8 -0
  316. package/dist/plugins/table/TableClipboard.d.ts.map +1 -0
  317. package/dist/plugins/table/TableCommands.d.ts.map +1 -1
  318. package/dist/plugins/table/TableContextMenu.d.ts +11 -1
  319. package/dist/plugins/table/TableContextMenu.d.ts.map +1 -1
  320. package/dist/plugins/table/TableControls.d.ts +6 -1
  321. package/dist/plugins/table/TableControls.d.ts.map +1 -1
  322. package/dist/plugins/table/TableControlsDOM.d.ts +11 -2
  323. package/dist/plugins/table/TableControlsDOM.d.ts.map +1 -1
  324. package/dist/plugins/table/TableControlsLayout.d.ts +12 -3
  325. package/dist/plugins/table/TableControlsLayout.d.ts.map +1 -1
  326. package/dist/plugins/table/TableGrid.d.ts +57 -0
  327. package/dist/plugins/table/TableGrid.d.ts.map +1 -0
  328. package/dist/plugins/table/TableHelpers.d.ts +4 -0
  329. package/dist/plugins/table/TableHelpers.d.ts.map +1 -1
  330. package/dist/plugins/table/TableLocale.d.ts +30 -0
  331. package/dist/plugins/table/TableLocale.d.ts.map +1 -1
  332. package/dist/plugins/table/TableNavigation.d.ts +5 -1
  333. package/dist/plugins/table/TableNavigation.d.ts.map +1 -1
  334. package/dist/plugins/table/TableNodeViews.d.ts +13 -1
  335. package/dist/plugins/table/TableNodeViews.d.ts.map +1 -1
  336. package/dist/plugins/table/TablePlugin.d.ts +21 -1
  337. package/dist/plugins/table/TablePlugin.d.ts.map +1 -1
  338. package/dist/plugins/table/TableSelection.d.ts.map +1 -1
  339. package/dist/plugins/table/TableSizeEditor.d.ts +11 -0
  340. package/dist/plugins/table/TableSizeEditor.d.ts.map +1 -0
  341. package/dist/plugins/table/TableSizing.d.ts +70 -0
  342. package/dist/plugins/table/TableSizing.d.ts.map +1 -0
  343. package/dist/plugins/table/index.d.ts +3 -1
  344. package/dist/plugins/table/index.d.ts.map +1 -1
  345. package/dist/plugins/table/locales/ar.d.ts.map +1 -1
  346. package/dist/plugins/table/locales/de.d.ts.map +1 -1
  347. package/dist/plugins/table/locales/es.d.ts.map +1 -1
  348. package/dist/plugins/table/locales/fr.d.ts.map +1 -1
  349. package/dist/plugins/table/locales/hi.d.ts.map +1 -1
  350. package/dist/plugins/table/locales/pt.d.ts.map +1 -1
  351. package/dist/plugins/table/locales/ru.d.ts.map +1 -1
  352. package/dist/plugins/table/locales/zh.d.ts.map +1 -1
  353. package/dist/plugins/table.mjs +1 -1
  354. package/dist/plugins/text-color.mjs +1 -1
  355. package/dist/plugins/text-direction-auto.mjs +1 -1
  356. package/dist/plugins/text-direction.mjs +1 -1
  357. package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts +9 -0
  358. package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts.map +1 -1
  359. package/dist/plugins/text-formatting.mjs +1 -1
  360. package/dist/plugins/toolbar.mjs +1 -1
  361. package/dist/plugins/video/VideoCommands.d.ts.map +1 -1
  362. package/dist/plugins/video.mjs +1 -1
  363. package/dist/presets/full.mjs +1 -1
  364. package/dist/presets/minimal.mjs +1 -1
  365. package/dist/presets.mjs +1 -1
  366. package/dist/serialization/DocumentParser.d.ts.map +1 -1
  367. package/dist/serialization/DocumentSerializer.d.ts +2 -0
  368. package/dist/serialization/DocumentSerializer.d.ts.map +1 -1
  369. package/dist/serialization/HTMLSanitization.d.ts +15 -0
  370. package/dist/serialization/HTMLSanitization.d.ts.map +1 -0
  371. package/dist/serialization/MarkSerializer.d.ts +12 -0
  372. package/dist/serialization/MarkSerializer.d.ts.map +1 -1
  373. package/dist/serialization/MarkdownParser.d.ts +6 -0
  374. package/dist/serialization/MarkdownParser.d.ts.map +1 -0
  375. package/dist/serialization/MarkdownSerializer.d.ts +12 -0
  376. package/dist/serialization/MarkdownSerializer.d.ts.map +1 -0
  377. package/dist/serialization/MarkdownTypes.d.ts +59 -0
  378. package/dist/serialization/MarkdownTypes.d.ts.map +1 -0
  379. package/dist/serialization/TableDimensions.d.ts +37 -0
  380. package/dist/serialization/TableDimensions.d.ts.map +1 -0
  381. package/dist/serialization/markdown/BlockSerializers.d.ts +7 -0
  382. package/dist/serialization/markdown/BlockSerializers.d.ts.map +1 -0
  383. package/dist/serialization/markdown/BlockTokenizer.d.ts +54 -0
  384. package/dist/serialization/markdown/BlockTokenizer.d.ts.map +1 -0
  385. package/dist/serialization/markdown/GfmAutolink.d.ts +20 -0
  386. package/dist/serialization/markdown/GfmAutolink.d.ts.map +1 -0
  387. package/dist/serialization/markdown/GfmTableParser.d.ts +26 -0
  388. package/dist/serialization/markdown/GfmTableParser.d.ts.map +1 -0
  389. package/dist/serialization/markdown/InlineAst.d.ts +34 -0
  390. package/dist/serialization/markdown/InlineAst.d.ts.map +1 -0
  391. package/dist/serialization/markdown/InlineSerializers.d.ts +5 -0
  392. package/dist/serialization/markdown/InlineSerializers.d.ts.map +1 -0
  393. package/dist/serialization/markdown/InlineTokenizer.d.ts +5 -0
  394. package/dist/serialization/markdown/InlineTokenizer.d.ts.map +1 -0
  395. package/dist/serialization/markdown/LinkReferenceExtractor.d.ts +37 -0
  396. package/dist/serialization/markdown/LinkReferenceExtractor.d.ts.map +1 -0
  397. package/dist/serialization/markdown/MarkdownContext.d.ts +32 -0
  398. package/dist/serialization/markdown/MarkdownContext.d.ts.map +1 -0
  399. package/dist/serialization/markdown/MarkdownEntities.d.ts +33 -0
  400. package/dist/serialization/markdown/MarkdownEntities.d.ts.map +1 -0
  401. package/dist/serialization/markdown/MarkdownEscape.d.ts +33 -0
  402. package/dist/serialization/markdown/MarkdownEscape.d.ts.map +1 -0
  403. package/dist/serialization/markdown/MarkdownHTMLRegistry.d.ts +4 -0
  404. package/dist/serialization/markdown/MarkdownHTMLRegistry.d.ts.map +1 -0
  405. package/dist/serialization/markdown/MarkdownParseContext.d.ts +23 -0
  406. package/dist/serialization/markdown/MarkdownParseContext.d.ts.map +1 -0
  407. package/dist/state/Mapping.d.ts +33 -10
  408. package/dist/state/Mapping.d.ts.map +1 -1
  409. package/dist/state/StepApplication.d.ts +3 -1
  410. package/dist/state/StepApplication.d.ts.map +1 -1
  411. package/dist/state/StepHandlers.d.ts.map +1 -1
  412. package/dist/state/StepInversion.d.ts +2 -1
  413. package/dist/state/StepInversion.d.ts.map +1 -1
  414. package/dist/state/StepMapping.d.ts +3 -2
  415. package/dist/state/StepMapping.d.ts.map +1 -1
  416. package/dist/state/StepMaps.d.ts +3 -2
  417. package/dist/state/StepMaps.d.ts.map +1 -1
  418. package/dist/state/Steps.d.ts +34 -2
  419. package/dist/state/Steps.d.ts.map +1 -1
  420. package/dist/state/TransactionBuilder.d.ts +7 -1
  421. package/dist/state/TransactionBuilder.d.ts.map +1 -1
  422. package/dist/test/MarkdownConformanceUtils.d.ts +12 -0
  423. package/dist/test/MarkdownConformanceUtils.d.ts.map +1 -0
  424. package/dist/view/BlockRendering.d.ts +5 -0
  425. package/dist/view/BlockRendering.d.ts.map +1 -1
  426. package/dist/view/DecorationRendering.d.ts +6 -0
  427. package/dist/view/DecorationRendering.d.ts.map +1 -1
  428. package/dist/view/EditorViewEvents.d.ts.map +1 -1
  429. package/dist/view/Reconciler.d.ts.map +1 -1
  430. package/package.json +14 -1
  431. package/dist/chunks/AttrRegistry-DcDVyzLm.mjs.map +0 -1
  432. package/dist/chunks/BlockInsertion-6rR9tIGP.mjs +0 -2
  433. package/dist/chunks/BlockInsertion-6rR9tIGP.mjs.map +0 -1
  434. package/dist/chunks/BlockquotePlugin-4V7KV_Sb.mjs +0 -2
  435. package/dist/chunks/CodeBlockPlugin-3V2K3RBe.mjs +0 -2
  436. package/dist/chunks/CodeBlockPlugin-3V2K3RBe.mjs.map +0 -1
  437. package/dist/chunks/ColorPickerPopup-lcf3jS6G.mjs +0 -2
  438. package/dist/chunks/Commands-BIIpx_Zd.mjs +0 -2
  439. package/dist/chunks/Commands-BIIpx_Zd.mjs.map +0 -1
  440. package/dist/chunks/Decoration-ZeyVfwJB.mjs +0 -2
  441. package/dist/chunks/Decoration-ZeyVfwJB.mjs.map +0 -1
  442. package/dist/chunks/Document-r7vLOAGA.mjs +0 -2
  443. package/dist/chunks/Document-r7vLOAGA.mjs.map +0 -1
  444. package/dist/chunks/DocumentParser-CcTSeT1B.mjs +0 -2
  445. package/dist/chunks/DocumentParser-CcTSeT1B.mjs.map +0 -1
  446. package/dist/chunks/FontSizePlugin-9StCjEfN.mjs.map +0 -1
  447. package/dist/chunks/FormulaPlugin-CV5VUxkb.mjs +0 -2
  448. package/dist/chunks/FormulaPlugin-CV5VUxkb.mjs.map +0 -1
  449. package/dist/chunks/GapCursorNavigation-ycNzuQVH.mjs +0 -2
  450. package/dist/chunks/HTMLUtils-C6B4UT00.mjs +0 -2
  451. package/dist/chunks/HTMLUtils-C6B4UT00.mjs.map +0 -1
  452. package/dist/chunks/HeadingPlugin-BuGoM9Rz.mjs +0 -2
  453. package/dist/chunks/HorizontalRulePlugin-0FjHPZuA.mjs +0 -2
  454. package/dist/chunks/HorizontalRulePlugin-0FjHPZuA.mjs.map +0 -1
  455. package/dist/chunks/ImagePlugin-KpkuE2LH.mjs +0 -2
  456. package/dist/chunks/InlineCodePlugin-DMr4O7c7.mjs.map +0 -1
  457. package/dist/chunks/InlineStyleMarkSpec-C6LJT7kp.mjs +0 -2
  458. package/dist/chunks/LinkPlugin-DvZ3MPgL.mjs +0 -2
  459. package/dist/chunks/LinkPlugin-DvZ3MPgL.mjs.map +0 -1
  460. package/dist/chunks/ListPlugin-2yl6KiTK.mjs +0 -2
  461. package/dist/chunks/ListPlugin-2yl6KiTK.mjs.map +0 -1
  462. package/dist/chunks/NodeSelectionCommands-Dj4VxLdD.mjs +0 -2
  463. package/dist/chunks/PluginHelpers-KDuTlmXm.mjs +0 -2
  464. package/dist/chunks/PopupPositioning-BB97-__N.mjs +0 -2
  465. package/dist/chunks/PrintPlugin-DyIZDY3Q.mjs +0 -2
  466. package/dist/chunks/PrintPlugin-DyIZDY3Q.mjs.map +0 -1
  467. package/dist/chunks/StrikethroughPlugin-BLKDRWtf.mjs +0 -2
  468. package/dist/chunks/StrikethroughPlugin-BLKDRWtf.mjs.map +0 -1
  469. package/dist/chunks/StyleRuntime-BFKu52mS.mjs +0 -2
  470. package/dist/chunks/StyleRuntime-BFKu52mS.mjs.map +0 -1
  471. package/dist/chunks/TablePlugin-BTH9VRZq.mjs +0 -2
  472. package/dist/chunks/TablePlugin-BTH9VRZq.mjs.map +0 -1
  473. package/dist/chunks/TextColorPlugin-CEfZQ6Md.mjs +0 -2
  474. package/dist/chunks/TextDirectionAutoPlugin-CzWJjrvG.mjs +0 -2
  475. package/dist/chunks/TextDirectionService-OFOU6r_s.mjs +0 -2
  476. package/dist/chunks/TextFormattingPlugin-Cubp3e7f.mjs +0 -2
  477. package/dist/chunks/TextFormattingPlugin-Cubp3e7f.mjs.map +0 -1
  478. package/dist/chunks/VideoPlugin-B3uf1Dwp.mjs +0 -2
  479. package/dist/chunks/VideoPlugin-B3uf1Dwp.mjs.map +0 -1
  480. package/dist/chunks/WordBoundary-DxeMBRyP.mjs +0 -2
  481. package/dist/chunks/ar-BTShmP2E.mjs +0 -2
  482. package/dist/chunks/ar-jbplYWkC.mjs +0 -2
  483. package/dist/chunks/ar-jbplYWkC.mjs.map +0 -1
  484. package/dist/chunks/de-DN-e6G5A.mjs +0 -2
  485. package/dist/chunks/de-DN-e6G5A.mjs.map +0 -1
  486. package/dist/chunks/es-CM55WeEN.mjs +0 -2
  487. package/dist/chunks/es-CM55WeEN.mjs.map +0 -1
  488. package/dist/chunks/fr-C_2i5Ono.mjs +0 -2
  489. package/dist/chunks/fr-C_2i5Ono.mjs.map +0 -1
  490. package/dist/chunks/full-BBl7mvwH.mjs +0 -2
  491. package/dist/chunks/hi-C9fvG91d.mjs +0 -2
  492. package/dist/chunks/hi-C9fvG91d.mjs.map +0 -1
  493. package/dist/chunks/minimal-CtnR4dqp.mjs +0 -2
  494. package/dist/chunks/pt-GqLw5tN0.mjs +0 -2
  495. package/dist/chunks/pt-GqLw5tN0.mjs.map +0 -1
  496. package/dist/chunks/ru-4g_qsaLr.mjs +0 -2
  497. package/dist/chunks/ru-4g_qsaLr.mjs.map +0 -1
  498. package/dist/chunks/src-C89Cw7ni.mjs +0 -2
  499. package/dist/chunks/src-C89Cw7ni.mjs.map +0 -1
  500. package/dist/chunks/zh-BjoyjClN.mjs +0 -2
  501. package/dist/chunks/zh-DeZP08HI.mjs +0 -2
  502. package/dist/chunks/zh-DeZP08HI.mjs.map +0 -1
@@ -0,0 +1,2 @@
1
+ import{c as e,o}from"./PluginHelpers-Dx_0hfDe.mjs";import{a as t,t as r}from"./ColorValidation-DAijTjG9.mjs";import{t as a}from"./InlineStyleMarkSpec-CjSRj4f_.mjs";import{t as s}from"./color-picker-C9B2rYw-.mjs";import{a as l,i as c,t as i}from"./ColorPickerPopup-DiA68Pzz.mjs";var f={label:"Text Color",tooltip:"Text Color",resetLabel:"Default",ariaLabelPrefix:"Text color"},m=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-Dcl3kgtd.mjs"),"./locales/de.ts":()=>import("./de-DHs9i4af.mjs"),"./locales/es.ts":()=>import("./es-DHxdoEzR.mjs"),"./locales/fr.ts":()=>import("./fr-SbpHNrQ-.mjs"),"./locales/hi.ts":()=>import("./hi-By8YwVIX.mjs"),"./locales/pt.ts":()=>import("./pt-DgfMoLWR.mjs"),"./locales/ru.ts":()=>import("./ru-C-APN_dm.mjs"),"./locales/zh.ts":()=>import("./zh-CYV-db-K.mjs")});async function d(o){return e(m,o,f)}var p=["#000000","#434343","#666666","#999999","#b7b7b7","#cccccc","#d9d9d9","#efefef","#f3f3f3","#ffffff","#980000","#ff0000","#ff9900","#ffff00","#00ff00","#00ffff","#4a86e8","#0000ff","#9900ff","#ff00ff","#e6b8af","#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#c9daf8","#cfe2f3","#d9d2e9","#ead1dc","#dd7e6b","#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#a4c2f4","#9fc5e8","#b4a7d6","#d5a6bd","#cc4125","#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6d9eeb","#6fa8dc","#8e7cc3","#c27ba0","#a61c00","#cc0000","#e69138","#f1c232","#6aa84f","#45818e","#3c78d8","#3d85c6","#674ea7","#a64d79","#85200c","#990000","#b45f06","#bf9000","#38761d","#134f5c","#1155cc","#0b5394","#351c75","#741b47"],n=class{id="textColor";name="Text Color";priority=23;config;colors;locale;constructor(e){this.config={...e},this.colors=t(e?.colors,p,"TextColorPlugin")}async init(e){this.locale=await o(e,this.config.locale,f,d),e.registerStyleSheet(s),this.registerMarkSpec(e),this.registerCommands(e),this.registerToolbarItem(e)}registerMarkSpec(e){e.registerMarkSpec(a({type:"textColor",rank:5,valueAttr:"color",domStyleProperty:"color",cssProperty:"color",validate:r,validateOnParse:!0}))}registerCommands(e){e.registerCommand("removeTextColor",()=>l(e,e.getState(),"textColor"))}registerToolbarItem(e){const o=['<svg xmlns="http://www.w3.org/2000/svg"',' viewBox="0 0 24 24">','<path d="M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z"/>','<rect x="3" y="19.5" width="18" height="3"',' rx="0.5" fill="#e53935"/>',"</svg>"].join("");e.registerToolbarItem({id:"textColor",group:"format",icon:o,label:this.locale.label,tooltip:this.locale.tooltip,command:"removeTextColor",popupType:"custom",renderPopup:(e,o,t)=>{i(e,o,{markType:"textColor",colors:this.colors,columns:10,resetLabel:this.locale.resetLabel,resetCommand:"removeTextColor",ariaLabelPrefix:this.locale.ariaLabelPrefix,onClose:t})},isActive:e=>c(e,"textColor")})}};export{f as n,d as r,n as t};
2
+ //# sourceMappingURL=TextColorPlugin-CTd9tfeG.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextColorPlugin-CEfZQ6Md.mjs","names":[],"sources":["../../src/plugins/text-color/TextColorLocale.ts","../../src/plugins/text-color/TextColorPalette.ts","../../src/plugins/text-color/TextColorPlugin.ts"],"sourcesContent":["/** Locale interface and default English locale for the TextColorPlugin. */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface TextColorLocale {\n\treadonly label: string;\n\treadonly tooltip: string;\n\treadonly resetLabel: string;\n\treadonly ariaLabelPrefix: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_COLOR_LOCALE_EN: TextColorLocale = {\n\tlabel: 'Text Color',\n\ttooltip: 'Text Color',\n\tresetLabel: 'Default',\n\tariaLabelPrefix: 'Text color',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<TextColorLocale> = import.meta.glob<{\n\tdefault: TextColorLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadTextColorLocale(lang: string): Promise<TextColorLocale> {\n\treturn loadLocaleModule(localeModules, lang, TEXT_COLOR_LOCALE_EN);\n}\n","/**\n * Default text-color palette (Google Docs style: 10 columns x 7 rows).\n * Used by TextColorPlugin when no `colors` override is provided.\n */\nexport const COLOR_PALETTE: readonly string[] = [\n\t// Row 1 — dark\n\t'#000000',\n\t'#434343',\n\t'#666666',\n\t'#999999',\n\t'#b7b7b7',\n\t'#cccccc',\n\t'#d9d9d9',\n\t'#efefef',\n\t'#f3f3f3',\n\t'#ffffff',\n\t// Row 2 — vivid\n\t'#980000',\n\t'#ff0000',\n\t'#ff9900',\n\t'#ffff00',\n\t'#00ff00',\n\t'#00ffff',\n\t'#4a86e8',\n\t'#0000ff',\n\t'#9900ff',\n\t'#ff00ff',\n\t// Row 3 — light 3\n\t'#e6b8af',\n\t'#f4cccc',\n\t'#fce5cd',\n\t'#fff2cc',\n\t'#d9ead3',\n\t'#d0e0e3',\n\t'#c9daf8',\n\t'#cfe2f3',\n\t'#d9d2e9',\n\t'#ead1dc',\n\t// Row 4 — light 2\n\t'#dd7e6b',\n\t'#ea9999',\n\t'#f9cb9c',\n\t'#ffe599',\n\t'#b6d7a8',\n\t'#a2c4c9',\n\t'#a4c2f4',\n\t'#9fc5e8',\n\t'#b4a7d6',\n\t'#d5a6bd',\n\t// Row 5 — light 1\n\t'#cc4125',\n\t'#e06666',\n\t'#f6b26b',\n\t'#ffd966',\n\t'#93c47d',\n\t'#76a5af',\n\t'#6d9eeb',\n\t'#6fa8dc',\n\t'#8e7cc3',\n\t'#c27ba0',\n\t// Row 6 — dark 1\n\t'#a61c00',\n\t'#cc0000',\n\t'#e69138',\n\t'#f1c232',\n\t'#6aa84f',\n\t'#45818e',\n\t'#3c78d8',\n\t'#3d85c6',\n\t'#674ea7',\n\t'#a64d79',\n\t// Row 7 — dark 2\n\t'#85200c',\n\t'#990000',\n\t'#b45f06',\n\t'#bf9000',\n\t'#38761d',\n\t'#134f5c',\n\t'#1155cc',\n\t'#0b5394',\n\t'#351c75',\n\t'#741b47',\n];\n","/**\n * TextColorPlugin: registers a text color mark with attrs,\n * toolbar button with a color picker popup, and removeTextColor command.\n */\n\nimport { COLOR_PICKER_CSS } from '../../editor/styles/color-picker.js';\nimport 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\tTEXT_COLOR_LOCALE_EN,\n\ttype TextColorLocale,\n\tloadTextColorLocale,\n} from './TextColorLocale.js';\nimport { COLOR_PALETTE } from './TextColorPalette.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\ttextColor: { color: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface TextColorConfig {\n\t/**\n\t * Restricts the color picker to a specific set of hex colors.\n\t * Each value must be a valid hex color code (`#RGB` or `#RRGGBB`).\n\t * Duplicates are removed automatically (case-insensitive).\n\t * When omitted, the full default palette is shown.\n\t */\n\treadonly colors?: readonly string[];\n\treadonly locale?: TextColorLocale;\n}\n\n// --- Plugin ---\n\nexport class TextColorPlugin implements Plugin {\n\treadonly id = 'textColor';\n\treadonly name = 'Text Color';\n\treadonly priority = 23;\n\n\tprivate readonly config: TextColorConfig;\n\tprivate readonly colors: readonly string[];\n\tprivate locale!: TextColorLocale;\n\n\tconstructor(config?: Partial<TextColorConfig>) {\n\t\tthis.config = { ...config };\n\t\tthis.colors = resolveColors(config?.colors, COLOR_PALETTE, 'TextColorPlugin');\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tTEXT_COLOR_LOCALE_EN,\n\t\t\tloadTextColorLocale,\n\t\t);\n\n\t\tcontext.registerStyleSheet(COLOR_PICKER_CSS);\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec(\n\t\t\tcreateInlineStyleMarkSpec({\n\t\t\t\ttype: 'textColor',\n\t\t\t\trank: 5,\n\t\t\t\tvalueAttr: 'color',\n\t\t\t\tdomStyleProperty: 'color',\n\t\t\t\tcssProperty: '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('removeTextColor', () => {\n\t\t\treturn removeColorMark(context, context.getState(), 'textColor');\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst pathD =\n\t\t\t'M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2z' + 'm-1.38 9L12 5.67 14.38 12H9.62z';\n\t\tconst icon: string = [\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\"',\n\t\t\t' viewBox=\"0 0 24 24\">',\n\t\t\t`<path d=\"${pathD}\"/>`,\n\t\t\t'<rect x=\"3\" y=\"19.5\" width=\"18\" height=\"3\"',\n\t\t\t' rx=\"0.5\" fill=\"#e53935\"/>',\n\t\t\t'</svg>',\n\t\t].join('');\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'textColor',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: this.locale.label,\n\t\t\ttooltip: this.locale.tooltip,\n\t\t\tcommand: 'removeTextColor',\n\t\t\tpopupType: 'custom',\n\t\t\trenderPopup: (container, ctx, onClose) => {\n\t\t\t\trenderColorPickerPopup(container, ctx, {\n\t\t\t\t\tmarkType: 'textColor',\n\t\t\t\t\tcolors: this.colors,\n\t\t\t\t\tcolumns: 10,\n\t\t\t\t\tresetLabel: this.locale.resetLabel,\n\t\t\t\t\tresetCommand: 'removeTextColor',\n\t\t\t\t\tariaLabelPrefix: this.locale.ariaLabelPrefix,\n\t\t\t\t\tonClose,\n\t\t\t\t});\n\t\t\t},\n\t\t\tisActive: (state: EditorState) => isColorMarkActive(state, 'textColor'),\n\t\t});\n\t}\n}\n"],"mappings":"iRAeA,IAAa,EAAwC,CACpD,MAAO,aACP,QAAS,aACT,WAAY,UACZ,gBAAiB,cAKZ,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,EAC9C,CC1BA,IAAa,EAAmC,CAE/C,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,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WCtCY,EAAb,MACC,GAAc,YACd,KAAgB,aAChB,SAAoB,GAEpB,OACA,OACA,OAEA,WAAA,CAAY,GACX,KAAK,OAAS,IAAK,GACnB,KAAK,OAAS,EAAc,GAAQ,OAAQ,EAAe,kBAC5D,CAEA,UAAM,CAAK,GACV,KAAK,aAAe,EACnB,EACA,KAAK,OAAO,OACZ,EACA,GAGD,EAAQ,mBAAmB,GAC3B,KAAK,iBAAiB,GACtB,KAAK,iBAAiB,GACtB,KAAK,oBAAoB,EAC1B,CAEA,gBAAA,CAAyB,GACxB,EAAQ,iBACP,EAA0B,CACzB,KAAM,YACN,KAAM,EACN,UAAW,QACX,iBAAkB,QAClB,YAAa,QACb,SAAU,EACV,iBAAiB,IAGpB,CAEA,gBAAA,CAAyB,GACxB,EAAQ,gBAAgB,kBAAA,IAChB,EAAgB,EAAS,EAAQ,WAAY,aAEtD,CAEA,mBAAA,CAA4B,GAG3B,MAAM,EAAe,CACpB,0CACA,wBACA,gGACA,6CACA,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,cAE7D"}
1
+ {"version":3,"file":"TextColorPlugin-CTd9tfeG.mjs","names":[],"sources":["../../src/plugins/text-color/TextColorLocale.ts","../../src/plugins/text-color/TextColorPalette.ts","../../src/plugins/text-color/TextColorPlugin.ts"],"sourcesContent":["/** Locale interface and default English locale for the TextColorPlugin. */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface TextColorLocale {\n\treadonly label: string;\n\treadonly tooltip: string;\n\treadonly resetLabel: string;\n\treadonly ariaLabelPrefix: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_COLOR_LOCALE_EN: TextColorLocale = {\n\tlabel: 'Text Color',\n\ttooltip: 'Text Color',\n\tresetLabel: 'Default',\n\tariaLabelPrefix: 'Text color',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<TextColorLocale> = import.meta.glob<{\n\tdefault: TextColorLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadTextColorLocale(lang: string): Promise<TextColorLocale> {\n\treturn loadLocaleModule(localeModules, lang, TEXT_COLOR_LOCALE_EN);\n}\n","/**\n * Default text-color palette (Google Docs style: 10 columns x 7 rows).\n * Used by TextColorPlugin when no `colors` override is provided.\n */\nexport const COLOR_PALETTE: readonly string[] = [\n\t// Row 1 — dark\n\t'#000000',\n\t'#434343',\n\t'#666666',\n\t'#999999',\n\t'#b7b7b7',\n\t'#cccccc',\n\t'#d9d9d9',\n\t'#efefef',\n\t'#f3f3f3',\n\t'#ffffff',\n\t// Row 2 — vivid\n\t'#980000',\n\t'#ff0000',\n\t'#ff9900',\n\t'#ffff00',\n\t'#00ff00',\n\t'#00ffff',\n\t'#4a86e8',\n\t'#0000ff',\n\t'#9900ff',\n\t'#ff00ff',\n\t// Row 3 — light 3\n\t'#e6b8af',\n\t'#f4cccc',\n\t'#fce5cd',\n\t'#fff2cc',\n\t'#d9ead3',\n\t'#d0e0e3',\n\t'#c9daf8',\n\t'#cfe2f3',\n\t'#d9d2e9',\n\t'#ead1dc',\n\t// Row 4 — light 2\n\t'#dd7e6b',\n\t'#ea9999',\n\t'#f9cb9c',\n\t'#ffe599',\n\t'#b6d7a8',\n\t'#a2c4c9',\n\t'#a4c2f4',\n\t'#9fc5e8',\n\t'#b4a7d6',\n\t'#d5a6bd',\n\t// Row 5 — light 1\n\t'#cc4125',\n\t'#e06666',\n\t'#f6b26b',\n\t'#ffd966',\n\t'#93c47d',\n\t'#76a5af',\n\t'#6d9eeb',\n\t'#6fa8dc',\n\t'#8e7cc3',\n\t'#c27ba0',\n\t// Row 6 — dark 1\n\t'#a61c00',\n\t'#cc0000',\n\t'#e69138',\n\t'#f1c232',\n\t'#6aa84f',\n\t'#45818e',\n\t'#3c78d8',\n\t'#3d85c6',\n\t'#674ea7',\n\t'#a64d79',\n\t// Row 7 — dark 2\n\t'#85200c',\n\t'#990000',\n\t'#b45f06',\n\t'#bf9000',\n\t'#38761d',\n\t'#134f5c',\n\t'#1155cc',\n\t'#0b5394',\n\t'#351c75',\n\t'#741b47',\n];\n","/**\n * TextColorPlugin: registers a text color mark with attrs,\n * toolbar button with a color picker popup, and removeTextColor command.\n */\n\nimport { COLOR_PICKER_CSS } from '../../editor/styles/color-picker.js';\nimport 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\tTEXT_COLOR_LOCALE_EN,\n\ttype TextColorLocale,\n\tloadTextColorLocale,\n} from './TextColorLocale.js';\nimport { COLOR_PALETTE } from './TextColorPalette.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\ttextColor: { color: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface TextColorConfig {\n\t/**\n\t * Restricts the color picker to a specific set of hex colors.\n\t * Each value must be a valid hex color code (`#RGB` or `#RRGGBB`).\n\t * Duplicates are removed automatically (case-insensitive).\n\t * When omitted, the full default palette is shown.\n\t */\n\treadonly colors?: readonly string[];\n\treadonly locale?: TextColorLocale;\n}\n\n// --- Plugin ---\n\nexport class TextColorPlugin implements Plugin {\n\treadonly id = 'textColor';\n\treadonly name = 'Text Color';\n\treadonly priority = 23;\n\n\tprivate readonly config: TextColorConfig;\n\tprivate readonly colors: readonly string[];\n\tprivate locale!: TextColorLocale;\n\n\tconstructor(config?: Partial<TextColorConfig>) {\n\t\tthis.config = { ...config };\n\t\tthis.colors = resolveColors(config?.colors, COLOR_PALETTE, 'TextColorPlugin');\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tTEXT_COLOR_LOCALE_EN,\n\t\t\tloadTextColorLocale,\n\t\t);\n\n\t\tcontext.registerStyleSheet(COLOR_PICKER_CSS);\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec(\n\t\t\tcreateInlineStyleMarkSpec({\n\t\t\t\ttype: 'textColor',\n\t\t\t\trank: 5,\n\t\t\t\tvalueAttr: 'color',\n\t\t\t\tdomStyleProperty: 'color',\n\t\t\t\tcssProperty: '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('removeTextColor', () => {\n\t\t\treturn removeColorMark(context, context.getState(), 'textColor');\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst pathD =\n\t\t\t'M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2z' + 'm-1.38 9L12 5.67 14.38 12H9.62z';\n\t\tconst icon: string = [\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\"',\n\t\t\t' viewBox=\"0 0 24 24\">',\n\t\t\t`<path d=\"${pathD}\"/>`,\n\t\t\t'<rect x=\"3\" y=\"19.5\" width=\"18\" height=\"3\"',\n\t\t\t' rx=\"0.5\" fill=\"#e53935\"/>',\n\t\t\t'</svg>',\n\t\t].join('');\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'textColor',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: this.locale.label,\n\t\t\ttooltip: this.locale.tooltip,\n\t\t\tcommand: 'removeTextColor',\n\t\t\tpopupType: 'custom',\n\t\t\trenderPopup: (container, ctx, onClose) => {\n\t\t\t\trenderColorPickerPopup(container, ctx, {\n\t\t\t\t\tmarkType: 'textColor',\n\t\t\t\t\tcolors: this.colors,\n\t\t\t\t\tcolumns: 10,\n\t\t\t\t\tresetLabel: this.locale.resetLabel,\n\t\t\t\t\tresetCommand: 'removeTextColor',\n\t\t\t\t\tariaLabelPrefix: this.locale.ariaLabelPrefix,\n\t\t\t\t\tonClose,\n\t\t\t\t});\n\t\t\t},\n\t\t\tisActive: (state: EditorState) => isColorMarkActive(state, 'textColor'),\n\t\t});\n\t}\n}\n"],"mappings":"sRAeA,IAAa,EAAwC,CACpD,MAAO,aACP,QAAS,aACT,WAAY,UACZ,gBAAiB,cAKZ,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,EAC9C,CC1BA,IAAa,EAAmC,CAE/C,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,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UAEA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,UACA,WCtCY,EAAb,MACC,GAAc,YACd,KAAgB,aAChB,SAAoB,GAEpB,OACA,OACA,OAEA,WAAA,CAAY,GACX,KAAK,OAAS,IAAK,GACnB,KAAK,OAAS,EAAc,GAAQ,OAAQ,EAAe,kBAC5D,CAEA,UAAM,CAAK,GACV,KAAK,aAAe,EACnB,EACA,KAAK,OAAO,OACZ,EACA,GAGD,EAAQ,mBAAmB,GAC3B,KAAK,iBAAiB,GACtB,KAAK,iBAAiB,GACtB,KAAK,oBAAoB,EAC1B,CAEA,gBAAA,CAAyB,GACxB,EAAQ,iBACP,EAA0B,CACzB,KAAM,YACN,KAAM,EACN,UAAW,QACX,iBAAkB,QAClB,YAAa,QACb,SAAU,EACV,iBAAiB,IAGpB,CAEA,gBAAA,CAAyB,GACxB,EAAQ,gBAAgB,kBAAA,IAChB,EAAgB,EAAS,EAAQ,WAAY,aAEtD,CAEA,mBAAA,CAA4B,GAG3B,MAAM,EAAe,CACpB,0CACA,wBACA,gGACA,6CACA,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,cAE7D"}
@@ -0,0 +1,2 @@
1
+ import{_ as t,h as e,i as r}from"./Document-827l3P80.mjs";import{t as i}from"./TextDirectionService-BcX07mw2.mjs";import{n,r as o,t as s}from"./DirectionDetection-CDVSEWQ6.mjs";function c(t,e,r){const i=t.getNodePath(e.id);if(i)return{type:"setNodeAttr",path:i,attrs:{...e.attrs,dir:r},previousAttrs:e.attrs}}function a(i,n,a,d){const u=n.getBlock(i.blockId);if(!u||!a.has(u.type))return;if("auto"!==o(u)&&e(u)>0)return;const f=t(u),p=r(u,i.offset),l=s(f.slice(0,p)+i.text+f.slice(p));if(!l)return;const h=c(n,u,l);h&&d.push(h)}function d(e,i,n,a){const d=i.getBlock(e.blockId);if(!d||!n.has(d.type))return;const u=o(d);if("auto"===u)return;const f=t(d),p=r(d,e.from),l=r(d,e.to),h=f.slice(0,p)+f.slice(l);if(0===h.length){const t=c(i,d,"auto");return void(t&&a.push(t))}const g=s(h);if(!g||g===u)return;const m=c(i,d,g);m&&a.push(m)}var u={autoDetect:!0,inherit:!0,preserve:!0},f=class{id="text-direction-auto";name="Text Direction Auto-detect";priority=93;dependencies=["text-direction"];config;constructor(t){this.config={...u,...t}}init(e){const r=e.getService(i);if(!r)throw new Error("TextDirectionAutoPlugin requires TextDirectionPlugin to be registered first.");const{directableTypes:o}=r;this.config.preserve&&function(t,e){t.registerMiddleware((t,r,i)=>{let n=!1;const o=t.steps.map(t=>{if("setBlockType"!==t.type)return t;if(!e.has(t.nodeType))return t;const r=t.previousAttrs?.dir;return r&&"auto"!==r?(n=!0,{...t,attrs:{...t.attrs,dir:r}}):t});i(n?{...t,steps:o}:t)},{name:"text-direction:preserve-dir"})}(e,o),this.config.autoDetect&&function(t,e){t.registerMiddleware((t,r,i)=>{const n=function(t){const e=/* @__PURE__ */new Set;for(const r of t)if("setBlockType"===r.type)e.add(r.blockId);else if("setNodeAttr"===r.type){const t=r.path[r.path.length-1];t&&e.add(t)}return e}(t.steps),o=[];for(const s of t.steps)if("insertText"===s.type){if(n.has(s.blockId))continue;a(s,r,e,o)}else if("deleteText"===s.type){if(n.has(s.blockId))continue;d(s,r,e,o)}i(o.length>0?{...t,steps:[...t.steps,...o]}:t)},{name:"text-direction:auto-detect"})}(e,o),this.config.inherit&&function(e,r){e.registerMiddleware((e,i,o)=>{let c=!1;const a=e.steps.map(e=>{if("insertNode"!==e.type)return e;if(!r.has(e.node.type))return e;if("auto"!==String(e.node.attrs?.dir??"auto"))return e;const o=t(e.node);if(o.length>0){const t=s(o);if(t)return c=!0,{...e,node:{...e.node,attrs:{...e.node.attrs,dir:t}}}}const a=n(i,e.parentPath,e.index);return a&&"auto"!==a?(c=!0,{...e,node:{...e.node,attrs:{...e.node.attrs,dir:a}}}):e});o(c?{...e,steps:a}:e)},{name:"text-direction:inherit-dir"})}(e,o)}};export{f as t};
2
+ //# sourceMappingURL=TextDirectionAutoPlugin-CPnKVVuI.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextDirectionAutoPlugin-CzWJjrvG.mjs","names":[],"sources":["../../src/plugins/text-direction-auto/TextDirectionAutoMiddleware.ts","../../src/plugins/text-direction-auto/TextDirectionAutoPlugin.ts"],"sourcesContent":["/**\n * Middleware registrations for the TextDirectionAutoPlugin.\n *\n * Three independent middlewares that all operate on the block-level `dir`\n * attribute owned by the {@link TextDirectionPlugin}:\n *\n * - **preserveDir**: keeps `dir` when another plugin replaces a block's\n * attrs (e.g. `setBlockType` paragraph → heading).\n * - **autoDetect**: on `insertText` / `deleteText`, detects direction from\n * the first strong directional character and updates `dir`.\n * - **inheritDir**: on `insertNode`, inherits the new block's `dir` from\n * the nearest sibling (or auto-detects from inserted text content).\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { blockOffsetToTextOffset, getBlockLength, getBlockText } from '../../model/Document.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Step } from '../../state/Transaction.js';\nimport type { PluginContext } from '../Plugin.js';\nimport {\n\tdetectTextDirection,\n\tfindSiblingDirection,\n\tgetBlockDir,\n} from '../text-direction/DirectionDetection.js';\nimport type { TextDirection } from '../text-direction/TextDirectionService.js';\n\nexport function registerPreserveDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, _state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'setBlockType') return step;\n\t\t\t\tif (!directableTypes.has(step.nodeType)) return step;\n\n\t\t\t\tconst prevDir = step.previousAttrs?.dir;\n\t\t\t\tif (!prevDir || prevDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tattrs: { ...step.attrs, dir: prevDir },\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:preserve-dir' },\n\t);\n}\n\nexport function registerAutoDetectMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tconst attrTouched: ReadonlySet<string> = collectAttrTouchedBlocks(tr.steps);\n\t\t\tconst extraSteps: Step[] = [];\n\n\t\t\tfor (const step of tr.steps) {\n\t\t\t\tif (step.type === 'insertText') {\n\t\t\t\t\tif (attrTouched.has(step.blockId)) continue;\n\t\t\t\t\thandleInsertText(step, state, directableTypes, extraSteps);\n\t\t\t\t} else if (step.type === 'deleteText') {\n\t\t\t\t\tif (attrTouched.has(step.blockId)) continue;\n\t\t\t\t\thandleDeleteText(step, state, directableTypes, extraSteps);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (extraSteps.length > 0) {\n\t\t\t\tnext({ ...tr, steps: [...tr.steps, ...extraSteps] });\n\t\t\t} else {\n\t\t\t\tnext(tr);\n\t\t\t}\n\t\t},\n\t\t{ name: 'text-direction:auto-detect' },\n\t);\n}\n\n/**\n * Collects IDs of blocks whose attrs are already mutated by `setBlockType`\n * or `setNodeAttr` steps in the transaction. The auto-detect pass must skip\n * these blocks: its `setNodeAttr` is built from a pre-transaction snapshot\n * and would clobber freshly written attrs (full-replace step semantics).\n */\nfunction collectAttrTouchedBlocks(steps: readonly Step[]): ReadonlySet<string> {\n\tconst touched: Set<string> = new Set();\n\tfor (const step of steps) {\n\t\tif (step.type === 'setBlockType') {\n\t\t\ttouched.add(step.blockId);\n\t\t} else if (step.type === 'setNodeAttr') {\n\t\t\tconst blockId: string | undefined = step.path[step.path.length - 1];\n\t\t\tif (blockId) touched.add(blockId);\n\t\t}\n\t}\n\treturn touched;\n}\n\nfunction buildDirChangeStep(\n\tstate: EditorState,\n\tblock: BlockNode,\n\tdir: TextDirection | 'auto',\n): Step | undefined {\n\tconst path = state.getNodePath(block.id);\n\tif (!path) return undefined;\n\n\treturn {\n\t\ttype: 'setNodeAttr',\n\t\tpath,\n\t\tattrs: { ...block.attrs, dir },\n\t\tpreviousAttrs: block.attrs,\n\t};\n}\n\nfunction handleInsertText(\n\tstep: Extract<Step, { type: 'insertText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tif (getBlockDir(block) !== 'auto' && getBlockLength(block) > 0) return;\n\n\tconst existingText: string = getBlockText(block);\n\tconst textOffset: number = blockOffsetToTextOffset(block, step.offset);\n\tconst textAfter: string =\n\t\texistingText.slice(0, textOffset) + step.text + existingText.slice(textOffset);\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\nfunction handleDeleteText(\n\tstep: Extract<Step, { type: 'deleteText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tconst currentDir: TextDirection = getBlockDir(block);\n\tif (currentDir === 'auto') return;\n\n\tconst existingText: string = getBlockText(block);\n\tconst fromText: number = blockOffsetToTextOffset(block, step.from);\n\tconst toText: number = blockOffsetToTextOffset(block, step.to);\n\tconst textAfter: string = existingText.slice(0, fromText) + existingText.slice(toText);\n\n\tif (textAfter.length === 0) {\n\t\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, 'auto');\n\t\tif (dirStep) extraSteps.push(dirStep);\n\t\treturn;\n\t}\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected || detected === currentDir) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\nexport function registerInheritDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'insertNode') return step;\n\t\t\t\tif (!directableTypes.has(step.node.type)) return step;\n\n\t\t\t\tconst newDir: string = String(step.node.attrs?.dir ?? 'auto');\n\t\t\t\tif (newDir !== 'auto') return step;\n\n\t\t\t\tconst nodeText: string = getBlockText(step.node);\n\t\t\t\tif (nodeText.length > 0) {\n\t\t\t\t\tconst detected: TextDirection | null = detectTextDirection(nodeText);\n\t\t\t\t\tif (detected) {\n\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...step,\n\t\t\t\t\t\t\tnode: {\n\t\t\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: detected },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst siblingDir: string | undefined = findSiblingDirection(\n\t\t\t\t\tstate,\n\t\t\t\t\tstep.parentPath,\n\t\t\t\t\tstep.index,\n\t\t\t\t);\n\t\t\t\tif (!siblingDir || siblingDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tnode: {\n\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: siblingDir },\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:inherit-dir' },\n\t);\n}\n","/**\n * Text direction auto-detection / inheritance / preservation plugin.\n *\n * Registers three transaction middlewares that keep block-level `dir`\n * attributes in sync with content changes. Strictly requires\n * {@link TextDirectionPlugin} (declared via `dependencies`) — without it,\n * the patched `dir` attribute does not exist on NodeSpecs and the\n * `directableTypes` service is unavailable.\n */\n\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { TEXT_DIRECTION_SERVICE_KEY } from '../text-direction/TextDirectionService.js';\nimport {\n\tregisterAutoDetectMiddleware,\n\tregisterInheritDirMiddleware,\n\tregisterPreserveDirMiddleware,\n} from './TextDirectionAutoMiddleware.js';\n\nexport interface TextDirectionAutoConfig {\n\t/**\n\t * Whether to register the auto-detect middleware (insertText / deleteText).\n\t * @default true\n\t */\n\treadonly autoDetect?: boolean;\n\t/**\n\t * Whether to register the inherit-dir middleware (insertNode).\n\t * @default true\n\t */\n\treadonly inherit?: boolean;\n\t/**\n\t * Whether to register the preserve-dir middleware (setBlockType).\n\t * @default true\n\t */\n\treadonly preserve?: boolean;\n}\n\nconst DEFAULT_CONFIG: Required<TextDirectionAutoConfig> = {\n\tautoDetect: true,\n\tinherit: true,\n\tpreserve: true,\n};\n\nexport class TextDirectionAutoPlugin implements Plugin {\n\treadonly id = 'text-direction-auto';\n\treadonly name = 'Text Direction Auto-detect';\n\treadonly priority = 93;\n\treadonly dependencies = ['text-direction'] as const;\n\n\tprivate readonly config: Required<TextDirectionAutoConfig>;\n\n\tconstructor(config?: TextDirectionAutoConfig) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tconst service = context.getService(TEXT_DIRECTION_SERVICE_KEY);\n\t\tif (!service) {\n\t\t\tthrow new Error(\n\t\t\t\t'TextDirectionAutoPlugin requires TextDirectionPlugin to be registered first.',\n\t\t\t);\n\t\t}\n\n\t\tconst { directableTypes } = service;\n\n\t\tif (this.config.preserve) {\n\t\t\tregisterPreserveDirMiddleware(context, directableTypes);\n\t\t}\n\t\tif (this.config.autoDetect) {\n\t\t\tregisterAutoDetectMiddleware(context, directableTypes);\n\t\t}\n\t\tif (this.config.inherit) {\n\t\t\tregisterInheritDirMiddleware(context, directableTypes);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TextDirectionAutoPlugin-CPnKVVuI.mjs","names":[],"sources":["../../src/plugins/text-direction-auto/TextDirectionAutoMiddleware.ts","../../src/plugins/text-direction-auto/TextDirectionAutoPlugin.ts"],"sourcesContent":["/**\n * Middleware registrations for the TextDirectionAutoPlugin.\n *\n * Three independent middlewares that all operate on the block-level `dir`\n * attribute owned by the {@link TextDirectionPlugin}:\n *\n * - **preserveDir**: keeps `dir` when another plugin replaces a block's\n * attrs (e.g. `setBlockType` paragraph → heading).\n * - **autoDetect**: on `insertText` / `deleteText`, detects direction from\n * the first strong directional character and updates `dir`.\n * - **inheritDir**: on `insertNode`, inherits the new block's `dir` from\n * the nearest sibling (or auto-detects from inserted text content).\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { blockOffsetToTextOffset, getBlockLength, getBlockText } from '../../model/Document.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Step } from '../../state/Transaction.js';\nimport type { PluginContext } from '../Plugin.js';\nimport {\n\tdetectTextDirection,\n\tfindSiblingDirection,\n\tgetBlockDir,\n} from '../text-direction/DirectionDetection.js';\nimport type { TextDirection } from '../text-direction/TextDirectionService.js';\n\nexport function registerPreserveDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, _state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'setBlockType') return step;\n\t\t\t\tif (!directableTypes.has(step.nodeType)) return step;\n\n\t\t\t\tconst prevDir = step.previousAttrs?.dir;\n\t\t\t\tif (!prevDir || prevDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tattrs: { ...step.attrs, dir: prevDir },\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:preserve-dir' },\n\t);\n}\n\nexport function registerAutoDetectMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tconst attrTouched: ReadonlySet<string> = collectAttrTouchedBlocks(tr.steps);\n\t\t\tconst extraSteps: Step[] = [];\n\n\t\t\tfor (const step of tr.steps) {\n\t\t\t\tif (step.type === 'insertText') {\n\t\t\t\t\tif (attrTouched.has(step.blockId)) continue;\n\t\t\t\t\thandleInsertText(step, state, directableTypes, extraSteps);\n\t\t\t\t} else if (step.type === 'deleteText') {\n\t\t\t\t\tif (attrTouched.has(step.blockId)) continue;\n\t\t\t\t\thandleDeleteText(step, state, directableTypes, extraSteps);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (extraSteps.length > 0) {\n\t\t\t\tnext({ ...tr, steps: [...tr.steps, ...extraSteps] });\n\t\t\t} else {\n\t\t\t\tnext(tr);\n\t\t\t}\n\t\t},\n\t\t{ name: 'text-direction:auto-detect' },\n\t);\n}\n\n/**\n * Collects IDs of blocks whose attrs are already mutated by `setBlockType`\n * or `setNodeAttr` steps in the transaction. The auto-detect pass must skip\n * these blocks: its `setNodeAttr` is built from a pre-transaction snapshot\n * and would clobber freshly written attrs (full-replace step semantics).\n */\nfunction collectAttrTouchedBlocks(steps: readonly Step[]): ReadonlySet<string> {\n\tconst touched: Set<string> = new Set();\n\tfor (const step of steps) {\n\t\tif (step.type === 'setBlockType') {\n\t\t\ttouched.add(step.blockId);\n\t\t} else if (step.type === 'setNodeAttr') {\n\t\t\tconst blockId: string | undefined = step.path[step.path.length - 1];\n\t\t\tif (blockId) touched.add(blockId);\n\t\t}\n\t}\n\treturn touched;\n}\n\nfunction buildDirChangeStep(\n\tstate: EditorState,\n\tblock: BlockNode,\n\tdir: TextDirection | 'auto',\n): Step | undefined {\n\tconst path = state.getNodePath(block.id);\n\tif (!path) return undefined;\n\n\treturn {\n\t\ttype: 'setNodeAttr',\n\t\tpath,\n\t\tattrs: { ...block.attrs, dir },\n\t\tpreviousAttrs: block.attrs,\n\t};\n}\n\nfunction handleInsertText(\n\tstep: Extract<Step, { type: 'insertText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tif (getBlockDir(block) !== 'auto' && getBlockLength(block) > 0) return;\n\n\tconst existingText: string = getBlockText(block);\n\tconst textOffset: number = blockOffsetToTextOffset(block, step.offset);\n\tconst textAfter: string =\n\t\texistingText.slice(0, textOffset) + step.text + existingText.slice(textOffset);\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\nfunction handleDeleteText(\n\tstep: Extract<Step, { type: 'deleteText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tconst currentDir: TextDirection = getBlockDir(block);\n\tif (currentDir === 'auto') return;\n\n\tconst existingText: string = getBlockText(block);\n\tconst fromText: number = blockOffsetToTextOffset(block, step.from);\n\tconst toText: number = blockOffsetToTextOffset(block, step.to);\n\tconst textAfter: string = existingText.slice(0, fromText) + existingText.slice(toText);\n\n\tif (textAfter.length === 0) {\n\t\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, 'auto');\n\t\tif (dirStep) extraSteps.push(dirStep);\n\t\treturn;\n\t}\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected || detected === currentDir) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\nexport function registerInheritDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'insertNode') return step;\n\t\t\t\tif (!directableTypes.has(step.node.type)) return step;\n\n\t\t\t\tconst newDir: string = String(step.node.attrs?.dir ?? 'auto');\n\t\t\t\tif (newDir !== 'auto') return step;\n\n\t\t\t\tconst nodeText: string = getBlockText(step.node);\n\t\t\t\tif (nodeText.length > 0) {\n\t\t\t\t\tconst detected: TextDirection | null = detectTextDirection(nodeText);\n\t\t\t\t\tif (detected) {\n\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...step,\n\t\t\t\t\t\t\tnode: {\n\t\t\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: detected },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst siblingDir: string | undefined = findSiblingDirection(\n\t\t\t\t\tstate,\n\t\t\t\t\tstep.parentPath,\n\t\t\t\t\tstep.index,\n\t\t\t\t);\n\t\t\t\tif (!siblingDir || siblingDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tnode: {\n\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: siblingDir },\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:inherit-dir' },\n\t);\n}\n","/**\n * Text direction auto-detection / inheritance / preservation plugin.\n *\n * Registers three transaction middlewares that keep block-level `dir`\n * attributes in sync with content changes. Strictly requires\n * {@link TextDirectionPlugin} (declared via `dependencies`) — without it,\n * the patched `dir` attribute does not exist on NodeSpecs and the\n * `directableTypes` service is unavailable.\n */\n\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { TEXT_DIRECTION_SERVICE_KEY } from '../text-direction/TextDirectionService.js';\nimport {\n\tregisterAutoDetectMiddleware,\n\tregisterInheritDirMiddleware,\n\tregisterPreserveDirMiddleware,\n} from './TextDirectionAutoMiddleware.js';\n\nexport interface TextDirectionAutoConfig {\n\t/**\n\t * Whether to register the auto-detect middleware (insertText / deleteText).\n\t * @default true\n\t */\n\treadonly autoDetect?: boolean;\n\t/**\n\t * Whether to register the inherit-dir middleware (insertNode).\n\t * @default true\n\t */\n\treadonly inherit?: boolean;\n\t/**\n\t * Whether to register the preserve-dir middleware (setBlockType).\n\t * @default true\n\t */\n\treadonly preserve?: boolean;\n}\n\nconst DEFAULT_CONFIG: Required<TextDirectionAutoConfig> = {\n\tautoDetect: true,\n\tinherit: true,\n\tpreserve: true,\n};\n\nexport class TextDirectionAutoPlugin implements Plugin {\n\treadonly id = 'text-direction-auto';\n\treadonly name = 'Text Direction Auto-detect';\n\treadonly priority = 93;\n\treadonly dependencies = ['text-direction'] as const;\n\n\tprivate readonly config: Required<TextDirectionAutoConfig>;\n\n\tconstructor(config?: TextDirectionAutoConfig) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tconst service = context.getService(TEXT_DIRECTION_SERVICE_KEY);\n\t\tif (!service) {\n\t\t\tthrow new Error(\n\t\t\t\t'TextDirectionAutoPlugin requires TextDirectionPlugin to be registered first.',\n\t\t\t);\n\t\t}\n\n\t\tconst { directableTypes } = service;\n\n\t\tif (this.config.preserve) {\n\t\t\tregisterPreserveDirMiddleware(context, directableTypes);\n\t\t}\n\t\tif (this.config.autoDetect) {\n\t\t\tregisterAutoDetectMiddleware(context, directableTypes);\n\t\t}\n\t\tif (this.config.inherit) {\n\t\t\tregisterInheritDirMiddleware(context, directableTypes);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{r as t}from"./Platform-ByobkiCc.mjs";import{a as e,c as i,n as o,o as r,r as s}from"./PluginHelpers-KDuTlmXm.mjs";import{t as n}from"./ShortcutFormatting-TwiufqeV.mjs";import{t as a}from"./NodeSpecPatching-B_yLknTl.mjs";import{t as c}from"./DirectionIcons-Bbawl9ei.mjs";import{t as l}from"./TextDirectionService-OFOU6r_s.mjs";import{r as h}from"./DirectionDetection-C7XE0nxW.mjs";var u=class{context;pendingDir=null;container=null;constructor(t){this.context=t}attach(t){this.container=t,t.addEventListener("keydown",this.onKeydown),t.addEventListener("keyup",this.onKeyup)}detach(){this.container&&(this.container.removeEventListener("keydown",this.onKeydown),this.container.removeEventListener("keyup",this.onKeyup),this.container=null)}onKeydown=t=>{"Shift"!==t.key||!t.ctrlKey||t.altKey||t.metaKey?this.pendingDir=null:"ShiftLeft"===t.code?this.pendingDir="ltr":"ShiftRight"===t.code&&(this.pendingDir="rtl")};onKeyup=t=>{if("Shift"!==t.key||!this.pendingDir)return;const e=this.pendingDir;this.pendingDir=null;const i="ltr"===e?"setDirectionLTR":"setDirectionRTL";this.context.executeCommand(i)}},m={ltr:"Left to Right",rtl:"Right to Left",auto:"Auto",toolbarLabel:"Text Direction",toolbarTooltip:"Text Direction",announceLTR:"Text direction set to left-to-right",announceRTL:"Text direction set to right-to-left",announceAuto:"Text direction set to automatic"},d=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-BwaoCUVN.mjs"),"./locales/de.ts":()=>import("./de-BdD3DpUB.mjs"),"./locales/es.ts":()=>import("./es-kfKiqpyD.mjs"),"./locales/fr.ts":()=>import("./fr-BSUKEtTk.mjs"),"./locales/hi.ts":()=>import("./hi-Dt89SxNy.mjs"),"./locales/pt.ts":()=>import("./pt-CMrFpUWS.mjs"),"./locales/ru.ts":()=>import("./ru-C9yFslEG.mjs"),"./locales/zh.ts":()=>import("./zh-CnW44JEw.mjs")});async function p(t){return i(d,t,m)}var g={directableTypes:["paragraph","heading","title","subtitle","table_cell","blockquote","list_item"]},D=["ltr","rtl","auto"],f=class{id="text-direction";name="Text Direction";priority=91;config;locale;directableTypes;shiftDirHandler=null;constructor(t){this.config={...g,...t}}async init(e){this.locale=await r(e,this.config.locale,m,p),this.directableTypes=new Set(this.config.directableTypes),this.patchNodeSpecs(e),this.registerCommands(e),this.registerKeymaps(e),this.registerToolbarItem(e),this.registerService(e),t()||(this.shiftDirHandler=new u(e),this.shiftDirHandler.attach(e.getContainer()))}destroy(){this.shiftDirHandler?.detach(),this.shiftDirHandler=null}registerService(t){const e={directableTypes:this.directableTypes,getBlockDir:h};t.registerService(l,e)}patchNodeSpecs(t){a(t.getSchemaRegistry(),this.config.directableTypes,{attrName:"dir",getDefault:()=>"auto",applyToDOM:y})}registerCommands(t){t.registerCommand("setDirectionLTR",()=>{const e=this.setDirection(t,"ltr");return e&&t.announce(this.locale.announceLTR),e}),t.registerCommand("setDirectionRTL",()=>{const e=this.setDirection(t,"rtl");return e&&t.announce(this.locale.announceRTL),e}),t.registerCommand("setDirectionAuto",()=>{const e=this.setDirection(t,"auto");return e&&t.announce(this.locale.announceAuto),e}),t.registerCommand("toggleDirection",()=>{const e=s(t.getState());if(!e||!this.directableTypes.has(e.type))return!1;const i=h(e),o="auto"===i?"rtl":"rtl"===i?"ltr":"auto";return this.setDirection(t,o)})}registerKeymaps(t){t.registerKeymap({"Mod-Shift-D":()=>t.executeCommand("toggleDirection")})}registerToolbarItem(t){const e={ltr:"setDirectionLTR",rtl:"setDirectionRTL",auto:"setDirectionAuto"},i=D.map(t=>({label:this.getDirectionLabel(t),command:e[t],icon:c[t]}));t.registerToolbarItem({id:"text-direction",group:"block",icon:c.auto,label:this.locale.toolbarLabel,tooltip:`${this.locale.toolbarTooltip} (${n("Mod-Shift-D")})`,command:"setDirectionAuto",popupType:"dropdown",popupConfig:{items:i},isActive:t=>this.isNonDefaultDirection(t),isEnabled:t=>this.isDirectable(t),getIcon:t=>{const e=s(t);return e?c[h(e)]??c.auto:c.auto}})}getDirectionLabel(t){return"ltr"===t?this.locale.ltr:"rtl"===t?this.locale.rtl:this.locale.auto}setDirection(t,i){const r=t.getState(),s=e(r);if(0===s.length)return!1;const n=r.transaction("command");let a=!1;for(const e of s){const t=r.getBlock(e);if(!t||!this.directableTypes.has(t.type))continue;const o=r.getNodePath(e);o&&(n.setNodeAttr(o,{...t.attrs,dir:i}),a=!0)}return!!a&&o(t,n.setSelection(r.selection).build())}isNonDefaultDirection(t){const e=s(t);if(!e||!this.directableTypes.has(e.type))return!1;const i=e.attrs?.dir;return null!=i&&"auto"!==i}isDirectable(t){const e=s(t);return null!=e&&this.directableTypes.has(e.type)}};function y(t,e){const i=e.attrs?.dir;"ltr"!==i&&"rtl"!==i&&"auto"!==i||t.setAttribute("dir",i)}export{m as n,p as r,f as t};
2
- //# sourceMappingURL=TextDirectionPlugin-DHB88HKf.mjs.map
1
+ import{r as t}from"./Platform-ByobkiCc.mjs";import{a as e,c as i,n as o,o as r,r as s}from"./PluginHelpers-Dx_0hfDe.mjs";import{t as n}from"./ShortcutFormatting-TwiufqeV.mjs";import{t as a}from"./NodeSpecPatching-B_yLknTl.mjs";import{t as c}from"./DirectionIcons-Bbawl9ei.mjs";import{t as l}from"./TextDirectionService-BcX07mw2.mjs";import{r as h}from"./DirectionDetection-CDVSEWQ6.mjs";var u=class{context;pendingDir=null;container=null;constructor(t){this.context=t}attach(t){this.container=t,t.addEventListener("keydown",this.onKeydown),t.addEventListener("keyup",this.onKeyup)}detach(){this.container&&(this.container.removeEventListener("keydown",this.onKeydown),this.container.removeEventListener("keyup",this.onKeyup),this.container=null)}onKeydown=t=>{"Shift"!==t.key||!t.ctrlKey||t.altKey||t.metaKey?this.pendingDir=null:"ShiftLeft"===t.code?this.pendingDir="ltr":"ShiftRight"===t.code&&(this.pendingDir="rtl")};onKeyup=t=>{if("Shift"!==t.key||!this.pendingDir)return;const e=this.pendingDir;this.pendingDir=null;const i="ltr"===e?"setDirectionLTR":"setDirectionRTL";this.context.executeCommand(i)}},m={ltr:"Left to Right",rtl:"Right to Left",auto:"Auto",toolbarLabel:"Text Direction",toolbarTooltip:"Text Direction",announceLTR:"Text direction set to left-to-right",announceRTL:"Text direction set to right-to-left",announceAuto:"Text direction set to automatic"},d=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-BwaoCUVN.mjs"),"./locales/de.ts":()=>import("./de-BdD3DpUB.mjs"),"./locales/es.ts":()=>import("./es-kfKiqpyD.mjs"),"./locales/fr.ts":()=>import("./fr-BSUKEtTk.mjs"),"./locales/hi.ts":()=>import("./hi-Dt89SxNy.mjs"),"./locales/pt.ts":()=>import("./pt-CMrFpUWS.mjs"),"./locales/ru.ts":()=>import("./ru-C9yFslEG.mjs"),"./locales/zh.ts":()=>import("./zh-CnW44JEw.mjs")});async function p(t){return i(d,t,m)}var g={directableTypes:["paragraph","heading","title","subtitle","table_cell","blockquote","list_item"]},D=["ltr","rtl","auto"],f=class{id="text-direction";name="Text Direction";priority=91;config;locale;directableTypes;shiftDirHandler=null;constructor(t){this.config={...g,...t}}async init(e){this.locale=await r(e,this.config.locale,m,p),this.directableTypes=new Set(this.config.directableTypes),this.patchNodeSpecs(e),this.registerCommands(e),this.registerKeymaps(e),this.registerToolbarItem(e),this.registerService(e),t()||(this.shiftDirHandler=new u(e),this.shiftDirHandler.attach(e.getContainer()))}destroy(){this.shiftDirHandler?.detach(),this.shiftDirHandler=null}registerService(t){const e={directableTypes:this.directableTypes,getBlockDir:h};t.registerService(l,e)}patchNodeSpecs(t){a(t.getSchemaRegistry(),this.config.directableTypes,{attrName:"dir",getDefault:()=>"auto",applyToDOM:y})}registerCommands(t){t.registerCommand("setDirectionLTR",()=>{const e=this.setDirection(t,"ltr");return e&&t.announce(this.locale.announceLTR),e}),t.registerCommand("setDirectionRTL",()=>{const e=this.setDirection(t,"rtl");return e&&t.announce(this.locale.announceRTL),e}),t.registerCommand("setDirectionAuto",()=>{const e=this.setDirection(t,"auto");return e&&t.announce(this.locale.announceAuto),e}),t.registerCommand("toggleDirection",()=>{const e=s(t.getState());if(!e||!this.directableTypes.has(e.type))return!1;const i=h(e),o="auto"===i?"rtl":"rtl"===i?"ltr":"auto";return this.setDirection(t,o)})}registerKeymaps(t){t.registerKeymap({"Mod-Shift-D":()=>t.executeCommand("toggleDirection")})}registerToolbarItem(t){const e={ltr:"setDirectionLTR",rtl:"setDirectionRTL",auto:"setDirectionAuto"},i=D.map(t=>({label:this.getDirectionLabel(t),command:e[t],icon:c[t]}));t.registerToolbarItem({id:"text-direction",group:"block",icon:c.auto,label:this.locale.toolbarLabel,tooltip:`${this.locale.toolbarTooltip} (${n("Mod-Shift-D")})`,command:"setDirectionAuto",popupType:"dropdown",popupConfig:{items:i},isActive:t=>this.isNonDefaultDirection(t),isEnabled:t=>this.isDirectable(t),getIcon:t=>{const e=s(t);return e?c[h(e)]??c.auto:c.auto}})}getDirectionLabel(t){return"ltr"===t?this.locale.ltr:"rtl"===t?this.locale.rtl:this.locale.auto}setDirection(t,i){const r=t.getState(),s=e(r);if(0===s.length)return!1;const n=r.transaction("command");let a=!1;for(const e of s){const t=r.getBlock(e);if(!t||!this.directableTypes.has(t.type))continue;const o=r.getNodePath(e);o&&(n.setNodeAttr(o,{...t.attrs,dir:i}),a=!0)}return!!a&&o(t,n.setSelection(r.selection).build())}isNonDefaultDirection(t){const e=s(t);if(!e||!this.directableTypes.has(e.type))return!1;const i=e.attrs?.dir;return null!=i&&"auto"!==i}isDirectable(t){const e=s(t);return null!=e&&this.directableTypes.has(e.type)}};function y(t,e){const i=e.attrs?.dir;"ltr"!==i&&"rtl"!==i&&"auto"!==i||t.setAttribute("dir",i)}export{m as n,p as r,f as t};
2
+ //# sourceMappingURL=TextDirectionPlugin-Bns_03vL.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextDirectionPlugin-DHB88HKf.mjs","names":[],"sources":["../../src/plugins/text-direction/ShiftDirectionHandler.ts","../../src/plugins/text-direction/TextDirectionLocale.ts","../../src/plugins/text-direction/TextDirectionPlugin.ts"],"sourcesContent":["/**\n * Handles Ctrl+Left-Shift → LTR and Ctrl+Right-Shift → RTL shortcuts.\n *\n * Uses a deferred pattern: sets a pending direction on Ctrl+Shift keydown,\n * and applies it on Shift keyup only if no other key was pressed in between.\n * This prevents conflicts with Ctrl+Shift+<key> shortcuts like Ctrl+Shift+D.\n */\n\nimport type { PluginContext } from '../Plugin.js';\n\nexport class ShiftDirectionHandler {\n\tprivate pendingDir: 'ltr' | 'rtl' | null = null;\n\tprivate container: HTMLElement | null = null;\n\n\tconstructor(private readonly context: PluginContext) {}\n\n\tattach(container: HTMLElement): void {\n\t\tthis.container = container;\n\t\tcontainer.addEventListener('keydown', this.onKeydown);\n\t\tcontainer.addEventListener('keyup', this.onKeyup);\n\t}\n\n\tdetach(): void {\n\t\tif (!this.container) return;\n\t\tthis.container.removeEventListener('keydown', this.onKeydown);\n\t\tthis.container.removeEventListener('keyup', this.onKeyup);\n\t\tthis.container = null;\n\t}\n\n\tprivate readonly onKeydown = (e: KeyboardEvent): void => {\n\t\tif (e.key === 'Shift' && e.ctrlKey && !e.altKey && !e.metaKey) {\n\t\t\tif (e.code === 'ShiftLeft') {\n\t\t\t\tthis.pendingDir = 'ltr';\n\t\t\t} else if (e.code === 'ShiftRight') {\n\t\t\t\tthis.pendingDir = 'rtl';\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// Any other keydown cancels the pending direction change\n\t\tthis.pendingDir = null;\n\t};\n\n\tprivate readonly onKeyup = (e: KeyboardEvent): void => {\n\t\tif (e.key !== 'Shift' || !this.pendingDir) return;\n\t\tconst dir: 'ltr' | 'rtl' = this.pendingDir;\n\t\tthis.pendingDir = null;\n\t\tconst command: string = dir === 'ltr' ? 'setDirectionLTR' : 'setDirectionRTL';\n\t\tthis.context.executeCommand(command);\n\t};\n}\n","/** Locale interface and default English locale for the TextDirectionPlugin. */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\nexport interface TextDirectionLocale {\n\treadonly ltr: string;\n\treadonly rtl: string;\n\treadonly auto: string;\n\treadonly toolbarLabel: string;\n\treadonly toolbarTooltip: string;\n\treadonly announceLTR: string;\n\treadonly announceRTL: string;\n\treadonly announceAuto: string;\n}\n\nexport const TEXT_DIRECTION_LOCALE_EN: TextDirectionLocale = {\n\tltr: 'Left to Right',\n\trtl: 'Right to Left',\n\tauto: 'Auto',\n\ttoolbarLabel: 'Text Direction',\n\ttoolbarTooltip: 'Text Direction',\n\tannounceLTR: 'Text direction set to left-to-right',\n\tannounceRTL: 'Text direction set to right-to-left',\n\tannounceAuto: 'Text direction set to automatic',\n};\n\nconst localeModules: LocaleModuleMap<TextDirectionLocale> = import.meta.glob<{\n\tdefault: TextDirectionLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadTextDirectionLocale(lang: string): Promise<TextDirectionLocale> {\n\treturn loadLocaleModule(localeModules, lang, TEXT_DIRECTION_LOCALE_EN);\n}\n","/**\n * Block-level text direction plugin.\n *\n * Patches NodeSpecs of directable block types to add a `dir` attribute\n * (`'ltr' | 'rtl' | 'auto'`), exposes commands and a toolbar dropdown\n * for changing block direction, registers a `Mod-Shift-D` keymap, and\n * (on Windows/Linux) attaches a `Ctrl+Shift` direction handler.\n *\n * Inline `<bdi>` isolation lives in {@link BidiIsolationPlugin}; the\n * auto-detect / inherit / preserve middlewares live in\n * {@link TextDirectionAutoPlugin}. Both consume the\n * {@link TextDirectionService} that this plugin registers.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { isMac } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { patchNodeSpecAttr } from '../shared/NodeSpecPatching.js';\nimport {\n\tdispatchIfPresent,\n\tgetSelectedBlock,\n\tgetSelectedBlockIds,\n\tresolveLocale,\n} from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { getBlockDir } from './DirectionDetection.js';\nimport { DIRECTION_ICONS } from './DirectionIcons.js';\nimport { ShiftDirectionHandler } from './ShiftDirectionHandler.js';\nimport {\n\tTEXT_DIRECTION_LOCALE_EN,\n\ttype TextDirectionLocale,\n\tloadTextDirectionLocale,\n} from './TextDirectionLocale.js';\nimport {\n\tTEXT_DIRECTION_SERVICE_KEY,\n\ttype TextDirection,\n\ttype TextDirectionService,\n} from './TextDirectionService.js';\n\nexport type { TextDirection };\n\nexport interface TextDirectionConfig {\n\t/** Block types that support direction. */\n\treadonly directableTypes: readonly string[];\n\treadonly locale?: TextDirectionLocale;\n}\n\nconst DEFAULT_CONFIG: TextDirectionConfig = {\n\tdirectableTypes: [\n\t\t'paragraph',\n\t\t'heading',\n\t\t'title',\n\t\t'subtitle',\n\t\t'table_cell',\n\t\t'blockquote',\n\t\t'list_item',\n\t],\n};\n\nconst ALL_DIRECTIONS: readonly TextDirection[] = ['ltr', 'rtl', 'auto'];\n\nexport class TextDirectionPlugin implements Plugin {\n\treadonly id = 'text-direction';\n\treadonly name = 'Text Direction';\n\treadonly priority = 91;\n\n\tprivate readonly config: TextDirectionConfig;\n\tprivate locale!: TextDirectionLocale;\n\tprivate directableTypes!: ReadonlySet<string>;\n\tprivate shiftDirHandler: ShiftDirectionHandler | null = null;\n\n\tconstructor(config?: Partial<TextDirectionConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tTEXT_DIRECTION_LOCALE_EN,\n\t\t\tloadTextDirectionLocale,\n\t\t);\n\n\t\tthis.directableTypes = new Set(this.config.directableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\t\tthis.registerService(context);\n\n\t\tif (!isMac()) {\n\t\t\tthis.shiftDirHandler = new ShiftDirectionHandler(context);\n\t\t\tthis.shiftDirHandler.attach(context.getContainer());\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.shiftDirHandler?.detach();\n\t\tthis.shiftDirHandler = null;\n\t}\n\n\tprivate registerService(context: PluginContext): void {\n\t\tconst service: TextDirectionService = {\n\t\t\tdirectableTypes: this.directableTypes,\n\t\t\tgetBlockDir,\n\t\t};\n\t\tcontext.registerService(TEXT_DIRECTION_SERVICE_KEY, service);\n\t}\n\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tpatchNodeSpecAttr(context.getSchemaRegistry(), this.config.directableTypes, {\n\t\t\tattrName: 'dir',\n\t\t\tgetDefault: () => 'auto',\n\t\t\tapplyToDOM: applyDirection,\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('setDirectionLTR', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.announceLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionRTL', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.announceRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionAuto', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.announceAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleDirection', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst block = getSelectedBlock(state);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\n\t\t\tconst current: TextDirection = getBlockDir(block);\n\t\t\tconst next: TextDirection = current === 'auto' ? 'rtl' : current === 'rtl' ? 'ltr' : 'auto';\n\t\t\treturn this.setDirection(context, next);\n\t\t});\n\t}\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-D': () => context.executeCommand('toggleDirection'),\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst commandNames: Readonly<Record<TextDirection, string>> = {\n\t\t\tltr: 'setDirectionLTR',\n\t\t\trtl: 'setDirectionRTL',\n\t\t\tauto: 'setDirectionAuto',\n\t\t};\n\n\t\tconst dropdownItems = ALL_DIRECTIONS.map((dir) => ({\n\t\t\tlabel: this.getDirectionLabel(dir),\n\t\t\tcommand: commandNames[dir],\n\t\t\ticon: DIRECTION_ICONS[dir],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-direction',\n\t\t\tgroup: 'block',\n\t\t\ticon: DIRECTION_ICONS.auto,\n\t\t\tlabel: this.locale.toolbarLabel,\n\t\t\ttooltip: `${this.locale.toolbarTooltip} (${formatShortcut('Mod-Shift-D')})`,\n\t\t\tcommand: 'setDirectionAuto',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tisActive: (state) => this.isNonDefaultDirection(state),\n\t\t\tisEnabled: (state) => this.isDirectable(state),\n\t\t\tgetIcon: (state) => {\n\t\t\t\tconst block = getSelectedBlock(state);\n\t\t\t\tif (!block) return DIRECTION_ICONS.auto;\n\t\t\t\tconst dir: TextDirection = getBlockDir(block);\n\t\t\t\treturn DIRECTION_ICONS[dir] ?? DIRECTION_ICONS.auto;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate getDirectionLabel(dir: TextDirection): string {\n\t\tif (dir === 'ltr') return this.locale.ltr;\n\t\tif (dir === 'rtl') return this.locale.rtl;\n\t\treturn this.locale.auto;\n\t}\n\n\tprivate setDirection(context: PluginContext, direction: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst blockIds: BlockId[] = getSelectedBlockIds(state);\n\t\tif (blockIds.length === 0) return false;\n\n\t\tconst tb = state.transaction('command');\n\t\tlet changed = false;\n\n\t\tfor (const id of blockIds) {\n\t\t\tconst block = state.getBlock(id);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) continue;\n\n\t\t\tconst path = state.getNodePath(id);\n\t\t\tif (!path) continue;\n\n\t\t\ttb.setNodeAttr(path, { ...block.attrs, dir: direction });\n\t\t\tchanged = true;\n\t\t}\n\n\t\tif (!changed) return false;\n\n\t\treturn dispatchIfPresent(context, tb.setSelection(state.selection).build());\n\t}\n\n\tprivate isNonDefaultDirection(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\t\tconst dir = block.attrs?.dir;\n\t\treturn dir != null && dir !== 'auto';\n\t}\n\n\tprivate isDirectable(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\treturn block != null && this.directableTypes.has(block.type);\n\t}\n}\n\nfunction applyDirection(el: HTMLElement, node: BlockNode): void {\n\tconst dir = node.attrs?.dir;\n\tif (dir === 'ltr' || dir === 'rtl' || dir === 'auto') {\n\t\tel.setAttribute('dir', dir);\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TextDirectionPlugin-Bns_03vL.mjs","names":[],"sources":["../../src/plugins/text-direction/ShiftDirectionHandler.ts","../../src/plugins/text-direction/TextDirectionLocale.ts","../../src/plugins/text-direction/TextDirectionPlugin.ts"],"sourcesContent":["/**\n * Handles Ctrl+Left-Shift → LTR and Ctrl+Right-Shift → RTL shortcuts.\n *\n * Uses a deferred pattern: sets a pending direction on Ctrl+Shift keydown,\n * and applies it on Shift keyup only if no other key was pressed in between.\n * This prevents conflicts with Ctrl+Shift+<key> shortcuts like Ctrl+Shift+D.\n */\n\nimport type { PluginContext } from '../Plugin.js';\n\nexport class ShiftDirectionHandler {\n\tprivate pendingDir: 'ltr' | 'rtl' | null = null;\n\tprivate container: HTMLElement | null = null;\n\n\tconstructor(private readonly context: PluginContext) {}\n\n\tattach(container: HTMLElement): void {\n\t\tthis.container = container;\n\t\tcontainer.addEventListener('keydown', this.onKeydown);\n\t\tcontainer.addEventListener('keyup', this.onKeyup);\n\t}\n\n\tdetach(): void {\n\t\tif (!this.container) return;\n\t\tthis.container.removeEventListener('keydown', this.onKeydown);\n\t\tthis.container.removeEventListener('keyup', this.onKeyup);\n\t\tthis.container = null;\n\t}\n\n\tprivate readonly onKeydown = (e: KeyboardEvent): void => {\n\t\tif (e.key === 'Shift' && e.ctrlKey && !e.altKey && !e.metaKey) {\n\t\t\tif (e.code === 'ShiftLeft') {\n\t\t\t\tthis.pendingDir = 'ltr';\n\t\t\t} else if (e.code === 'ShiftRight') {\n\t\t\t\tthis.pendingDir = 'rtl';\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\t// Any other keydown cancels the pending direction change\n\t\tthis.pendingDir = null;\n\t};\n\n\tprivate readonly onKeyup = (e: KeyboardEvent): void => {\n\t\tif (e.key !== 'Shift' || !this.pendingDir) return;\n\t\tconst dir: 'ltr' | 'rtl' = this.pendingDir;\n\t\tthis.pendingDir = null;\n\t\tconst command: string = dir === 'ltr' ? 'setDirectionLTR' : 'setDirectionRTL';\n\t\tthis.context.executeCommand(command);\n\t};\n}\n","/** Locale interface and default English locale for the TextDirectionPlugin. */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\nexport interface TextDirectionLocale {\n\treadonly ltr: string;\n\treadonly rtl: string;\n\treadonly auto: string;\n\treadonly toolbarLabel: string;\n\treadonly toolbarTooltip: string;\n\treadonly announceLTR: string;\n\treadonly announceRTL: string;\n\treadonly announceAuto: string;\n}\n\nexport const TEXT_DIRECTION_LOCALE_EN: TextDirectionLocale = {\n\tltr: 'Left to Right',\n\trtl: 'Right to Left',\n\tauto: 'Auto',\n\ttoolbarLabel: 'Text Direction',\n\ttoolbarTooltip: 'Text Direction',\n\tannounceLTR: 'Text direction set to left-to-right',\n\tannounceRTL: 'Text direction set to right-to-left',\n\tannounceAuto: 'Text direction set to automatic',\n};\n\nconst localeModules: LocaleModuleMap<TextDirectionLocale> = import.meta.glob<{\n\tdefault: TextDirectionLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadTextDirectionLocale(lang: string): Promise<TextDirectionLocale> {\n\treturn loadLocaleModule(localeModules, lang, TEXT_DIRECTION_LOCALE_EN);\n}\n","/**\n * Block-level text direction plugin.\n *\n * Patches NodeSpecs of directable block types to add a `dir` attribute\n * (`'ltr' | 'rtl' | 'auto'`), exposes commands and a toolbar dropdown\n * for changing block direction, registers a `Mod-Shift-D` keymap, and\n * (on Windows/Linux) attaches a `Ctrl+Shift` direction handler.\n *\n * Inline `<bdi>` isolation lives in {@link BidiIsolationPlugin}; the\n * auto-detect / inherit / preserve middlewares live in\n * {@link TextDirectionAutoPlugin}. Both consume the\n * {@link TextDirectionService} that this plugin registers.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { isMac } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { patchNodeSpecAttr } from '../shared/NodeSpecPatching.js';\nimport {\n\tdispatchIfPresent,\n\tgetSelectedBlock,\n\tgetSelectedBlockIds,\n\tresolveLocale,\n} from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { getBlockDir } from './DirectionDetection.js';\nimport { DIRECTION_ICONS } from './DirectionIcons.js';\nimport { ShiftDirectionHandler } from './ShiftDirectionHandler.js';\nimport {\n\tTEXT_DIRECTION_LOCALE_EN,\n\ttype TextDirectionLocale,\n\tloadTextDirectionLocale,\n} from './TextDirectionLocale.js';\nimport {\n\tTEXT_DIRECTION_SERVICE_KEY,\n\ttype TextDirection,\n\ttype TextDirectionService,\n} from './TextDirectionService.js';\n\nexport type { TextDirection };\n\nexport interface TextDirectionConfig {\n\t/** Block types that support direction. */\n\treadonly directableTypes: readonly string[];\n\treadonly locale?: TextDirectionLocale;\n}\n\nconst DEFAULT_CONFIG: TextDirectionConfig = {\n\tdirectableTypes: [\n\t\t'paragraph',\n\t\t'heading',\n\t\t'title',\n\t\t'subtitle',\n\t\t'table_cell',\n\t\t'blockquote',\n\t\t'list_item',\n\t],\n};\n\nconst ALL_DIRECTIONS: readonly TextDirection[] = ['ltr', 'rtl', 'auto'];\n\nexport class TextDirectionPlugin implements Plugin {\n\treadonly id = 'text-direction';\n\treadonly name = 'Text Direction';\n\treadonly priority = 91;\n\n\tprivate readonly config: TextDirectionConfig;\n\tprivate locale!: TextDirectionLocale;\n\tprivate directableTypes!: ReadonlySet<string>;\n\tprivate shiftDirHandler: ShiftDirectionHandler | null = null;\n\n\tconstructor(config?: Partial<TextDirectionConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tTEXT_DIRECTION_LOCALE_EN,\n\t\t\tloadTextDirectionLocale,\n\t\t);\n\n\t\tthis.directableTypes = new Set(this.config.directableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\t\tthis.registerService(context);\n\n\t\tif (!isMac()) {\n\t\t\tthis.shiftDirHandler = new ShiftDirectionHandler(context);\n\t\t\tthis.shiftDirHandler.attach(context.getContainer());\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.shiftDirHandler?.detach();\n\t\tthis.shiftDirHandler = null;\n\t}\n\n\tprivate registerService(context: PluginContext): void {\n\t\tconst service: TextDirectionService = {\n\t\t\tdirectableTypes: this.directableTypes,\n\t\t\tgetBlockDir,\n\t\t};\n\t\tcontext.registerService(TEXT_DIRECTION_SERVICE_KEY, service);\n\t}\n\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tpatchNodeSpecAttr(context.getSchemaRegistry(), this.config.directableTypes, {\n\t\t\tattrName: 'dir',\n\t\t\tgetDefault: () => 'auto',\n\t\t\tapplyToDOM: applyDirection,\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('setDirectionLTR', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.announceLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionRTL', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.announceRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionAuto', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.announceAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleDirection', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst block = getSelectedBlock(state);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\n\t\t\tconst current: TextDirection = getBlockDir(block);\n\t\t\tconst next: TextDirection = current === 'auto' ? 'rtl' : current === 'rtl' ? 'ltr' : 'auto';\n\t\t\treturn this.setDirection(context, next);\n\t\t});\n\t}\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-D': () => context.executeCommand('toggleDirection'),\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst commandNames: Readonly<Record<TextDirection, string>> = {\n\t\t\tltr: 'setDirectionLTR',\n\t\t\trtl: 'setDirectionRTL',\n\t\t\tauto: 'setDirectionAuto',\n\t\t};\n\n\t\tconst dropdownItems = ALL_DIRECTIONS.map((dir) => ({\n\t\t\tlabel: this.getDirectionLabel(dir),\n\t\t\tcommand: commandNames[dir],\n\t\t\ticon: DIRECTION_ICONS[dir],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-direction',\n\t\t\tgroup: 'block',\n\t\t\ticon: DIRECTION_ICONS.auto,\n\t\t\tlabel: this.locale.toolbarLabel,\n\t\t\ttooltip: `${this.locale.toolbarTooltip} (${formatShortcut('Mod-Shift-D')})`,\n\t\t\tcommand: 'setDirectionAuto',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tisActive: (state) => this.isNonDefaultDirection(state),\n\t\t\tisEnabled: (state) => this.isDirectable(state),\n\t\t\tgetIcon: (state) => {\n\t\t\t\tconst block = getSelectedBlock(state);\n\t\t\t\tif (!block) return DIRECTION_ICONS.auto;\n\t\t\t\tconst dir: TextDirection = getBlockDir(block);\n\t\t\t\treturn DIRECTION_ICONS[dir] ?? DIRECTION_ICONS.auto;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate getDirectionLabel(dir: TextDirection): string {\n\t\tif (dir === 'ltr') return this.locale.ltr;\n\t\tif (dir === 'rtl') return this.locale.rtl;\n\t\treturn this.locale.auto;\n\t}\n\n\tprivate setDirection(context: PluginContext, direction: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst blockIds: BlockId[] = getSelectedBlockIds(state);\n\t\tif (blockIds.length === 0) return false;\n\n\t\tconst tb = state.transaction('command');\n\t\tlet changed = false;\n\n\t\tfor (const id of blockIds) {\n\t\t\tconst block = state.getBlock(id);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) continue;\n\n\t\t\tconst path = state.getNodePath(id);\n\t\t\tif (!path) continue;\n\n\t\t\ttb.setNodeAttr(path, { ...block.attrs, dir: direction });\n\t\t\tchanged = true;\n\t\t}\n\n\t\tif (!changed) return false;\n\n\t\treturn dispatchIfPresent(context, tb.setSelection(state.selection).build());\n\t}\n\n\tprivate isNonDefaultDirection(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\t\tconst dir = block.attrs?.dir;\n\t\treturn dir != null && dir !== 'auto';\n\t}\n\n\tprivate isDirectable(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\treturn block != null && this.directableTypes.has(block.type);\n\t}\n}\n\nfunction applyDirection(el: HTMLElement, node: BlockNode): void {\n\tconst dir = node.attrs?.dir;\n\tif (dir === 'ltr' || dir === 'rtl' || dir === 'auto') {\n\t\tel.setAttribute('dir', dir);\n\t}\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import{n as e}from"./TypedKeys-CA4bfw9O.mjs";var r=new e("textDirection");export{r as t};
2
+ //# sourceMappingURL=TextDirectionService-BcX07mw2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"TextDirectionService-OFOU6r_s.mjs","names":[],"sources":["../../src/plugins/text-direction/TextDirectionService.ts"],"sourcesContent":["/**\n * Service contract exposed by `TextDirectionPlugin` to other plugins\n * (e.g. `BidiIsolationPlugin`, `TextDirectionAutoPlugin`) that need to\n * read the current block-level direction or the set of types that\n * support direction.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { ServiceKey } from '../../model/TypedKeys.js';\n\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\n\nexport interface TextDirectionService {\n\treadonly directableTypes: ReadonlySet<string>;\n\tgetBlockDir(block: BlockNode): TextDirection;\n}\n\nexport const TEXT_DIRECTION_SERVICE_KEY: ServiceKey<TextDirectionService> =\n\tnew ServiceKey<TextDirectionService>('textDirection');\n"],"mappings":"6CAiBA,IAAa,EACZ,IAAI,EAAiC"}
1
+ {"version":3,"file":"TextDirectionService-BcX07mw2.mjs","names":[],"sources":["../../src/plugins/text-direction/TextDirectionService.ts"],"sourcesContent":["/**\n * Service contract exposed by `TextDirectionPlugin` to other plugins\n * (e.g. `BidiIsolationPlugin`, `TextDirectionAutoPlugin`) that need to\n * read the current block-level direction or the set of types that\n * support direction.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { ServiceKey } from '../../model/TypedKeys.js';\n\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\n\nexport interface TextDirectionService {\n\treadonly directableTypes: ReadonlySet<string>;\n\tgetBlockDir(block: BlockNode): TextDirection;\n}\n\nexport const TEXT_DIRECTION_SERVICE_KEY: ServiceKey<TextDirectionService> =\n\tnew ServiceKey<TextDirectionService>('textDirection');\n"],"mappings":"6CAiBA,IAAa,EACZ,IAAI,EAAiC"}
@@ -0,0 +1,2 @@
1
+ import{_ as t,m as e}from"./Commands-1dFFldi7.mjs";import{i}from"./TypeBrands-Ch9856Gb.mjs";import{c as s,n as o,o as r,s as n}from"./PluginHelpers-Dx_0hfDe.mjs";import{t as a}from"./MarkInputRule-Bdi8KPus.mjs";import{t as l}from"./ShortcutFormatting-TwiufqeV.mjs";var g={boldLabel:"Bold",italicLabel:"Italic",underlineLabel:"Underline"},c=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-Dx2lO0Nm.mjs"),"./locales/de.ts":()=>import("./de-BcPntcnr.mjs"),"./locales/es.ts":()=>import("./es-nRLq7bgP.mjs"),"./locales/fr.ts":()=>import("./fr-DiDhVhyV.mjs"),"./locales/hi.ts":()=>import("./hi-BNJIGWQQ.mjs"),"./locales/pt.ts":()=>import("./pt-D__tcM2T.mjs"),"./locales/ru.ts":()=>import("./ru-CvDl-yEd.mjs"),"./locales/zh.ts":()=>import("./zh-C-wHnDo5.mjs")});async function m(t){return s(c,t,g)}var p={bold:!0,italic:!0,underline:!0},f=[{type:"bold",configKey:"bold",rank:0,tag:"strong",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/></svg>',keyBinding:"Mod-B",toHTMLString:t=>`<strong>${t}</strong>`,parseHTML:[{tag:"strong"},{tag:"b",getAttrs:t=>{const e=t.style.fontWeight;return"normal"!==e&&"400"!==e&&{}}},{tag:"span",getAttrs:t=>{const e=t.style.fontWeight;if(!e)return!1;if("bold"===e)return{};const i=Number.parseInt(e,10);return!Number.isNaN(i)&&i>=700&&{}}}],sanitize:{tags:["strong","b"]}},{type:"italic",configKey:"italic",rank:1,tag:"em",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/></svg>',keyBinding:"Mod-I",toHTMLString:t=>`<em>${t}</em>`,parseHTML:[{tag:"em"},{tag:"i"},{tag:"span",getAttrs:t=>"italic"===t.style.fontStyle&&{}}],sanitize:{tags:["em","i"]}},{type:"underline",configKey:"underline",rank:2,tag:"u",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z"/></svg>',keyBinding:"Mod-U",toHTMLString:t=>`<u>${t}</u>`,parseHTML:[{tag:"u"},{tag:"span",getAttrs:t=>!!t.style.textDecoration.includes("underline")&&{}}],sanitize:{tags:["u"]}}],h=class{id="text-formatting";name="Text Formatting";priority=20;config;locale;constructor(t){this.config={...p,...t}}async init(t){this.locale=await r(t,this.config.locale,g,m);const e=f.filter(t=>this.config[t.configKey]);for(const i of e)this.registerMark(t,i);this.registerKeymaps(t,e),this.registerInputRules(t),this.registerDisabledToolbarItems(t)}registerMark(s,r){const a=n(r.type),g=this.isToolbarVisible(r.configKey);if(s.registerMarkSpec({type:r.type,rank:r.rank,toDOM:()=>document.createElement(r.tag),toHTMLString:(t,e)=>r.toHTMLString(e),parseHTML:r.parseHTML,sanitize:r.sanitize}),s.registerCommand(a,()=>o(s,t(s.getState(),i(r.type)))),g){const t=this.getMarkLabel(r.type);s.registerToolbarItem({id:r.type,group:"format",icon:r.icon,label:t,tooltip:`${t} (${l(r.keyBinding)})`,command:a,isActive:t=>e(t,i(r.type))})}}registerKeymaps(t,e){const i={};for(const s of e){const e=n(s.type);i[s.keyBinding]=()=>t.executeCommand(e)}Object.keys(i).length>0&&t.registerKeymap(i)}registerInputRules(t){!1!==this.config.inputRule&&(this.config.bold&&t.registerInputRule(a("bold","**")),this.config.italic&&t.registerInputRule(a("italic","*")))}registerDisabledToolbarItems(t){if(this.config.toolbar)for(const e of f){const i=this.config[e.configKey],s=this.config.toolbar[e.configKey]??!0;!i&&s&&t.registerToolbarItem({id:e.type,group:"format",icon:e.icon,label:this.getMarkLabel(e.type),command:n(e.type),isEnabled:()=>!1})}}getMarkLabel(t){const e=`${t}Label`;return this.locale[e]}isToolbarVisible(t){return!this.config.toolbar||(this.config.toolbar[t]??!0)}};export{g as n,m as r,h as t};
2
+ //# sourceMappingURL=TextFormattingPlugin-DBVlePqj.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TextFormattingPlugin-DBVlePqj.mjs","names":[],"sources":["../../src/plugins/text-formatting/TextFormattingLocale.ts","../../src/plugins/text-formatting/TextFormattingPlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the TextFormattingPlugin.\n */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface TextFormattingLocale {\n\treadonly boldLabel: string;\n\treadonly italicLabel: string;\n\treadonly underlineLabel: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_EN: TextFormattingLocale = {\n\tboldLabel: 'Bold',\n\titalicLabel: 'Italic',\n\tunderlineLabel: 'Underline',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<TextFormattingLocale> = import.meta.glob<{\n\tdefault: TextFormattingLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadTextFormattingLocale(lang: string): Promise<TextFormattingLocale> {\n\treturn loadLocaleModule(localeModules, lang, TEXT_FORMATTING_LOCALE_EN);\n}\n","/**\n * TextFormattingPlugin: registers inline marks (bold, italic, underline)\n * with their MarkSpecs, toggle commands, keyboard shortcuts, and toolbar items.\n *\n * This plugin is data-driven — each mark type is defined declaratively and\n * all registrations (MarkSpec, command, keymap, toolbar item) are derived\n * from the same definition.\n *\n * Supports two separate config dimensions:\n * - Feature config (bold/italic/underline): controls whether the mark is\n * registered in the schema. When disabled, the keyboard shortcut does nothing.\n * - Toolbar config: controls whether the toolbar button is visible.\n * When a feature is disabled but toolbar is enabled, the button renders as disabled.\n */\n\nimport { isMarkActive, toggleMark } from '../../commands/Commands.js';\nimport type { ParseRule } from '../../model/ParseRule.js';\nimport type { SanitizeConfig } from '../../model/SanitizeConfig.js';\nimport { markType as mkType } from '../../model/TypeBrands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { createMarkInputRule } from '../shared/MarkInputRule.js';\nimport { dispatchIfPresent, resolveLocale, toCommandName } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport {\n\tTEXT_FORMATTING_LOCALE_EN,\n\ttype TextFormattingLocale,\n\tloadTextFormattingLocale,\n} from './TextFormattingLocale.js';\n\n// --- Configuration ---\n\n/** Controls toolbar button visibility per mark. */\nexport interface TextFormattingToolbarConfig {\n\treadonly bold?: boolean;\n\treadonly italic?: boolean;\n\treadonly underline?: boolean;\n}\n\n/** Controls which inline marks are enabled and which toolbar buttons are shown. */\nexport interface TextFormattingConfig {\n\treadonly bold: boolean;\n\treadonly italic: boolean;\n\treadonly underline: boolean;\n\t/** Live Markdown shortcuts: `**x**` to bold, `*x*` to italic. Default true. */\n\treadonly inputRule?: boolean;\n\treadonly toolbar?: TextFormattingToolbarConfig;\n\treadonly locale?: TextFormattingLocale;\n}\n\nconst DEFAULT_CONFIG: TextFormattingConfig = {\n\tbold: true,\n\titalic: true,\n\tunderline: true,\n};\n\n// --- Mark Definitions ---\n\ninterface MarkDefinition {\n\treadonly type: string;\n\treadonly configKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'locale' | 'inputRule'>;\n\treadonly rank: number;\n\treadonly tag: string;\n\treadonly icon: string;\n\treadonly keyBinding: string;\n\treadonly toHTMLString: (content: string) => string;\n\treadonly parseHTML: readonly ParseRule[];\n\treadonly sanitize: SanitizeConfig;\n}\n\nconst BOLD_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z\"/></svg>';\nconst ITALIC_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z\"/></svg>';\nconst UNDERLINE_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z\"/></svg>';\n\nconst MARK_DEFINITIONS: readonly MarkDefinition[] = [\n\t{\n\t\ttype: 'bold',\n\t\tconfigKey: 'bold',\n\t\trank: 0,\n\t\ttag: 'strong',\n\t\ticon: BOLD_ICON,\n\t\tkeyBinding: 'Mod-B',\n\t\ttoHTMLString: (content) => `<strong>${content}</strong>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'strong' },\n\t\t\t{\n\t\t\t\ttag: 'b',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst fw: string = el.style.fontWeight;\n\t\t\t\t\treturn fw === 'normal' || fw === '400' ? false : {};\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst fw: string = el.style.fontWeight;\n\t\t\t\t\tif (!fw) return false;\n\t\t\t\t\tif (fw === 'bold') return {};\n\t\t\t\t\tconst numeric: number = Number.parseInt(fw, 10);\n\t\t\t\t\treturn !Number.isNaN(numeric) && numeric >= 700 ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['strong', 'b'] },\n\t},\n\t{\n\t\ttype: 'italic',\n\t\tconfigKey: 'italic',\n\t\trank: 1,\n\t\ttag: 'em',\n\t\ticon: ITALIC_ICON,\n\t\tkeyBinding: 'Mod-I',\n\t\ttoHTMLString: (content) => `<em>${content}</em>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'em' },\n\t\t\t{ tag: 'i' },\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\treturn el.style.fontStyle === 'italic' ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['em', 'i'] },\n\t},\n\t{\n\t\ttype: 'underline',\n\t\tconfigKey: 'underline',\n\t\trank: 2,\n\t\ttag: 'u',\n\t\ticon: UNDERLINE_ICON,\n\t\tkeyBinding: 'Mod-U',\n\t\ttoHTMLString: (content) => `<u>${content}</u>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'u' },\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\treturn el.style.textDecoration.includes('underline') ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['u'] },\n\t},\n];\n\n// --- Plugin ---\n\nexport class TextFormattingPlugin implements Plugin {\n\treadonly id = 'text-formatting';\n\treadonly name = 'Text Formatting';\n\treadonly priority = 20;\n\n\tprivate readonly config: TextFormattingConfig;\n\tprivate locale!: TextFormattingLocale;\n\n\tconstructor(config?: Partial<TextFormattingConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tTEXT_FORMATTING_LOCALE_EN,\n\t\t\tloadTextFormattingLocale,\n\t\t);\n\n\t\tconst enabledMarks = MARK_DEFINITIONS.filter((def) => this.config[def.configKey]);\n\n\t\tfor (const def of enabledMarks) {\n\t\t\tthis.registerMark(context, def);\n\t\t}\n\n\t\tthis.registerKeymaps(context, enabledMarks);\n\t\tthis.registerInputRules(context);\n\n\t\t// Register disabled placeholder buttons for marks that are disabled\n\t\t// as features but explicitly requested in the toolbar config\n\t\tthis.registerDisabledToolbarItems(context);\n\t}\n\n\tprivate registerMark(context: PluginContext, def: MarkDefinition): void {\n\t\tconst commandName = toCommandName(def.type);\n\t\tconst toolbarVisible = this.isToolbarVisible(def.configKey);\n\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: def.type,\n\t\t\trank: def.rank,\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement(def.tag);\n\t\t\t},\n\t\t\ttoHTMLString: (_mark, content) => def.toHTMLString(content),\n\t\t\tparseHTML: def.parseHTML,\n\t\t\tsanitize: def.sanitize,\n\t\t});\n\n\t\tcontext.registerCommand(commandName, () =>\n\t\t\tdispatchIfPresent(context, toggleMark(context.getState(), mkType(def.type))),\n\t\t);\n\n\t\tif (toolbarVisible) {\n\t\t\tconst label: string = this.getMarkLabel(def.type);\n\t\t\tcontext.registerToolbarItem({\n\t\t\t\tid: def.type,\n\t\t\t\tgroup: 'format',\n\t\t\t\ticon: def.icon,\n\t\t\t\tlabel,\n\t\t\t\ttooltip: `${label} (${formatShortcut(def.keyBinding)})`,\n\t\t\t\tcommand: commandName,\n\t\t\t\tisActive: (state) => isMarkActive(state, mkType(def.type)),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerKeymaps(context: PluginContext, marks: readonly MarkDefinition[]): void {\n\t\tconst keymap: Record<string, () => boolean> = {};\n\t\tfor (const def of marks) {\n\t\t\tconst commandName = toCommandName(def.type);\n\t\t\tkeymap[def.keyBinding] = () => context.executeCommand(commandName);\n\t\t}\n\t\tif (Object.keys(keymap).length > 0) {\n\t\t\tcontext.registerKeymap(keymap);\n\t\t}\n\t}\n\n\t/**\n\t * Registers live Markdown input rules: `**x**` to bold and `*x*` to italic,\n\t * each gated on its feature being enabled. Bold is registered first so it\n\t * wins over italic when both could match. Underscore variants are left to the\n\t * full parser (import/paste) to avoid intra-word `snake_case` false positives.\n\t */\n\tprivate registerInputRules(context: PluginContext): void {\n\t\tif (this.config.inputRule === false) return;\n\t\tif (this.config.bold) context.registerInputRule(createMarkInputRule('bold', '**'));\n\t\tif (this.config.italic) context.registerInputRule(createMarkInputRule('italic', '*'));\n\t}\n\n\t/**\n\t * Registers disabled toolbar buttons for marks whose feature is disabled\n\t * but whose toolbar button is explicitly requested.\n\t */\n\tprivate registerDisabledToolbarItems(context: PluginContext): void {\n\t\tif (!this.config.toolbar) return;\n\n\t\tfor (const def of MARK_DEFINITIONS) {\n\t\t\tconst featureEnabled = this.config[def.configKey];\n\t\t\tconst toolbarVisible = this.config.toolbar[def.configKey] ?? true;\n\n\t\t\tif (!featureEnabled && toolbarVisible) {\n\t\t\t\tcontext.registerToolbarItem({\n\t\t\t\t\tid: def.type,\n\t\t\t\t\tgroup: 'format',\n\t\t\t\t\ticon: def.icon,\n\t\t\t\t\tlabel: this.getMarkLabel(def.type),\n\t\t\t\t\tcommand: toCommandName(def.type),\n\t\t\t\t\tisEnabled: () => false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getMarkLabel(type: string): string {\n\t\tconst key = `${type}Label` as keyof TextFormattingLocale;\n\t\treturn this.locale[key] as string;\n\t}\n\n\t/** Checks if a toolbar button should be visible for a given mark. */\n\tprivate isToolbarVisible(\n\t\tconfigKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'locale' | 'inputRule'>,\n\t): boolean {\n\t\tif (!this.config.toolbar) return true;\n\t\treturn this.config.toolbar[configKey] ?? true;\n\t}\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{i as t}from"./Platform-ByobkiCc.mjs";import{c as e,s as o}from"./StyleRuntime-BFKu52mS.mjs";import{n}from"./TypedKeys-CA4bfw9O.mjs";import{c as r,o as i}from"./PluginHelpers-KDuTlmXm.mjs";import{n as l,r as s,t as a}from"./KeyboardNav-D0my3wuy.mjs";import{n as c,r as d,t as p}from"./PopupPositioning-BB97-__N.mjs";import{n as u,t as h}from"./PopupManager-DUtaK3WX.mjs";var b=class{_toolbarItems=/* @__PURE__ */new Map;_toolbarItemPluginMap=/* @__PURE__ */new Map;registerToolbarItem(t,e){if(this._toolbarItems.has(t.id))throw new Error(`ToolbarItem with id "${t.id}" is already registered.`);if(this._toolbarItems.set(t.id,t),e){const o=this._toolbarItemPluginMap.get(e)??[];o.push(t.id),this._toolbarItemPluginMap.set(e,o)}}getToolbarItemsByPlugin(t){const e=this._toolbarItemPluginMap.get(t)??[],o=[];for(const n of e){const t=this._toolbarItems.get(n);t&&o.push(t)}return o}getToolbarItem(t){return this._toolbarItems.get(t)}getToolbarItems(){return[...this._toolbarItems.values()]}removeToolbarItem(t){this._toolbarItems.delete(t);for(const[e,o]of this._toolbarItemPluginMap){const n=o.indexOf(t);if(-1!==n){o.splice(n,1),0===o.length&&this._toolbarItemPluginMap.delete(e);break}}}clear(){this._toolbarItems.clear(),this._toolbarItemPluginMap.clear()}};function m(t){for(let e=0;e<t.length;e++)if(!t[e]?.disabled)return e;return-1}var f={formattingOptionsAria:"Formatting options",moreToolsAria:"More tools",gridPickerLabel:(t,e)=>`${t} x ${e}`},v=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-C9lO1jsY.mjs"),"./locales/de.ts":()=>import("./de-BXQBXxFJ.mjs"),"./locales/es.ts":()=>import("./es-CXuMz87y.mjs"),"./locales/fr.ts":()=>import("./fr-fshsDD66.mjs"),"./locales/hi.ts":()=>import("./hi-BOMkDPqC.mjs"),"./locales/pt.ts":()=>import("./pt-Cc4zysaT.mjs"),"./locales/ru.ts":()=>import("./ru-CwyPz2Va.mjs"),"./locales/zh.ts":()=>import("./zh-DgSmvLyw.mjs")});async function g(t){return r(v,t,f)}var w={BurgerMenu:"burger-menu",Flow:"flow",None:"none"},x="notectl-toolbar-btn--overflow-hidden",y="notectl-toolbar-separator--overflow-hidden",A="notectl-toolbar-group--overflow-hidden",E="notectl-toolbar-group",_="notectl-toolbar-separator",k=class{toolbar;context;onOverflowChange;onItemActivated;getActiveElement;ariaLabel;popupManager;entries=[];overflowButton=null;overflowDropdown=null;overflowHandle=null;overflowEntries=[];resizeObserver=null;closeHandler=null;closeHandlerTimer=null;closeHandlerAttached=!1;constructor(t){this.toolbar=t.toolbar,this.ariaLabel=t.ariaLabel,this.context=t.context,this.onOverflowChange=t.onOverflowChange,this.onItemActivated=t.onItemActivated,this.getActiveElement=t.getActiveElement,this.popupManager=t.popupManager??null,this.resizeObserver=new ResizeObserver(()=>this.recalculate()),this.resizeObserver.observe(this.toolbar)}update(t){this.entries=t.map(t=>({element:t.element,item:t.item})),this.recalculate()}recalculate(){if(0===this.entries.length)return;this.closeDropdown(),this.resetVisibility(),this.ensureOverflowButton(),this.setOverflowButtonVisible(!1);const t=this.measureAvailableWidth(),e=Array.from(this.toolbar.children),o=this.measureChildWidths(e),n=t-34-2;let r=0,i=!1;const l=[];for(const s of e){if(s===this.overflowButton)continue;if(s.classList.contains(_)){const t=(o.get(s)??0)+2;i||r+t>n?(i=!0,s.classList.add(y)):r+=t;continue}if(s.classList.contains(E)){const t=(o.get(s)??0)+2,e=this.entriesInside(s);i||r+t>n?(i=!0,this.hideGroup(s,e,l)):r+=t;continue}const t=this.entries.find(t=>t.element===s);if(!t)continue;const e=(o.get(s)??0)+2;i||r+e>n?(i=!0,t.element.classList.add(x),l.push(t)):r+=e}this.overflowEntries=l,this.hideTrailingSeparators(),this.setOverflowButtonVisible(l.length>0),this.notifyChange()}hideGroup(t,e,o){t.classList.add(A);for(const n of e)n.element.classList.add(x),o.push(n)}entriesInside(t){const e=[];for(const o of this.entries)t.contains(o.element)&&e.push(o);return e}updateItemStates(t){if(!this.overflowDropdown)return;const e=Array.from(this.overflowDropdown.querySelectorAll(".notectl-dropdown__item"));for(const o of e){const e=o.getAttribute("data-toolbar-item"),n=this.overflowEntries.find(t=>t.item.id===e);if(!n)continue;const r=n.item.isActive?.(t)??!1,i=n.item.isEnabled?.(t)??!0;if(o.classList.toggle("notectl-dropdown__item--active",r),o.disabled=!i,"combobox"===n.item.popupType){const e=o.querySelector(".notectl-dropdown__item-label");e&&(e.textContent=n.item.getLabel(t))}if(n.item.getIcon){const e=n.item.getIcon(t),r=o.querySelector(".notectl-dropdown__item-icon");r&&r.innerHTML!==e&&(r.innerHTML=e)}}}destroy(){this.resizeObserver?.disconnect(),this.resizeObserver=null,this.closeDropdown(),this.overflowButton?.remove(),this.overflowButton=null,this.entries=[],this.overflowEntries=[]}measureChildWidths(t){const e=/* @__PURE__ */new Map;for(const o of t)o!==this.overflowButton&&e.set(o,o.offsetWidth);return e}measureAvailableWidth(){const t=getComputedStyle(this.toolbar),e=Number.parseFloat(t.paddingLeft)||0,o=Number.parseFloat(t.paddingRight)||0;return this.toolbar.clientWidth-e-o}resetVisibility(){for(const o of this.entries)o.element.classList.remove(x);const t=Array.from(this.toolbar.querySelectorAll(`.${_}`));for(const o of t)o.classList.remove(y);const e=Array.from(this.toolbar.querySelectorAll(`.${E}`));for(const o of e)o.classList.remove(A)}setOverflowButtonVisible(t){this.overflowButton&&(this.overflowButton.classList.toggle("notectl-toolbar-overflow-btn--hidden",!t),t||this.overflowButton.removeAttribute("tabindex"))}ensureOverflowButton(){if(this.overflowButton)return;const t=document.createElement("button");t.type="button",t.className="notectl-toolbar-overflow-btn",t.setAttribute("aria-label",this.ariaLabel),t.setAttribute("aria-haspopup","true"),t.setAttribute("aria-expanded","false"),t.setAttribute("part","toolbar-button toolbar-overflow-button"),t.innerHTML='<svg viewBox="0 0 16 16" width="16" height="16"><circle cx="3" cy="8" r="1.5" fill="currentColor"/><circle cx="8" cy="8" r="1.5" fill="currentColor"/><circle cx="13" cy="8" r="1.5" fill="currentColor"/></svg>',t.addEventListener("mousedown",t=>{t.preventDefault(),this.toggleDropdown()}),this.toolbar.appendChild(t),this.overflowButton=t}toggleDropdown(){this.overflowDropdown?this.closeDropdown():this.openDropdown()}openDropdown(){if(!this.overflowButton||0===this.overflowEntries.length)return;const t=document.createElement("div");t.className="notectl-toolbar-popup notectl-dropdown",t.setAttribute("role","menu"),this.renderDropdownItems(t,this.context.getState()),this.popupManager?(this.overflowHandle=this.popupManager.open({anchor:this.overflowButton,className:"notectl-toolbar-popup notectl-dropdown",ariaRole:"menu",position:"below-end",referenceNode:this.overflowButton,restoreFocusTo:this.overflowButton,onClose:()=>{this.overflowHandle=null,this.overflowDropdown=null,this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false")},content:t=>{this.renderDropdownItems(t,this.context.getState()),this.overflowDropdown=t,t.addEventListener("keydown",t=>this.handleDropdownKeydown(t))}}),this.overflowButton.setAttribute("aria-expanded","true")):(this.positionDropdown(t),p(t,this.overflowButton),this.overflowDropdown=t,this.overflowButton.setAttribute("aria-expanded","true"),requestAnimationFrame(()=>{t.querySelector('[role="menuitem"]')?.focus()}),t.addEventListener("keydown",t=>this.handleDropdownKeydown(t)),this.registerCloseHandler())}renderDropdownItems(t,e){let o=null;for(const n of this.overflowEntries){if(null!==o&&n.item.group!==o){const e=document.createElement("div");e.className="notectl-dropdown__separator",e.setAttribute("role","separator"),t.appendChild(e)}o=n.item.group;const r=document.createElement("button");r.type="button",r.className="notectl-dropdown__item",r.setAttribute("role","menuitem"),r.setAttribute("tabindex","-1"),r.setAttribute("data-toolbar-item",n.item.id);const i=document.createElement("span");i.className="notectl-dropdown__item-icon","combobox"!==n.item.popupType&&(i.innerHTML=n.item.icon),r.appendChild(i);const l=document.createElement("span");l.className="notectl-dropdown__item-label",l.textContent="combobox"===n.item.popupType?n.item.getLabel(e):n.item.tooltip??n.item.label,r.appendChild(l),r.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),this.activateOverflowItem(n)}),t.appendChild(r)}}positionDropdown(e){if(!this.overflowButton)return;const o=this.overflowButton.getBoundingClientRect(),n=t(this.toolbar);d(e,o,{position:n?"below-start":"below-end",isRtl:n})}registerCloseHandler(){this.closeHandler=t=>{const e=t.composedPath();this.overflowDropdown&&!e.includes(this.overflowDropdown)&&this.overflowButton&&!e.includes(this.overflowButton)&&this.closeDropdown()},this.closeHandlerTimer=setTimeout(()=>{this.closeHandlerTimer=null,this.closeHandler&&this.overflowDropdown&&(document.addEventListener("mousedown",this.closeHandler),this.closeHandlerAttached=!0)},0)}closeDropdown(){if(this.overflowHandle){const t=this.overflowHandle;return this.overflowHandle=null,this.overflowDropdown=null,t.close(),void(this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false"))}this.overflowDropdown&&(this.overflowDropdown.remove(),this.overflowDropdown=null),this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false"),this.closeHandler&&(null!==this.closeHandlerTimer&&(clearTimeout(this.closeHandlerTimer),this.closeHandlerTimer=null),this.closeHandlerAttached&&(document.removeEventListener("mousedown",this.closeHandler),this.closeHandlerAttached=!1),this.closeHandler=null)}activateOverflowItem(t){this.closeDropdown(),t.item.popupType&&this.overflowButton?this.onItemActivated(this.overflowButton,t.item):this.context.executeCommand(t.item.command)}handleDropdownKeydown(t){if(!this.overflowDropdown)return;if("Escape"===t.key||"Tab"===t.key)return t.preventDefault(),t.stopPropagation(),this.closeDropdown(),void this.overflowButton?.focus();const e=Array.from(this.overflowDropdown.querySelectorAll('[role="menuitem"]')),o=e.indexOf(this.getActiveElement());switch(t.key){case"ArrowDown":t.preventDefault(),e[l(e,o,1)]?.focus();break;case"ArrowUp":t.preventDefault(),e[l(e,o,-1)]?.focus();break;case"Enter":case" ":{t.preventDefault();const n=e[o];if(!n)break;const r=n.getAttribute("data-toolbar-item"),i=this.overflowEntries.find(t=>t.item.id===r);i&&this.activateOverflowItem(i);break}}}hideTrailingSeparators(){const t=Array.from(this.toolbar.children);for(let e=t.length-1;e>=0;e--){const o=t[e];if(!o||o===this.overflowButton)continue;if(o.classList.contains(_)){o.classList.contains(y)||o.classList.add(y);continue}const n=o.classList.contains(E)&&o.classList.contains(A),r=o.classList.contains("notectl-toolbar-btn")&&o.classList.contains(x);if(!n&&!r)break}}notifyChange(){const t=this.entries.filter(t=>!t.element.classList.contains(x)).map(t=>t.element);this.onOverflowChange(t,this.overflowEntries.length>0?this.overflowButton:null)}};function C(t,e,o){const n=t.querySelectorAll(".notectl-grid-picker__cell");for(const r of n){const t=Number(r.getAttribute("data-row")),n=Number(r.getAttribute("data-col"));r.classList.toggle("notectl-grid-picker__cell--highlighted",t<=e&&n<=o)}}function B(){const t=document.createElement("span");return t.className="notectl-toolbar-separator",t.setAttribute("role","separator"),t.setAttribute("part","toolbar-divider"),t}var L=class{activePopup=null;activePopupButton=null;activeHandle=null;getActiveElement;locale;popupManager=null;constructor(t,e=f){this.getActiveElement=t,this.locale=e}setPopupManager(t){this.popupManager=t}isOpen(){return null!==this.activePopup}toggle(t,e,o){this.activePopup?this.close():this.openViaManager(t,e,o)}close(){if(this.activeHandle){const t=this.activeHandle;return this.activeHandle=null,this.clearButtonState(),void t.close()}this.clearButtonState(),this.activePopup&&(this.activePopup.remove(),this.activePopup=null)}closeAndRestoreFocus(){const t=this.activePopupButton;this.close(),t?.focus()}destroy(){this.close()}openViaManager(t,e,o){this.popupManager&&(this.activePopupButton=t,t.classList.add("notectl-toolbar-btn--popup-open"),t.setAttribute("aria-expanded","true"),this.activeHandle=this.popupManager.open({anchor:t,className:"notectl-toolbar-popup",referenceNode:t,restoreFocusTo:t,position:"below-start",onClose:()=>{this.activeHandle=null,this.clearButtonState(),this.activePopup=null},content:(t,n)=>{this.activePopup=t,this.renderPopupContent(t,e,o,n),t.addEventListener("keydown",t=>this.handlePopupKeydown(t))}}))}renderPopupContent(t,e,n,r){const i=()=>{r({restoreFocusTo:null}),n.getContainer().focus()};switch(e.popupType){case"gridPicker":!function(t,e,n,r=f){t.className+=" notectl-grid-picker";const i=document.createElement("div");i.className="notectl-grid-picker__grid",i.setAttribute("role","grid"),o(i,{display:"grid",gridTemplateColumns:`repeat(${e.maxCols}, 1fr)`,gap:"2px",padding:"8px"});const l=document.createElement("div");l.className="notectl-grid-picker__label",l.textContent=r.gridPickerLabel(1,1),o(l,{textAlign:"center",padding:"4px",fontSize:"12px"}),l.setAttribute("aria-live","polite");for(let s=1;s<=e.maxRows;s++)for(let t=1;t<=e.maxCols;t++){const a=document.createElement("div");a.className="notectl-grid-picker__cell",a.setAttribute("role","gridcell"),a.setAttribute("tabindex","-1"),a.setAttribute("aria-label",r.gridPickerLabel(s,t)),o(a,{width:"20px",height:"20px",border:"1px solid #ccc",cursor:"pointer"}),a.setAttribute("data-row",String(s)),a.setAttribute("data-col",String(t)),a.addEventListener("mouseenter",()=>{C(i,s,t),l.textContent=r.gridPickerLabel(s,t)}),a.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),a.addEventListener("click",()=>{e.onSelect(s,t),n()}),i.appendChild(a)}t.appendChild(i),t.appendChild(l)}(t,e.popupConfig,i,this.locale);break;case"dropdown":!function(t,e,o,r){t.classList.add("notectl-dropdown"),t.setAttribute("role","menu");for(const i of e.items){const e=document.createElement("button");if(e.type="button",e.className="notectl-dropdown__item",e.setAttribute("role","menuitem"),e.setAttribute("tabindex","-1"),i.icon){const t=document.createElement("span");t.className="notectl-dropdown__item-icon",t.innerHTML=i.icon,e.appendChild(t)}const o=document.createElement("span");o.className="notectl-dropdown__item-label",o.textContent=i.label,e.appendChild(o),e.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),e.addEventListener("click",()=>{var t;t=i.command,n.executeCommand(t),r()}),t.appendChild(e)}}(t,e.popupConfig,0,i);break;case"custom":case"combobox":e.renderPopup(t,n,r)}}clearButtonState(){this.activePopupButton&&(this.activePopupButton.classList.remove("notectl-toolbar-btn--popup-open"),this.activePopupButton.setAttribute("aria-expanded","false"),this.activePopupButton=null)}handlePopupKeydown(t){if(!this.activePopup)return;if("Escape"===t.key)return t.preventDefault(),t.stopPropagation(),void this.closeAndRestoreFocus();if("Tab"===t.key)return t.preventDefault(),void this.closeAndRestoreFocus();const e=this.activePopup.querySelectorAll('[role="menuitem"]');e.length>0?this.handleDropdownKeydown(t,e):null===this.activePopup.querySelector(".notectl-grid-picker__cell")?this.handleCustomPopupKeydown(t):this.handleGridKeydown(t)}handleDropdownKeydown(t,e){const o=Array.from(e),n=o.indexOf(this.getActiveElement());switch(t.key){case"ArrowDown":t.preventDefault(),o[l(o,n,1)]?.focus();break;case"ArrowUp":t.preventDefault(),o[l(o,n,-1)]?.focus();break;case"Enter":case" ":{t.preventDefault();const e=o[n];e&&e.click();break}}}handleGridKeydown(e){const o=this.getActiveElement(),n=Number(o?.getAttribute("data-row")??1),r=Number(o?.getAttribute("data-col")??1),i=this.activePopup?.querySelector(".notectl-grid-picker__grid")??null;if(!i)return;const l=i.querySelector(".notectl-grid-picker__cell:last-child"),a=Number(l?.getAttribute("data-col")??1),c=Number(l?.getAttribute("data-row")??1);if(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(e.key)){e.preventDefault();const[o,l]=s(n,r,c,a,e.key,!!this.activePopup&&t(this.activePopup));i.querySelector(`.notectl-grid-picker__cell[data-row="${o}"][data-col="${l}"]`)?.focus(),C(i,o,l);const d=this.activePopup?.querySelector(".notectl-grid-picker__label")??null;d&&(d.textContent=this.locale.gridPickerLabel(o,l))}"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),o?.click())}handleCustomPopupKeydown(t){if(!this.activePopup)return;const e=Array.from(this.activePopup.querySelectorAll("button"));if(0===e.length)return;const o=this.getActiveElement(),n=e.indexOf(o);switch(t.key){case"ArrowDown":t.preventDefault(),e[l(e,n,1)]?.focus();break;case"ArrowUp":t.preventDefault(),e[l(e,n,-1)]?.focus();break;case"Enter":case" ":t.preventDefault(),o&&((r=o).dispatchEvent(new MouseEvent("mousedown",{bubbles:!0,cancelable:!0})),r.dispatchEvent(new MouseEvent("mouseup",{bubbles:!0,cancelable:!0})),r.click())}var r}},I=class t{element;timer=null;target=null;isPopupActive;static TOOLTIP_ID="notectl-toolbar-tooltip";constructor(o){this.isPopupActive=o,this.element=document.createElement("div"),this.element.className="notectl-toolbar-tooltip",this.element.id=t.TOOLTIP_ID,this.element.setAttribute("role","tooltip"),e(this.element,"display","none")}show(n){if(this.hide(),this.isPopupActive()||n.disabled)return;const r=n.getAttribute("data-tooltip");r&&(this.target=n,this.timer=setTimeout(()=>{if(this.isPopupActive())return;this.element.textContent=r,e(this.element,"display","");const i=n.getRootNode();i instanceof ShadowRoot&&!this.element.parentNode?i.appendChild(this.element):i instanceof ShadowRoot||this.element.parentNode||document.body.appendChild(this.element),n.setAttribute("aria-describedby",t.TOOLTIP_ID);const l=n.getBoundingClientRect();e(this.element,"position","fixed");const s=c(this.element);o(this.element,{top:l.bottom+6-s.y+"px",left:l.left+l.width/2-s.x+"px",transform:"translateX(-50%)"})},500))}hide(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.target&&(this.target.removeAttribute("aria-describedby"),this.target=null),e(this.element,"display","none")}destroy(){this.hide(),this.element.remove()}};function P(t){if(Array.isArray(t))return{plugins:t,label:void 0};const e=t;return{plugins:e.plugins,label:e.label}}var T=new n("toolbar"),D=class{id="toolbar";name="Toolbar";priority=10;context=null;toolbarElement=null;buttons=[];hiddenItems=/* @__PURE__ */new Set;layoutConfig;overflowBehavior;focusedIndex=0;tooltip=null;popupController=null;popupManager=null;overflowController=null;visibleElements=[];locale;constructor(t){this.layoutConfig=t??null,this.overflowBehavior=t?.overflow??w.BurgerMenu}async init(t){this.locale=await i(t,void 0,f,g),t.registerStyleSheet('\n/* Toolbar */\n.notectl-plugin-container--top {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: nowrap;\n\tborder-bottom: 1px solid var(--notectl-border);\n\tbackground: var(--notectl-toolbar-bg, var(--notectl-surface-raised));\n\tmin-height: 40px;\n\tflex-shrink: 0;\n}\n\n.notectl-toolbar {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: nowrap;\n\toverflow: hidden;\n\tflex: 1;\n\tmin-width: 0;\n\tgap: 2px;\n\tpadding: 4px 8px;\n}\n\n.notectl-toolbar[hidden] {\n\tdisplay: none;\n}\n\n/* Group wrapper — real flex container so consumers can style it via ::part(toolbar-group)\n with padding/background/border directly. Group gap mirrors the toolbar gap so the\n visual rhythm between buttons stays uniform whether or not a group boundary lies between them. */\n.notectl-toolbar-group {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 2px;\n}\n\n.notectl-toolbar-group--overflow-hidden {\n\tdisplay: none;\n}\n\n.notectl-toolbar-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid transparent;\n\tborder-radius: 4px;\n\tbackground: var(--notectl-toolbar-button-bg, transparent);\n\tcursor: pointer;\n\tcolor: var(--notectl-toolbar-button-fg, var(--notectl-fg));\n\tfont-size: 14px;\n\tline-height: 1;\n\tpadding: 0;\n\tflex-shrink: 0;\n\ttransition: background 0.1s, border-color 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn:hover {\n\t\tbackground: var(--notectl-toolbar-button-hover-bg, var(--notectl-hover-bg));\n\t\tborder-color: var(--notectl-border);\n\t}\n}\n\n.notectl-toolbar-btn--active {\n\tbackground: var(--notectl-toolbar-button-active-bg, var(--notectl-active-bg));\n\tborder-color: var(--notectl-primary-muted);\n\tcolor: var(--notectl-toolbar-button-active-fg, var(--notectl-primary-fg));\n}\n\n.notectl-toolbar-btn:focus-visible {\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n\toutline: none;\n}\n\n.notectl-toolbar-btn:disabled {\n\topacity: 0.4;\n\tcursor: not-allowed;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn:disabled:hover {\n\t\tbackground: transparent;\n\t\tborder-color: transparent;\n\t}\n}\n\n.notectl-toolbar-btn__icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpointer-events: none;\n}\n\n.notectl-toolbar-btn__icon svg {\n\tdisplay: block;\n\twidth: 18px;\n\theight: 18px;\n\tfill: currentColor;\n}\n\n/* Tooltip (rendered as fixed-position element in shadow root) */\n.notectl-toolbar-tooltip {\n\tpadding: 4px 8px;\n\tborder-radius: 4px;\n\tbackground: var(--notectl-tooltip-bg);\n\tcolor: var(--notectl-tooltip-fg);\n\tfont-size: 11px;\n\tfont-weight: 500;\n\twhite-space: nowrap;\n\tpointer-events: none;\n\tz-index: 10001;\n\tline-height: 1.4;\n\tletter-spacing: 0.01em;\n\tfont-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;\n}\n\n.notectl-toolbar-separator {\n\tdisplay: inline-block;\n\twidth: 1px;\n\theight: 20px;\n\tbackground: var(--notectl-border);\n\tmargin: 0 4px;\n\tvertical-align: middle;\n}\n\n/* Toolbar Popups */\n.notectl-toolbar-popup {\n\tbackground: var(--notectl-surface-overlay);\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 6px;\n\tbox-shadow: 0 4px 12px var(--notectl-shadow);\n\toverflow: hidden;\n}\n\n/* Grid Picker */\n.notectl-grid-picker__cell:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n\n.notectl-grid-picker__cell--highlighted {\n\tbackground: var(--notectl-primary-muted);\n\tborder-color: var(--notectl-primary);\n}\n\n/* Dropdown */\n.notectl-dropdown {\n\tmin-width: 160px;\n\tpadding: 4px 0;\n}\n\n.notectl-dropdown__item {\n\tdisplay: flex;\n\talign-items: center;\n\twidth: 100%;\n\tpadding: 8px 12px;\n\ttext-align: start;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: var(--notectl-fg);\n\tline-height: 1.4;\n\tfont-family: inherit;\n\twhite-space: nowrap;\n}\n\n@media (hover: hover) {\n\t.notectl-dropdown__item:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-dropdown__item:focus-visible {\n\tbackground: var(--notectl-hover-bg);\n\toutline: none;\n}\n\n.notectl-dropdown__item-icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\tfont-weight: 600;\n\tcolor: var(--notectl-fg-muted);\n\tflex-shrink: 0;\n}\n\n.notectl-dropdown__item-label {\n\tflex: 1;\n}\n\n/* Overflow behavior: flow mode — toolbar wraps to additional rows */\n.notectl-toolbar[data-overflow="flow"] {\n\tflex-wrap: wrap;\n\toverflow: visible;\n}\n\n/* Overflow behavior: none — toolbar clips without any responsive behavior */\n.notectl-toolbar[data-overflow="none"] {\n\tflex-wrap: nowrap;\n\toverflow: hidden;\n}\n\n/* Overflow: hidden items (burger-menu mode) */\n.notectl-toolbar-btn--overflow-hidden,\n.notectl-toolbar-separator--overflow-hidden {\n\tdisplay: none;\n}\n\n/* Overflow "more" button */\n.notectl-toolbar-overflow-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid transparent;\n\tborder-radius: 4px;\n\tbackground: transparent;\n\tcursor: pointer;\n\tcolor: var(--notectl-fg);\n\tfont-size: 16px;\n\tline-height: 1;\n\tpadding: 0;\n\tflex-shrink: 0;\n\tmargin-inline-start: auto;\n\ttransition: background 0.1s, border-color 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-overflow-btn:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t\tborder-color: var(--notectl-border);\n\t}\n}\n\n.notectl-toolbar-overflow-btn--hidden {\n\tdisplay: none;\n}\n\n.notectl-toolbar-overflow-btn:focus-visible {\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n\toutline: none;\n}\n\n/* Dropdown item states shared by all dropdown menus (including overflow) */\n.notectl-dropdown__item:disabled {\n\topacity: 0.4;\n\tcursor: not-allowed;\n}\n\n@media (hover: hover) {\n\t.notectl-dropdown__item:disabled:hover {\n\t\tbackground: none;\n\t}\n}\n\n.notectl-dropdown__item--active {\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-dropdown__item-icon svg {\n\tdisplay: block;\n\twidth: 16px;\n\theight: 16px;\n\tfill: currentColor;\n}\n\n.notectl-dropdown__separator {\n\theight: 1px;\n\tbackground: var(--notectl-border);\n\tmargin: 4px 0;\n}\n\n/* Combobox-style toolbar buttons (shared base for font, fontSize, heading, etc.) */\n.notectl-toolbar-btn[role="combobox"] {\n\twidth: auto;\n\tpadding: 0 8px;\n\tgap: 4px;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-toolbar-bg, var(--notectl-surface-raised));\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn[role="combobox"]:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t\tborder-color: var(--notectl-fg-muted);\n\t}\n}\n\n.notectl-toolbar-btn[role="combobox"].notectl-toolbar-btn--active {\n\tbackground: var(--notectl-toolbar-bg, var(--notectl-surface-raised));\n\tborder-color: var(--notectl-primary-muted);\n}\n\n.notectl-toolbar-combobox__label {\n\tflex: 1;\n\tfont-size: 13px;\n\tfont-weight: 500;\n\tcolor: var(--notectl-fg);\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\ttext-align: start;\n\tline-height: 30px;\n}\n\n.notectl-toolbar-combobox__arrow {\n\tflex-shrink: 0;\n\tfont-size: 11px;\n\tcolor: var(--notectl-fg-muted);\n\tline-height: 30px;\n}\n\n/* Link Popup */\n.notectl-link-popup {\n\tpadding: 8px;\n\tmin-width: 200px;\n}\n\n.notectl-link-popup__input {\n\twidth: 100%;\n\tpadding: 4px;\n\tbox-sizing: border-box;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tfont-size: 13px;\n\tcolor: var(--notectl-fg);\n\tbackground: var(--notectl-surface-overlay);\n}\n\n.notectl-link-popup__input:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n\n.notectl-link-popup__button {\n\twidth: 100%;\n\tpadding: 6px 12px;\n\tcursor: pointer;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-overlay);\n\tcolor: var(--notectl-fg);\n\tfont-size: 13px;\n}\n\n.notectl-link-popup__button--apply {\n\tmargin-top: 4px;\n}\n\n@media (hover: hover) {\n\t.notectl-link-popup__button:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-link-popup__button:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n'),this.context=t,this.popupManager=new h(t.getContainer()),t.registerService(u,this.popupManager),this.popupController=new L(()=>this.getActiveElement(),this.locale),this.popupController.setPopupManager(this.popupManager),this.tooltip=new I(()=>this.popupController?.isOpen()??!1),t.registerService(T,{refresh:()=>this.updateButtonStates(t.getState()),closePopup:()=>this.popupController?.close()}),this.createToolbarElement()}getOverflowBehavior(){return this.overflowBehavior}setOverflowBehavior(t){t!==this.overflowBehavior&&(this.overflowBehavior=t,this.applyOverflowBehavior(),this.renderItems())}onReady(){this.renderItems()}destroy(){this.overflowController?.destroy(),this.overflowController=null,this.popupController?.destroy(),this.popupController=null,this.popupManager?.destroy(),this.popupManager=null,this.tooltip?.destroy(),this.tooltip=null,this.toolbarElement&&(this.toolbarElement.remove(),this.toolbarElement=null),this.buttons=[],this.visibleElements=[],this.context=null}onStateChange(t,e,o){this.updateButtonStates(e)}onReadOnlyChange(t){this.toolbarElement&&(this.toolbarElement.hidden=t)}onConfigure(t){for(const[e,o]of Object.entries(t))!1===o?this.hiddenItems.add(e):this.hiddenItems.delete(e);this.renderItems()}createToolbarElement(){if(!this.context)return;this.toolbarElement&&this.toolbarElement.remove(),this.buttons=[];const t=this.context.getPluginContainer("top");this.toolbarElement=document.createElement("div"),this.toolbarElement.setAttribute("role","toolbar"),this.toolbarElement.setAttribute("aria-label",this.locale.formattingOptionsAria),this.toolbarElement.setAttribute("data-notectl-no-print",""),this.toolbarElement.setAttribute("part","toolbar"),this.toolbarElement.className="notectl-toolbar",this.toolbarElement.addEventListener("keydown",t=>this.handleToolbarKeydown(t)),this.applyOverflowBehavior(),t.appendChild(this.toolbarElement)}applyOverflowBehavior(){this.toolbarElement&&this.context&&(this.overflowController?.destroy(),this.overflowController=null,this.toolbarElement.setAttribute("data-overflow",this.overflowBehavior),this.overflowBehavior===w.BurgerMenu?this.overflowController=new k({toolbar:this.toolbarElement,ariaLabel:this.locale.moreToolsAria,context:this.context,popupManager:this.popupManager??void 0,onOverflowChange:(t,e)=>{this.visibleElements=e?[...t,e]:[...t],this.initRovingTabindex()},onItemActivated:(t,e)=>{this.activateButton(t,e)},getActiveElement:()=>this.getActiveElement()}):this.visibleElements=[])}renderItems(){if(this.context&&this.toolbarElement){for(const t of this.buttons)t.element.remove();this.buttons=[];for(const t of this.toolbarElement.querySelectorAll(".notectl-toolbar-separator"))t.remove();for(const t of this.toolbarElement.querySelectorAll(".notectl-toolbar-group"))t.remove();this.layoutConfig?this.renderItemsByLayout():this.renderItemsByGroup(),this.buttons.length>0&&!this.toolbarElement.parentElement&&this.context.getPluginContainer("top").appendChild(this.toolbarElement),this.overflowController?.update(this.buttons),this.initRovingTabindex(),this.updateButtonStates(this.context.getState())}}createGroupWrapper(t){const e=document.createElement("div");return e.className="notectl-toolbar-group",e.setAttribute("part","toolbar-group"),void 0!==t&&(e.setAttribute("role","group"),e.setAttribute("aria-label",t)),e}getTabElements(){return this.visibleElements.length>0?this.visibleElements:this.buttons.map(t=>t.element)}initRovingTabindex(){const t=this.getTabElements(),e=m(t);this.focusedIndex=e>=0?e:0,a(t,this.focusedIndex)}setRovingFocus(t){const e=this.getTabElements();t<0||t>=e.length||(this.focusedIndex=t,a(e,t),e[t]?.focus())}getActiveElement(){const t=this.toolbarElement?.getRootNode();return t instanceof ShadowRoot?t.activeElement:document.activeElement}syncFocusedIndex(){const t=this.getActiveElement(),e=this.getTabElements().findIndex(e=>e===t);e>=0&&(this.focusedIndex=e)}handleToolbarKeydown(e){const o=this.getTabElements();var n;if(0!==o.length)switch(this.syncFocusedIndex(),e.key){case"ArrowRight":case"ArrowLeft":{e.preventDefault();const r=(n=!!this.toolbarElement&&t(this.toolbarElement),"ArrowRight"===e.key?n?-1:1:n?1:-1),i=function(t,e,o){const n=t.length;if(0===n)return-1;let r=e;for(let i=0;i<n;i++)if(r=(r+o+n)%n,!t[r]?.disabled)return r;return e}(o,this.focusedIndex,r);this.setRovingFocus(i);break}case"Home":{e.preventDefault();const t=m(o);t>=0&&this.setRovingFocus(t);break}case"End":{e.preventDefault();const t=function(t){for(let e=t.length-1;e>=0;e--)if(!t[e]?.disabled)return e;return-1}(o);t>=0&&this.setRovingFocus(t);break}case"Enter":case" ":{e.preventDefault();const t=o[this.focusedIndex],n=this.buttons.find(e=>e.element===t);n&&this.activateButton(n.element,n.item);break}}}activateButton(t,e){this.tooltip?.hide(),e.popupType&&this.context?this.popupController?.toggle(t,e,this.context):this.context?.executeCommand(e.command)}renderItemsByLayout(){if(!this.context||!this.toolbarElement||!this.layoutConfig)return;const t=this.context.getToolbarRegistry();let e=!0;for(const o of this.layoutConfig.groups){const{plugins:n,label:r}=P(o),i=[];for(const e of n){const o=t.getToolbarItemsByPlugin(e).filter(t=>!this.hiddenItems.has(t.id));i.push(...o)}if(0===i.length)continue;e||this.toolbarElement.appendChild(B()),e=!1;const l=this.createGroupWrapper(r);for(const t of i){const e=this.createButton(t);l.appendChild(e.element),this.buttons.push(e)}this.toolbarElement.appendChild(l)}0===this.buttons.length&&this.toolbarElement.remove()}renderItemsByGroup(){if(!this.context||!this.toolbarElement)return;const t=this.context.getToolbarRegistry().getToolbarItems().filter(t=>!this.hiddenItems.has(t.id));if(0===t.length)return void this.toolbarElement.remove();const e=/* @__PURE__ */new Map;for(const n of t){const t=e.get(n.group)??[];t.push(n),e.set(n.group,t)}let o=!0;for(const[,n]of e){o||this.toolbarElement.appendChild(B()),o=!1;const t=this.createGroupWrapper(void 0);for(const e of n){const o=this.createButton(e);t.appendChild(o.element),this.buttons.push(o)}this.toolbarElement.appendChild(t)}}createButton(t){const e=document.createElement("button");e.type="button",e.className=`notectl-toolbar-btn notectl-toolbar-btn--${t.id}`,e.setAttribute("aria-pressed","false"),e.setAttribute("aria-label",t.label),e.setAttribute("data-toolbar-item",t.id),e.setAttribute("data-tooltip",t.tooltip??t.label),e.setAttribute("part","toolbar-button");let o=null;if("combobox"===t.popupType){e.setAttribute("role","combobox"),e.setAttribute("aria-haspopup","listbox"),e.setAttribute("aria-expanded","false");const n=document.createElement("span");n.className="notectl-toolbar-combobox__label";const r=this.context?.getState();r&&(n.textContent=t.getLabel(r)),e.appendChild(n),o=n;const i=document.createElement("span");i.className="notectl-toolbar-combobox__arrow",i.setAttribute("aria-hidden","true"),i.textContent="▾",e.appendChild(i)}else{t.popupType&&(e.setAttribute("aria-haspopup","true"),e.setAttribute("aria-expanded","false"));const o=document.createElement("span");o.className="notectl-toolbar-btn__icon",o.innerHTML=t.icon,e.appendChild(o)}return e.addEventListener("mousedown",o=>{o.preventDefault(),this.activateButton(e,t)}),e.addEventListener("mouseenter",()=>this.tooltip?.show(e)),e.addEventListener("mouseleave",()=>this.tooltip?.hide()),e.addEventListener("focus",()=>this.tooltip?.show(e)),e.addEventListener("blur",()=>this.tooltip?.hide()),{element:e,item:t,comboLabelEl:o}}updateButtonStates(t){for(const e of this.buttons){const o=e.item.isActive?.(t)??!1,n=e.item.isEnabled?.(t)??!0;if(e.element.setAttribute("aria-pressed",String(o)),e.element.classList.toggle("notectl-toolbar-btn--active",o),e.element.setAttribute("part",o?"toolbar-button toolbar-button-active":"toolbar-button"),e.element.disabled=!n,n?e.element.removeAttribute("aria-disabled"):e.element.setAttribute("aria-disabled","true"),e.comboLabelEl&&"combobox"===e.item.popupType&&(e.comboLabelEl.textContent=e.item.getLabel(t)),e.item.getIcon){const o=e.item.getIcon(t),n=e.element.querySelector(".notectl-toolbar-btn__icon");n&&n.innerHTML!==o&&(n.innerHTML=o)}}this.overflowController?.updateItemStates(t)}};export{g as a,f as i,T as n,b as o,w as r,D as t};
2
- //# sourceMappingURL=ToolbarPlugin-DVGrFf8v.mjs.map
1
+ import{i as t}from"./Platform-ByobkiCc.mjs";import{c as e,s as o}from"./StyleRuntime-DW6omotc.mjs";import{n}from"./TypedKeys-CA4bfw9O.mjs";import{c as r,o as i}from"./PluginHelpers-Dx_0hfDe.mjs";import{n as l,r as s,t as a}from"./KeyboardNav-D0my3wuy.mjs";import{i as c,r as d,t as p}from"./PopupPositioning-BFh6Ed1D.mjs";import{n as u,t as h}from"./PopupManager-CT-fMZJn.mjs";var b=class{_toolbarItems=/* @__PURE__ */new Map;_toolbarItemPluginMap=/* @__PURE__ */new Map;registerToolbarItem(t,e){if(this._toolbarItems.has(t.id))throw new Error(`ToolbarItem with id "${t.id}" is already registered.`);if(this._toolbarItems.set(t.id,t),e){const o=this._toolbarItemPluginMap.get(e)??[];o.push(t.id),this._toolbarItemPluginMap.set(e,o)}}getToolbarItemsByPlugin(t){const e=this._toolbarItemPluginMap.get(t)??[],o=[];for(const n of e){const t=this._toolbarItems.get(n);t&&o.push(t)}return o}getToolbarItem(t){return this._toolbarItems.get(t)}getToolbarItems(){return[...this._toolbarItems.values()]}removeToolbarItem(t){this._toolbarItems.delete(t);for(const[e,o]of this._toolbarItemPluginMap){const n=o.indexOf(t);if(-1!==n){o.splice(n,1),0===o.length&&this._toolbarItemPluginMap.delete(e);break}}}clear(){this._toolbarItems.clear(),this._toolbarItemPluginMap.clear()}};function m(t){for(let e=0;e<t.length;e++)if(!t[e]?.disabled)return e;return-1}var f={formattingOptionsAria:"Formatting options",moreToolsAria:"More tools",gridPickerLabel:(t,e)=>`${t} x ${e}`},v=/* #__PURE__ */Object.assign({"./locales/ar.ts":()=>import("./ar-C9lO1jsY.mjs"),"./locales/de.ts":()=>import("./de-BXQBXxFJ.mjs"),"./locales/es.ts":()=>import("./es-CXuMz87y.mjs"),"./locales/fr.ts":()=>import("./fr-fshsDD66.mjs"),"./locales/hi.ts":()=>import("./hi-BOMkDPqC.mjs"),"./locales/pt.ts":()=>import("./pt-Cc4zysaT.mjs"),"./locales/ru.ts":()=>import("./ru-CwyPz2Va.mjs"),"./locales/zh.ts":()=>import("./zh-DgSmvLyw.mjs")});async function g(t){return r(v,t,f)}var w={BurgerMenu:"burger-menu",Flow:"flow",None:"none"},x="notectl-toolbar-btn--overflow-hidden",y="notectl-toolbar-separator--overflow-hidden",A="notectl-toolbar-group--overflow-hidden",E="notectl-toolbar-group",_="notectl-toolbar-separator",k=class{toolbar;context;onOverflowChange;onItemActivated;getActiveElement;ariaLabel;popupManager;entries=[];overflowButton=null;overflowDropdown=null;overflowHandle=null;overflowEntries=[];resizeObserver=null;closeHandler=null;closeHandlerTimer=null;closeHandlerAttached=!1;constructor(t){this.toolbar=t.toolbar,this.ariaLabel=t.ariaLabel,this.context=t.context,this.onOverflowChange=t.onOverflowChange,this.onItemActivated=t.onItemActivated,this.getActiveElement=t.getActiveElement,this.popupManager=t.popupManager??null,this.resizeObserver=new ResizeObserver(()=>this.recalculate()),this.resizeObserver.observe(this.toolbar)}update(t){this.entries=t.map(t=>({element:t.element,item:t.item})),this.recalculate()}recalculate(){if(0===this.entries.length)return;this.closeDropdown(),this.resetVisibility(),this.ensureOverflowButton(),this.setOverflowButtonVisible(!1);const t=this.measureAvailableWidth(),e=Array.from(this.toolbar.children),o=this.measureChildWidths(e),n=t-34-2;let r=0,i=!1;const l=[];for(const s of e){if(s===this.overflowButton)continue;if(s.classList.contains(_)){const t=(o.get(s)??0)+2;i||r+t>n?(i=!0,s.classList.add(y)):r+=t;continue}if(s.classList.contains(E)){const t=(o.get(s)??0)+2,e=this.entriesInside(s);i||r+t>n?(i=!0,this.hideGroup(s,e,l)):r+=t;continue}const t=this.entries.find(t=>t.element===s);if(!t)continue;const e=(o.get(s)??0)+2;i||r+e>n?(i=!0,t.element.classList.add(x),l.push(t)):r+=e}this.overflowEntries=l,this.hideTrailingSeparators(),this.setOverflowButtonVisible(l.length>0),this.notifyChange()}hideGroup(t,e,o){t.classList.add(A);for(const n of e)n.element.classList.add(x),o.push(n)}entriesInside(t){const e=[];for(const o of this.entries)t.contains(o.element)&&e.push(o);return e}updateItemStates(t){if(!this.overflowDropdown)return;const e=Array.from(this.overflowDropdown.querySelectorAll(".notectl-dropdown__item"));for(const o of e){const e=o.getAttribute("data-toolbar-item"),n=this.overflowEntries.find(t=>t.item.id===e);if(!n)continue;const r=n.item.isActive?.(t)??!1,i=n.item.isEnabled?.(t)??!0;if(o.classList.toggle("notectl-dropdown__item--active",r),o.disabled=!i,"combobox"===n.item.popupType){const e=o.querySelector(".notectl-dropdown__item-label");e&&(e.textContent=n.item.getLabel(t))}if(n.item.getIcon){const e=n.item.getIcon(t),r=o.querySelector(".notectl-dropdown__item-icon");r&&r.innerHTML!==e&&(r.innerHTML=e)}}}destroy(){this.resizeObserver?.disconnect(),this.resizeObserver=null,this.closeDropdown(),this.overflowButton?.remove(),this.overflowButton=null,this.entries=[],this.overflowEntries=[]}measureChildWidths(t){const e=/* @__PURE__ */new Map;for(const o of t)o!==this.overflowButton&&e.set(o,o.offsetWidth);return e}measureAvailableWidth(){const t=getComputedStyle(this.toolbar),e=Number.parseFloat(t.paddingLeft)||0,o=Number.parseFloat(t.paddingRight)||0;return this.toolbar.clientWidth-e-o}resetVisibility(){for(const o of this.entries)o.element.classList.remove(x);const t=Array.from(this.toolbar.querySelectorAll(`.${_}`));for(const o of t)o.classList.remove(y);const e=Array.from(this.toolbar.querySelectorAll(`.${E}`));for(const o of e)o.classList.remove(A)}setOverflowButtonVisible(t){this.overflowButton&&(this.overflowButton.classList.toggle("notectl-toolbar-overflow-btn--hidden",!t),t||this.overflowButton.removeAttribute("tabindex"))}ensureOverflowButton(){if(this.overflowButton)return;const t=document.createElement("button");t.type="button",t.className="notectl-toolbar-overflow-btn",t.setAttribute("aria-label",this.ariaLabel),t.setAttribute("aria-haspopup","true"),t.setAttribute("aria-expanded","false"),t.setAttribute("part","toolbar-button toolbar-overflow-button"),t.innerHTML='<svg viewBox="0 0 16 16" width="16" height="16"><circle cx="3" cy="8" r="1.5" fill="currentColor"/><circle cx="8" cy="8" r="1.5" fill="currentColor"/><circle cx="13" cy="8" r="1.5" fill="currentColor"/></svg>',t.addEventListener("mousedown",t=>{t.preventDefault(),this.toggleDropdown()}),this.toolbar.appendChild(t),this.overflowButton=t}toggleDropdown(){this.overflowDropdown?this.closeDropdown():this.openDropdown()}openDropdown(){if(!this.overflowButton||0===this.overflowEntries.length)return;const t=document.createElement("div");t.className="notectl-toolbar-popup notectl-dropdown",t.setAttribute("role","menu"),this.renderDropdownItems(t,this.context.getState()),this.popupManager?(this.overflowHandle=this.popupManager.open({anchor:this.overflowButton,className:"notectl-toolbar-popup notectl-dropdown",ariaRole:"menu",position:"below-end",referenceNode:this.overflowButton,restoreFocusTo:this.overflowButton,onClose:()=>{this.overflowHandle=null,this.overflowDropdown=null,this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false")},content:t=>{this.renderDropdownItems(t,this.context.getState()),this.overflowDropdown=t,t.addEventListener("keydown",t=>this.handleDropdownKeydown(t))}}),this.overflowButton.setAttribute("aria-expanded","true")):(this.positionDropdown(t),p(t,this.overflowButton),this.overflowDropdown=t,this.overflowButton.setAttribute("aria-expanded","true"),requestAnimationFrame(()=>{t.querySelector('[role="menuitem"]')?.focus()}),t.addEventListener("keydown",t=>this.handleDropdownKeydown(t)),this.registerCloseHandler())}renderDropdownItems(t,e){let o=null;for(const n of this.overflowEntries){if(null!==o&&n.item.group!==o){const e=document.createElement("div");e.className="notectl-dropdown__separator",e.setAttribute("role","separator"),t.appendChild(e)}o=n.item.group;const r=document.createElement("button");r.type="button",r.className="notectl-dropdown__item",r.setAttribute("role","menuitem"),r.setAttribute("tabindex","-1"),r.setAttribute("data-toolbar-item",n.item.id);const i=document.createElement("span");i.className="notectl-dropdown__item-icon","combobox"!==n.item.popupType&&(i.innerHTML=n.item.icon),r.appendChild(i);const l=document.createElement("span");l.className="notectl-dropdown__item-label",l.textContent="combobox"===n.item.popupType?n.item.getLabel(e):n.item.tooltip??n.item.label,r.appendChild(l),r.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation(),this.activateOverflowItem(n)}),t.appendChild(r)}}positionDropdown(e){if(!this.overflowButton)return;const o=this.overflowButton.getBoundingClientRect(),n=t(this.toolbar);c(e,o,{position:n?"below-start":"below-end",isRtl:n})}registerCloseHandler(){this.closeHandler=t=>{const e=t.composedPath();this.overflowDropdown&&!e.includes(this.overflowDropdown)&&this.overflowButton&&!e.includes(this.overflowButton)&&this.closeDropdown()},this.closeHandlerTimer=setTimeout(()=>{this.closeHandlerTimer=null,this.closeHandler&&this.overflowDropdown&&(document.addEventListener("mousedown",this.closeHandler),this.closeHandlerAttached=!0)},0)}closeDropdown(){if(this.overflowHandle){const t=this.overflowHandle;return this.overflowHandle=null,this.overflowDropdown=null,t.close(),void(this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false"))}this.overflowDropdown&&(this.overflowDropdown.remove(),this.overflowDropdown=null),this.overflowButton&&this.overflowButton.setAttribute("aria-expanded","false"),this.closeHandler&&(null!==this.closeHandlerTimer&&(clearTimeout(this.closeHandlerTimer),this.closeHandlerTimer=null),this.closeHandlerAttached&&(document.removeEventListener("mousedown",this.closeHandler),this.closeHandlerAttached=!1),this.closeHandler=null)}activateOverflowItem(t){this.closeDropdown(),t.item.popupType&&this.overflowButton?this.onItemActivated(this.overflowButton,t.item):this.context.executeCommand(t.item.command)}handleDropdownKeydown(t){if(!this.overflowDropdown)return;if("Escape"===t.key||"Tab"===t.key)return t.preventDefault(),t.stopPropagation(),this.closeDropdown(),void this.overflowButton?.focus();const e=Array.from(this.overflowDropdown.querySelectorAll('[role="menuitem"]')),o=e.indexOf(this.getActiveElement());switch(t.key){case"ArrowDown":t.preventDefault(),e[l(e,o,1)]?.focus();break;case"ArrowUp":t.preventDefault(),e[l(e,o,-1)]?.focus();break;case"Enter":case" ":{t.preventDefault();const n=e[o];if(!n)break;const r=n.getAttribute("data-toolbar-item"),i=this.overflowEntries.find(t=>t.item.id===r);i&&this.activateOverflowItem(i);break}}}hideTrailingSeparators(){const t=Array.from(this.toolbar.children);for(let e=t.length-1;e>=0;e--){const o=t[e];if(!o||o===this.overflowButton)continue;if(o.classList.contains(_)){o.classList.contains(y)||o.classList.add(y);continue}const n=o.classList.contains(E)&&o.classList.contains(A),r=o.classList.contains("notectl-toolbar-btn")&&o.classList.contains(x);if(!n&&!r)break}}notifyChange(){const t=this.entries.filter(t=>!t.element.classList.contains(x)).map(t=>t.element);this.onOverflowChange(t,this.overflowEntries.length>0?this.overflowButton:null)}};function C(t,e,o){const n=t.querySelectorAll(".notectl-grid-picker__cell");for(const r of n){const t=Number(r.getAttribute("data-row")),n=Number(r.getAttribute("data-col"));r.classList.toggle("notectl-grid-picker__cell--highlighted",t<=e&&n<=o)}}function B(){const t=document.createElement("span");return t.className="notectl-toolbar-separator",t.setAttribute("role","separator"),t.setAttribute("part","toolbar-divider"),t}var L=class{activePopup=null;activePopupButton=null;activeHandle=null;getActiveElement;locale;popupManager=null;constructor(t,e=f){this.getActiveElement=t,this.locale=e}setPopupManager(t){this.popupManager=t}isOpen(){return null!==this.activePopup}toggle(t,e,o){this.activePopup?this.close():this.openViaManager(t,e,o)}close(){if(this.activeHandle){const t=this.activeHandle;return this.activeHandle=null,this.clearButtonState(),void t.close()}this.clearButtonState(),this.activePopup&&(this.activePopup.remove(),this.activePopup=null)}closeAndRestoreFocus(){const t=this.activePopupButton;this.close(),t?.focus()}destroy(){this.close()}openViaManager(t,e,o){this.popupManager&&(this.activePopupButton=t,t.classList.add("notectl-toolbar-btn--popup-open"),t.setAttribute("aria-expanded","true"),this.activeHandle=this.popupManager.open({anchor:t,className:"notectl-toolbar-popup",referenceNode:t,restoreFocusTo:t,position:"below-start",onClose:()=>{this.activeHandle=null,this.clearButtonState(),this.activePopup=null},content:(t,n)=>{this.activePopup=t,this.renderPopupContent(t,e,o,n),t.addEventListener("keydown",t=>this.handlePopupKeydown(t))}}))}renderPopupContent(t,e,n,r){const i=()=>{r({restoreFocusTo:null}),n.getContainer().focus()};switch(e.popupType){case"gridPicker":!function(t,e,n,r=f){t.className+=" notectl-grid-picker";const i=document.createElement("div");i.className="notectl-grid-picker__grid",i.setAttribute("role","grid"),o(i,{display:"grid",gridTemplateColumns:`repeat(${e.maxCols}, 1fr)`,gap:"2px",padding:"8px"});const l=document.createElement("div");l.className="notectl-grid-picker__label",l.textContent=r.gridPickerLabel(1,1),o(l,{textAlign:"center",padding:"4px",fontSize:"12px"}),l.setAttribute("aria-live","polite");for(let s=1;s<=e.maxRows;s++)for(let t=1;t<=e.maxCols;t++){const a=document.createElement("div");a.className="notectl-grid-picker__cell",a.setAttribute("role","gridcell"),a.setAttribute("tabindex","-1"),a.setAttribute("aria-label",r.gridPickerLabel(s,t)),o(a,{width:"20px",height:"20px",border:"1px solid #ccc",cursor:"pointer"}),a.setAttribute("data-row",String(s)),a.setAttribute("data-col",String(t)),a.addEventListener("mouseenter",()=>{C(i,s,t),l.textContent=r.gridPickerLabel(s,t)}),a.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),a.addEventListener("click",()=>{e.onSelect(s,t),n()}),i.appendChild(a)}t.appendChild(i),t.appendChild(l)}(t,e.popupConfig,i,this.locale);break;case"dropdown":!function(t,e,o,r){t.classList.add("notectl-dropdown"),t.setAttribute("role","menu");for(const i of e.items){const e=document.createElement("button");if(e.type="button",e.className="notectl-dropdown__item",e.setAttribute("role","menuitem"),e.setAttribute("tabindex","-1"),i.icon){const t=document.createElement("span");t.className="notectl-dropdown__item-icon",t.innerHTML=i.icon,e.appendChild(t)}const o=document.createElement("span");o.className="notectl-dropdown__item-label",o.textContent=i.label,e.appendChild(o),e.addEventListener("mousedown",t=>{t.preventDefault(),t.stopPropagation()}),e.addEventListener("click",()=>{var t;t=i.command,n.executeCommand(t),r()}),t.appendChild(e)}}(t,e.popupConfig,0,i);break;case"custom":case"combobox":e.renderPopup(t,n,r)}}clearButtonState(){this.activePopupButton&&(this.activePopupButton.classList.remove("notectl-toolbar-btn--popup-open"),this.activePopupButton.setAttribute("aria-expanded","false"),this.activePopupButton=null)}handlePopupKeydown(t){if(!this.activePopup)return;if("Escape"===t.key)return t.preventDefault(),t.stopPropagation(),void this.closeAndRestoreFocus();if("Tab"===t.key)return t.preventDefault(),void this.closeAndRestoreFocus();const e=this.activePopup.querySelectorAll('[role="menuitem"]');e.length>0?this.handleDropdownKeydown(t,e):null===this.activePopup.querySelector(".notectl-grid-picker__cell")?this.handleCustomPopupKeydown(t):this.handleGridKeydown(t)}handleDropdownKeydown(t,e){const o=Array.from(e),n=o.indexOf(this.getActiveElement());switch(t.key){case"ArrowDown":t.preventDefault(),o[l(o,n,1)]?.focus();break;case"ArrowUp":t.preventDefault(),o[l(o,n,-1)]?.focus();break;case"Enter":case" ":{t.preventDefault();const e=o[n];e&&e.click();break}}}handleGridKeydown(e){const o=this.getActiveElement(),n=Number(o?.getAttribute("data-row")??1),r=Number(o?.getAttribute("data-col")??1),i=this.activePopup?.querySelector(".notectl-grid-picker__grid")??null;if(!i)return;const l=i.querySelector(".notectl-grid-picker__cell:last-child"),a=Number(l?.getAttribute("data-col")??1),c=Number(l?.getAttribute("data-row")??1);if(["ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(e.key)){e.preventDefault();const[o,l]=s(n,r,c,a,e.key,!!this.activePopup&&t(this.activePopup));i.querySelector(`.notectl-grid-picker__cell[data-row="${o}"][data-col="${l}"]`)?.focus(),C(i,o,l);const d=this.activePopup?.querySelector(".notectl-grid-picker__label")??null;d&&(d.textContent=this.locale.gridPickerLabel(o,l))}"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),o?.click())}handleCustomPopupKeydown(t){if(!this.activePopup)return;const e=Array.from(this.activePopup.querySelectorAll("button"));if(0===e.length)return;const o=this.getActiveElement(),n=e.indexOf(o);switch(t.key){case"ArrowDown":t.preventDefault(),e[l(e,n,1)]?.focus();break;case"ArrowUp":t.preventDefault(),e[l(e,n,-1)]?.focus();break;case"Enter":case" ":t.preventDefault(),o&&((r=o).dispatchEvent(new MouseEvent("mousedown",{bubbles:!0,cancelable:!0})),r.dispatchEvent(new MouseEvent("mouseup",{bubbles:!0,cancelable:!0})),r.click())}var r}},I=class t{element;timer=null;target=null;isPopupActive;static TOOLTIP_ID="notectl-toolbar-tooltip";constructor(o){this.isPopupActive=o,this.element=document.createElement("div"),this.element.className="notectl-toolbar-tooltip",this.element.id=t.TOOLTIP_ID,this.element.setAttribute("role","tooltip"),e(this.element,"display","none")}show(n){if(this.hide(),this.isPopupActive()||n.disabled)return;const r=n.getAttribute("data-tooltip");r&&(this.target=n,this.timer=setTimeout(()=>{if(this.isPopupActive())return;this.element.textContent=r,e(this.element,"display","");const i=n.getRootNode();i instanceof ShadowRoot&&!this.element.parentNode?i.appendChild(this.element):i instanceof ShadowRoot||this.element.parentNode||document.body.appendChild(this.element),n.setAttribute("aria-describedby",t.TOOLTIP_ID);const l=n.getBoundingClientRect();e(this.element,"position","fixed");const s=d(this.element);o(this.element,{top:l.bottom+6-s.y+"px",left:l.left+l.width/2-s.x+"px",transform:"translateX(-50%)"})},500))}hide(){this.timer&&(clearTimeout(this.timer),this.timer=null),this.target&&(this.target.removeAttribute("aria-describedby"),this.target=null),e(this.element,"display","none")}destroy(){this.hide(),this.element.remove()}};function P(t){if(Array.isArray(t))return{plugins:t,label:void 0};const e=t;return{plugins:e.plugins,label:e.label}}var D=new n("toolbar"),T=class{id="toolbar";name="Toolbar";priority=10;context=null;toolbarElement=null;buttons=[];hiddenItems=/* @__PURE__ */new Set;layoutConfig;overflowBehavior;focusedIndex=0;tooltip=null;popupController=null;popupManager=null;overflowController=null;visibleElements=[];locale;constructor(t){this.layoutConfig=t??null,this.overflowBehavior=t?.overflow??w.BurgerMenu}async init(t){this.locale=await i(t,void 0,f,g),t.registerStyleSheet('\n/* Toolbar */\n.notectl-plugin-container--top {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: nowrap;\n\tborder-bottom: 1px solid var(--notectl-border);\n\tbackground: var(--notectl-toolbar-bg, var(--notectl-surface-raised));\n\tmin-height: 40px;\n\tflex-shrink: 0;\n}\n\n.notectl-toolbar {\n\tdisplay: flex;\n\talign-items: center;\n\tflex-wrap: nowrap;\n\toverflow: hidden;\n\tflex: 1;\n\tmin-width: 0;\n\tgap: 2px;\n\tpadding: 4px 8px;\n}\n\n.notectl-toolbar[hidden] {\n\tdisplay: none;\n}\n\n/* Group wrapper — real flex container so consumers can style it via ::part(toolbar-group)\n with padding/background/border directly. Group gap mirrors the toolbar gap so the\n visual rhythm between buttons stays uniform whether or not a group boundary lies between them. */\n.notectl-toolbar-group {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 2px;\n}\n\n.notectl-toolbar-group--overflow-hidden {\n\tdisplay: none;\n}\n\n.notectl-toolbar-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid transparent;\n\tborder-radius: 4px;\n\tbackground: var(--notectl-toolbar-button-bg, transparent);\n\tcursor: pointer;\n\tcolor: var(--notectl-toolbar-button-fg, var(--notectl-fg));\n\tfont-size: 14px;\n\tline-height: 1;\n\tpadding: 0;\n\tflex-shrink: 0;\n\ttransition: background 0.1s, border-color 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn:hover {\n\t\tbackground: var(--notectl-toolbar-button-hover-bg, var(--notectl-hover-bg));\n\t\tborder-color: var(--notectl-border);\n\t}\n}\n\n.notectl-toolbar-btn--active {\n\tbackground: var(--notectl-toolbar-button-active-bg, var(--notectl-active-bg));\n\tborder-color: var(--notectl-primary-muted);\n\tcolor: var(--notectl-toolbar-button-active-fg, var(--notectl-primary-fg));\n}\n\n.notectl-toolbar-btn:focus-visible {\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n\toutline: none;\n}\n\n.notectl-toolbar-btn:disabled {\n\topacity: 0.4;\n\tcursor: not-allowed;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn:disabled:hover {\n\t\tbackground: transparent;\n\t\tborder-color: transparent;\n\t}\n}\n\n.notectl-toolbar-btn__icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\tpointer-events: none;\n}\n\n.notectl-toolbar-btn__icon svg {\n\tdisplay: block;\n\twidth: 18px;\n\theight: 18px;\n\tfill: currentColor;\n}\n\n/* Tooltip (rendered as fixed-position element in shadow root) */\n.notectl-toolbar-tooltip {\n\tpadding: 4px 8px;\n\tborder-radius: 4px;\n\tbackground: var(--notectl-tooltip-bg);\n\tcolor: var(--notectl-tooltip-fg);\n\tfont-size: 11px;\n\tfont-weight: 500;\n\twhite-space: nowrap;\n\tpointer-events: none;\n\tz-index: 10001;\n\tline-height: 1.4;\n\tletter-spacing: 0.01em;\n\tfont-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;\n}\n\n.notectl-toolbar-separator {\n\tdisplay: inline-block;\n\twidth: 1px;\n\theight: 20px;\n\tbackground: var(--notectl-border);\n\tmargin: 0 4px;\n\tvertical-align: middle;\n}\n\n/* Toolbar Popups */\n.notectl-toolbar-popup {\n\tbackground: var(--notectl-surface-overlay);\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 6px;\n\tbox-shadow: 0 4px 12px var(--notectl-shadow);\n\toverflow: hidden;\n}\n\n/* Grid Picker */\n.notectl-grid-picker__cell:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n\n.notectl-grid-picker__cell--highlighted {\n\tbackground: var(--notectl-primary-muted);\n\tborder-color: var(--notectl-primary);\n}\n\n/* Dropdown */\n.notectl-dropdown {\n\tmin-width: 160px;\n\tpadding: 4px 0;\n}\n\n.notectl-dropdown__item {\n\tdisplay: flex;\n\talign-items: center;\n\twidth: 100%;\n\tpadding: 8px 12px;\n\ttext-align: start;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: var(--notectl-fg);\n\tline-height: 1.4;\n\tfont-family: inherit;\n\twhite-space: nowrap;\n}\n\n@media (hover: hover) {\n\t.notectl-dropdown__item:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-dropdown__item:focus-visible {\n\tbackground: var(--notectl-hover-bg);\n\toutline: none;\n}\n\n.notectl-dropdown__item-icon {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 28px;\n\tfont-weight: 600;\n\tcolor: var(--notectl-fg-muted);\n\tflex-shrink: 0;\n}\n\n.notectl-dropdown__item-label {\n\tflex: 1;\n}\n\n/* Overflow behavior: flow mode — toolbar wraps to additional rows */\n.notectl-toolbar[data-overflow="flow"] {\n\tflex-wrap: wrap;\n\toverflow: visible;\n}\n\n/* Overflow behavior: none — toolbar clips without any responsive behavior */\n.notectl-toolbar[data-overflow="none"] {\n\tflex-wrap: nowrap;\n\toverflow: hidden;\n}\n\n/* Overflow: hidden items (burger-menu mode) */\n.notectl-toolbar-btn--overflow-hidden,\n.notectl-toolbar-separator--overflow-hidden {\n\tdisplay: none;\n}\n\n/* Overflow "more" button */\n.notectl-toolbar-overflow-btn {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 32px;\n\theight: 32px;\n\tborder: 1px solid transparent;\n\tborder-radius: 4px;\n\tbackground: transparent;\n\tcursor: pointer;\n\tcolor: var(--notectl-fg);\n\tfont-size: 16px;\n\tline-height: 1;\n\tpadding: 0;\n\tflex-shrink: 0;\n\tmargin-inline-start: auto;\n\ttransition: background 0.1s, border-color 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-overflow-btn:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t\tborder-color: var(--notectl-border);\n\t}\n}\n\n.notectl-toolbar-overflow-btn--hidden {\n\tdisplay: none;\n}\n\n.notectl-toolbar-overflow-btn:focus-visible {\n\tbox-shadow: 0 0 0 2px var(--notectl-focus-ring);\n\toutline: none;\n}\n\n/* Dropdown item states shared by all dropdown menus (including overflow) */\n.notectl-dropdown__item:disabled {\n\topacity: 0.4;\n\tcursor: not-allowed;\n}\n\n@media (hover: hover) {\n\t.notectl-dropdown__item:disabled:hover {\n\t\tbackground: none;\n\t}\n}\n\n.notectl-dropdown__item--active {\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-dropdown__item-icon svg {\n\tdisplay: block;\n\twidth: 16px;\n\theight: 16px;\n\tfill: currentColor;\n}\n\n.notectl-dropdown__separator {\n\theight: 1px;\n\tbackground: var(--notectl-border);\n\tmargin: 4px 0;\n}\n\n/* Combobox-style toolbar buttons (shared base for font, fontSize, heading, etc.) */\n.notectl-toolbar-btn[role="combobox"] {\n\twidth: auto;\n\tpadding: 0 8px;\n\tgap: 4px;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-toolbar-bg, var(--notectl-surface-raised));\n}\n\n@media (hover: hover) {\n\t.notectl-toolbar-btn[role="combobox"]:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t\tborder-color: var(--notectl-fg-muted);\n\t}\n}\n\n.notectl-toolbar-btn[role="combobox"].notectl-toolbar-btn--active {\n\tbackground: var(--notectl-toolbar-bg, var(--notectl-surface-raised));\n\tborder-color: var(--notectl-primary-muted);\n}\n\n.notectl-toolbar-combobox__label {\n\tflex: 1;\n\tfont-size: 13px;\n\tfont-weight: 500;\n\tcolor: var(--notectl-fg);\n\twhite-space: nowrap;\n\toverflow: hidden;\n\ttext-overflow: ellipsis;\n\ttext-align: start;\n\tline-height: 30px;\n}\n\n.notectl-toolbar-combobox__arrow {\n\tflex-shrink: 0;\n\tfont-size: 11px;\n\tcolor: var(--notectl-fg-muted);\n\tline-height: 30px;\n}\n\n/* Link Popup */\n.notectl-link-popup {\n\tpadding: 8px;\n\tmin-width: 200px;\n}\n\n.notectl-link-popup__input {\n\twidth: 100%;\n\tpadding: 4px;\n\tbox-sizing: border-box;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tfont-size: 13px;\n\tcolor: var(--notectl-fg);\n\tbackground: var(--notectl-surface-overlay);\n}\n\n.notectl-link-popup__input:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n\n.notectl-link-popup__button {\n\twidth: 100%;\n\tpadding: 6px 12px;\n\tcursor: pointer;\n\tborder: 1px solid var(--notectl-border);\n\tborder-radius: 4px;\n\tbackground: var(--notectl-surface-overlay);\n\tcolor: var(--notectl-fg);\n\tfont-size: 13px;\n}\n\n.notectl-link-popup__button--apply {\n\tmargin-top: 4px;\n}\n\n@media (hover: hover) {\n\t.notectl-link-popup__button:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-link-popup__button:focus-visible {\n\toutline: 2px solid var(--notectl-focus-ring);\n\toutline-offset: -1px;\n}\n'),this.context=t,this.popupManager=new h(t.getContainer()),t.registerService(u,this.popupManager),this.popupController=new L(()=>this.getActiveElement(),this.locale),this.popupController.setPopupManager(this.popupManager),this.tooltip=new I(()=>this.popupController?.isOpen()??!1),t.registerService(D,{refresh:()=>this.updateButtonStates(t.getState()),closePopup:()=>this.popupController?.close()}),this.createToolbarElement()}getOverflowBehavior(){return this.overflowBehavior}setOverflowBehavior(t){t!==this.overflowBehavior&&(this.overflowBehavior=t,this.applyOverflowBehavior(),this.renderItems())}onReady(){this.renderItems()}destroy(){this.overflowController?.destroy(),this.overflowController=null,this.popupController?.destroy(),this.popupController=null,this.popupManager?.destroy(),this.popupManager=null,this.tooltip?.destroy(),this.tooltip=null,this.toolbarElement&&(this.toolbarElement.remove(),this.toolbarElement=null),this.buttons=[],this.visibleElements=[],this.context=null}onStateChange(t,e,o){this.updateButtonStates(e)}onReadOnlyChange(t){this.toolbarElement&&(this.toolbarElement.hidden=t)}onConfigure(t){for(const[e,o]of Object.entries(t))!1===o?this.hiddenItems.add(e):this.hiddenItems.delete(e);this.renderItems()}createToolbarElement(){if(!this.context)return;this.toolbarElement&&this.toolbarElement.remove(),this.buttons=[];const t=this.context.getPluginContainer("top");this.toolbarElement=document.createElement("div"),this.toolbarElement.setAttribute("role","toolbar"),this.toolbarElement.setAttribute("aria-label",this.locale.formattingOptionsAria),this.toolbarElement.setAttribute("data-notectl-no-print",""),this.toolbarElement.setAttribute("part","toolbar"),this.toolbarElement.className="notectl-toolbar",this.toolbarElement.addEventListener("keydown",t=>this.handleToolbarKeydown(t)),this.applyOverflowBehavior(),t.appendChild(this.toolbarElement)}applyOverflowBehavior(){this.toolbarElement&&this.context&&(this.overflowController?.destroy(),this.overflowController=null,this.toolbarElement.setAttribute("data-overflow",this.overflowBehavior),this.overflowBehavior===w.BurgerMenu?this.overflowController=new k({toolbar:this.toolbarElement,ariaLabel:this.locale.moreToolsAria,context:this.context,popupManager:this.popupManager??void 0,onOverflowChange:(t,e)=>{this.visibleElements=e?[...t,e]:[...t],this.initRovingTabindex()},onItemActivated:(t,e)=>{this.activateButton(t,e)},getActiveElement:()=>this.getActiveElement()}):this.visibleElements=[])}renderItems(){if(this.context&&this.toolbarElement){for(const t of this.buttons)t.element.remove();this.buttons=[];for(const t of this.toolbarElement.querySelectorAll(".notectl-toolbar-separator"))t.remove();for(const t of this.toolbarElement.querySelectorAll(".notectl-toolbar-group"))t.remove();this.layoutConfig?this.renderItemsByLayout():this.renderItemsByGroup(),this.buttons.length>0&&!this.toolbarElement.parentElement&&this.context.getPluginContainer("top").appendChild(this.toolbarElement),this.overflowController?.update(this.buttons),this.initRovingTabindex(),this.updateButtonStates(this.context.getState())}}createGroupWrapper(t){const e=document.createElement("div");return e.className="notectl-toolbar-group",e.setAttribute("part","toolbar-group"),void 0!==t&&(e.setAttribute("role","group"),e.setAttribute("aria-label",t)),e}getTabElements(){return this.visibleElements.length>0?this.visibleElements:this.buttons.map(t=>t.element)}initRovingTabindex(){const t=this.getTabElements(),e=m(t);this.focusedIndex=e>=0?e:0,a(t,this.focusedIndex)}setRovingFocus(t){const e=this.getTabElements();t<0||t>=e.length||(this.focusedIndex=t,a(e,t),e[t]?.focus())}getActiveElement(){const t=this.toolbarElement?.getRootNode();return t instanceof ShadowRoot?t.activeElement:document.activeElement}syncFocusedIndex(){const t=this.getActiveElement(),e=this.getTabElements().findIndex(e=>e===t);e>=0&&(this.focusedIndex=e)}handleToolbarKeydown(e){const o=this.getTabElements();var n;if(0!==o.length)switch(this.syncFocusedIndex(),e.key){case"ArrowRight":case"ArrowLeft":{e.preventDefault();const r=(n=!!this.toolbarElement&&t(this.toolbarElement),"ArrowRight"===e.key?n?-1:1:n?1:-1),i=function(t,e,o){const n=t.length;if(0===n)return-1;let r=e;for(let i=0;i<n;i++)if(r=(r+o+n)%n,!t[r]?.disabled)return r;return e}(o,this.focusedIndex,r);this.setRovingFocus(i);break}case"Home":{e.preventDefault();const t=m(o);t>=0&&this.setRovingFocus(t);break}case"End":{e.preventDefault();const t=function(t){for(let e=t.length-1;e>=0;e--)if(!t[e]?.disabled)return e;return-1}(o);t>=0&&this.setRovingFocus(t);break}case"Enter":case" ":{e.preventDefault();const t=o[this.focusedIndex],n=this.buttons.find(e=>e.element===t);n&&this.activateButton(n.element,n.item);break}}}activateButton(t,e){this.tooltip?.hide(),e.popupType&&this.context?this.popupController?.toggle(t,e,this.context):this.context?.executeCommand(e.command)}renderItemsByLayout(){if(!this.context||!this.toolbarElement||!this.layoutConfig)return;const t=this.context.getToolbarRegistry();let e=!0;for(const o of this.layoutConfig.groups){const{plugins:n,label:r}=P(o),i=[];for(const e of n){const o=t.getToolbarItemsByPlugin(e).filter(t=>!this.hiddenItems.has(t.id));i.push(...o)}if(0===i.length)continue;e||this.toolbarElement.appendChild(B()),e=!1;const l=this.createGroupWrapper(r);for(const t of i){const e=this.createButton(t);l.appendChild(e.element),this.buttons.push(e)}this.toolbarElement.appendChild(l)}0===this.buttons.length&&this.toolbarElement.remove()}renderItemsByGroup(){if(!this.context||!this.toolbarElement)return;const t=this.context.getToolbarRegistry().getToolbarItems().filter(t=>!this.hiddenItems.has(t.id));if(0===t.length)return void this.toolbarElement.remove();const e=/* @__PURE__ */new Map;for(const n of t){const t=e.get(n.group)??[];t.push(n),e.set(n.group,t)}let o=!0;for(const[,n]of e){o||this.toolbarElement.appendChild(B()),o=!1;const t=this.createGroupWrapper(void 0);for(const e of n){const o=this.createButton(e);t.appendChild(o.element),this.buttons.push(o)}this.toolbarElement.appendChild(t)}}createButton(t){const e=document.createElement("button");e.type="button",e.className=`notectl-toolbar-btn notectl-toolbar-btn--${t.id}`,e.setAttribute("aria-pressed","false"),e.setAttribute("aria-label",t.label),e.setAttribute("data-toolbar-item",t.id),e.setAttribute("data-tooltip",t.tooltip??t.label),e.setAttribute("part","toolbar-button");let o=null;if("combobox"===t.popupType){e.setAttribute("role","combobox"),e.setAttribute("aria-haspopup","listbox"),e.setAttribute("aria-expanded","false");const n=document.createElement("span");n.className="notectl-toolbar-combobox__label";const r=this.context?.getState();r&&(n.textContent=t.getLabel(r)),e.appendChild(n),o=n;const i=document.createElement("span");i.className="notectl-toolbar-combobox__arrow",i.setAttribute("aria-hidden","true"),i.textContent="▾",e.appendChild(i)}else{t.popupType&&(e.setAttribute("aria-haspopup","true"),e.setAttribute("aria-expanded","false"));const o=document.createElement("span");o.className="notectl-toolbar-btn__icon",o.innerHTML=t.icon,e.appendChild(o)}return e.addEventListener("mousedown",o=>{o.preventDefault(),this.activateButton(e,t)}),e.addEventListener("mouseenter",()=>this.tooltip?.show(e)),e.addEventListener("mouseleave",()=>this.tooltip?.hide()),e.addEventListener("focus",()=>this.tooltip?.show(e)),e.addEventListener("blur",()=>this.tooltip?.hide()),{element:e,item:t,comboLabelEl:o}}updateButtonStates(t){for(const e of this.buttons){const o=e.item.isActive?.(t)??!1,n=e.item.isEnabled?.(t)??!0;if(e.element.setAttribute("aria-pressed",String(o)),e.element.classList.toggle("notectl-toolbar-btn--active",o),e.element.setAttribute("part",o?"toolbar-button toolbar-button-active":"toolbar-button"),e.element.disabled=!n,n?e.element.removeAttribute("aria-disabled"):e.element.setAttribute("aria-disabled","true"),e.comboLabelEl&&"combobox"===e.item.popupType&&(e.comboLabelEl.textContent=e.item.getLabel(t)),e.item.getIcon){const o=e.item.getIcon(t),n=e.element.querySelector(".notectl-toolbar-btn__icon");n&&n.innerHTML!==o&&(n.innerHTML=o)}}this.overflowController?.updateItemStates(t)}};export{g as a,f as i,D as n,b as o,w as r,T as t};
2
+ //# sourceMappingURL=ToolbarPlugin-DtfGTO_V.mjs.map