@notectl/core 2.0.0 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/README.md +12 -10
  2. package/dist/chunks/{AttrRegistry-B2AGfTE0.mjs → AttrRegistry-iNpjvcSG.mjs} +2 -2
  3. package/dist/chunks/{AttrRegistry-B2AGfTE0.mjs.map → AttrRegistry-iNpjvcSG.mjs.map} +1 -1
  4. package/dist/chunks/AttributedMarkCommands-BY1BSYWM.mjs +2 -0
  5. package/dist/chunks/AttributedMarkCommands-BY1BSYWM.mjs.map +1 -0
  6. package/dist/chunks/BlockInsertion-BJFhE0jA.mjs +2 -0
  7. package/dist/chunks/BlockInsertion-BJFhE0jA.mjs.map +1 -0
  8. package/dist/chunks/{ColorPickerPopup-DRzFvt7o.mjs → ColorPickerPopup-D6XjShhv.mjs} +2 -2
  9. package/dist/chunks/ColorPickerPopup-D6XjShhv.mjs.map +1 -0
  10. package/dist/chunks/CommandHelpers-M6mPS6Ww.mjs +2 -0
  11. package/dist/chunks/CommandHelpers-M6mPS6Ww.mjs.map +1 -0
  12. package/dist/chunks/Commands-D_gMCnVa.mjs +2 -0
  13. package/dist/chunks/Commands-D_gMCnVa.mjs.map +1 -0
  14. package/dist/chunks/Document-3pNX7ear.mjs +2 -0
  15. package/dist/chunks/Document-3pNX7ear.mjs.map +1 -0
  16. package/dist/chunks/DocumentParser-LvzDQOd1.mjs +2 -0
  17. package/dist/chunks/DocumentParser-LvzDQOd1.mjs.map +1 -0
  18. package/dist/chunks/DomUtils-CznMAZZg.mjs +2 -0
  19. package/dist/chunks/DomUtils-CznMAZZg.mjs.map +1 -0
  20. package/dist/chunks/HTMLUtils-Cxy99Ak2.mjs +2 -0
  21. package/dist/chunks/HTMLUtils-Cxy99Ak2.mjs.map +1 -0
  22. package/dist/chunks/HeadingPlugin-BmkeUXj8.mjs +2 -0
  23. package/dist/chunks/HeadingPlugin-BmkeUXj8.mjs.map +1 -0
  24. package/dist/chunks/MarkCommands-CeCa4WSC.mjs +2 -0
  25. package/dist/chunks/MarkCommands-CeCa4WSC.mjs.map +1 -0
  26. package/dist/chunks/NavigationQueries-11qe4j9x.mjs +2 -0
  27. package/dist/chunks/NavigationQueries-11qe4j9x.mjs.map +1 -0
  28. package/dist/chunks/NodeResolver-z0ReCR34.mjs +2 -0
  29. package/dist/chunks/NodeResolver-z0ReCR34.mjs.map +1 -0
  30. package/dist/chunks/NodeSelectionCommands-CXrOcPtG.mjs +2 -0
  31. package/dist/chunks/NodeSelectionCommands-CXrOcPtG.mjs.map +1 -0
  32. package/dist/chunks/NotectlEditor-BJD7-FFx.mjs +4 -0
  33. package/dist/chunks/NotectlEditor-BJD7-FFx.mjs.map +1 -0
  34. package/dist/chunks/PluginHelpers-CdPR0MuT.mjs +2 -0
  35. package/dist/chunks/PluginHelpers-CdPR0MuT.mjs.map +1 -0
  36. package/dist/chunks/PopupManager-0b_Q0m7K.mjs +2 -0
  37. package/dist/chunks/PopupManager-0b_Q0m7K.mjs.map +1 -0
  38. package/dist/chunks/PrintTypes-DukwDSWS.mjs +2 -0
  39. package/dist/chunks/{PrintTypes-ehbL7ipA.mjs.map → PrintTypes-DukwDSWS.mjs.map} +1 -1
  40. package/dist/chunks/{RangeIterator-CNI6smOg.mjs → RangeIterator-XFN5FaYf.mjs} +2 -2
  41. package/dist/chunks/{RangeIterator-CNI6smOg.mjs.map → RangeIterator-XFN5FaYf.mjs.map} +1 -1
  42. package/dist/chunks/{Selection-6-W6Flxc.mjs → Selection-DhbizDM4.mjs} +2 -2
  43. package/dist/chunks/{Selection-6-W6Flxc.mjs.map → Selection-DhbizDM4.mjs.map} +1 -1
  44. package/dist/chunks/SelectionTransactions-DzIZxcuN.mjs +2 -0
  45. package/dist/chunks/{SelectionTransactions-q71GEzgE.mjs.map → SelectionTransactions-DzIZxcuN.mjs.map} +1 -1
  46. package/dist/chunks/{TextDirectionLocale-DB_aqrMg.mjs → TextDirectionLocale-CKz0ZrH_.mjs} +2 -2
  47. package/dist/chunks/{TextDirectionLocale-DB_aqrMg.mjs.map → TextDirectionLocale-CKz0ZrH_.mjs.map} +1 -1
  48. package/dist/chunks/XmlPatterns-DxQXGjP8.mjs +2 -0
  49. package/dist/chunks/XmlPatterns-DxQXGjP8.mjs.map +1 -0
  50. package/dist/chunks/ar-b6VdnxAs.mjs +2 -0
  51. package/dist/chunks/ar-b6VdnxAs.mjs.map +1 -0
  52. package/dist/chunks/de-fXvs5vQT.mjs +2 -0
  53. package/dist/chunks/de-fXvs5vQT.mjs.map +1 -0
  54. package/dist/chunks/es-BTqy_aQ4.mjs +2 -0
  55. package/dist/chunks/es-BTqy_aQ4.mjs.map +1 -0
  56. package/dist/chunks/fr-VdiCNF4J.mjs +2 -0
  57. package/dist/chunks/fr-VdiCNF4J.mjs.map +1 -0
  58. package/dist/chunks/hi-BdtVhAzs.mjs +2 -0
  59. package/dist/chunks/hi-BdtVhAzs.mjs.map +1 -0
  60. package/dist/chunks/index-C-L4awHz.mjs +2 -0
  61. package/dist/chunks/index-C-L4awHz.mjs.map +1 -0
  62. package/dist/chunks/index-Cs9iqxhF.mjs +2 -0
  63. package/dist/chunks/index-Cs9iqxhF.mjs.map +1 -0
  64. package/dist/chunks/pt-K0BUlM9X.mjs +2 -0
  65. package/dist/chunks/pt-K0BUlM9X.mjs.map +1 -0
  66. package/dist/chunks/ru-Tzd5N37W.mjs +2 -0
  67. package/dist/chunks/ru-Tzd5N37W.mjs.map +1 -0
  68. package/dist/chunks/zh-Di3WqY4_.mjs +2 -0
  69. package/dist/chunks/zh-Di3WqY4_.mjs.map +1 -0
  70. package/dist/{input → commands}/BlockInsertion.d.ts +14 -1
  71. package/dist/commands/BlockInsertion.d.ts.map +1 -0
  72. package/dist/commands/CommandHelpers.d.ts +17 -2
  73. package/dist/commands/CommandHelpers.d.ts.map +1 -1
  74. package/dist/commands/Commands.d.ts.map +1 -1
  75. package/dist/commands/GapCursorCommands.d.ts.map +1 -1
  76. package/dist/commands/NodeSelectionCommands.d.ts +3 -8
  77. package/dist/commands/NodeSelectionCommands.d.ts.map +1 -1
  78. package/dist/commands/PasteCommand.d.ts.map +1 -1
  79. package/dist/editor/ContentSerializer.d.ts.map +1 -1
  80. package/dist/editor/EditorConfig.d.ts +50 -0
  81. package/dist/editor/EditorConfig.d.ts.map +1 -0
  82. package/dist/editor/EditorConfigController.d.ts +1 -1
  83. package/dist/editor/EditorConfigController.d.ts.map +1 -1
  84. package/dist/editor/EditorDOM.d.ts.map +1 -1
  85. package/dist/editor/EditorInitializer.d.ts +37 -0
  86. package/dist/editor/EditorInitializer.d.ts.map +1 -0
  87. package/dist/editor/EditorLifecycleCoordinator.d.ts +6 -1
  88. package/dist/editor/EditorLifecycleCoordinator.d.ts.map +1 -1
  89. package/dist/editor/EditorThemeController.d.ts.map +1 -1
  90. package/dist/editor/NotectlEditor.d.ts +13 -51
  91. package/dist/editor/NotectlEditor.d.ts.map +1 -1
  92. package/dist/editor/PluginBootstrapper.d.ts +1 -1
  93. package/dist/editor/PluginBootstrapper.d.ts.map +1 -1
  94. package/dist/editor/styles/code-block.d.ts +1 -1
  95. package/dist/editor/styles/code-block.d.ts.map +1 -1
  96. package/dist/editor/theme/ThemeEngine.d.ts.map +1 -1
  97. package/dist/editor/theme/ThemeTokens.d.ts +17 -1
  98. package/dist/editor/theme/ThemeTokens.d.ts.map +1 -1
  99. package/dist/full.d.ts +1 -0
  100. package/dist/full.d.ts.map +1 -1
  101. package/dist/full.mjs +1 -1
  102. package/dist/html.mjs +1 -1
  103. package/dist/index.d.ts +1 -1
  104. package/dist/index.d.ts.map +1 -1
  105. package/dist/input/ClipboardHandler.d.ts +5 -0
  106. package/dist/input/ClipboardHandler.d.ts.map +1 -1
  107. package/dist/input/HTMLParser.d.ts +9 -5
  108. package/dist/input/HTMLParser.d.ts.map +1 -1
  109. package/dist/input/InputHandler.d.ts +1 -0
  110. package/dist/input/InputHandler.d.ts.map +1 -1
  111. package/dist/input/InputManager.d.ts +2 -0
  112. package/dist/input/InputManager.d.ts.map +1 -1
  113. package/dist/input/InternalClipboard.d.ts +2 -22
  114. package/dist/input/InternalClipboard.d.ts.map +1 -1
  115. package/dist/input/PasteHTMLHandler.d.ts +25 -0
  116. package/dist/input/PasteHTMLHandler.d.ts.map +1 -0
  117. package/dist/input/PasteHandler.d.ts +7 -25
  118. package/dist/input/PasteHandler.d.ts.map +1 -1
  119. package/dist/input/PasteRichBlockHandler.d.ts +23 -0
  120. package/dist/input/PasteRichBlockHandler.d.ts.map +1 -0
  121. package/dist/input/SelectionDocument.d.ts +10 -0
  122. package/dist/input/SelectionDocument.d.ts.map +1 -0
  123. package/dist/model/Document.d.ts.map +1 -1
  124. package/dist/model/HTMLUtils.d.ts +2 -0
  125. package/dist/model/HTMLUtils.d.ts.map +1 -1
  126. package/dist/model/PasteInterceptor.d.ts +21 -0
  127. package/dist/model/PasteInterceptor.d.ts.map +1 -0
  128. package/dist/model/RichBlockData.d.ts +34 -0
  129. package/dist/model/RichBlockData.d.ts.map +1 -0
  130. package/dist/model/SchemaRegistry.d.ts +2 -0
  131. package/dist/model/SchemaRegistry.d.ts.map +1 -1
  132. package/dist/notectl-core.mjs +1 -1
  133. package/dist/notectl-core.umd.js +1 -1
  134. package/dist/notectl-core.umd.js.map +1 -1
  135. package/dist/plugins/Plugin.d.ts +3 -0
  136. package/dist/plugins/Plugin.d.ts.map +1 -1
  137. package/dist/plugins/PluginContextFactory.d.ts +73 -0
  138. package/dist/plugins/PluginContextFactory.d.ts.map +1 -0
  139. package/dist/plugins/PluginManager.d.ts +12 -0
  140. package/dist/plugins/PluginManager.d.ts.map +1 -1
  141. package/dist/plugins/alignment/AlignmentPlugin.d.ts.map +1 -1
  142. package/dist/plugins/alignment.mjs +1 -1
  143. package/dist/plugins/alignment.mjs.map +1 -1
  144. package/dist/plugins/blockquote/BlockquoteKeyboardHandlers.d.ts.map +1 -1
  145. package/dist/plugins/blockquote/BlockquotePlugin.d.ts.map +1 -1
  146. package/dist/plugins/blockquote.mjs +1 -1
  147. package/dist/plugins/blockquote.mjs.map +1 -1
  148. package/dist/plugins/caret-navigation/CaretNavigationPlugin.d.ts.map +1 -1
  149. package/dist/plugins/caret-navigation.mjs +1 -1
  150. package/dist/plugins/code-block/CodeBlockKeyboardHandlers.d.ts.map +1 -1
  151. package/dist/plugins/code-block/CodeBlockPlugin.d.ts +5 -0
  152. package/dist/plugins/code-block/CodeBlockPlugin.d.ts.map +1 -1
  153. package/dist/plugins/code-block/CodeBlockTypes.d.ts +7 -0
  154. package/dist/plugins/code-block/CodeBlockTypes.d.ts.map +1 -1
  155. package/dist/plugins/code-block/highlighter/RegexTokenizer.d.ts +14 -0
  156. package/dist/plugins/code-block/highlighter/RegexTokenizer.d.ts.map +1 -0
  157. package/dist/plugins/code-block/highlighter/TokenizerTypes.d.ts +15 -0
  158. package/dist/plugins/code-block/highlighter/TokenizerTypes.d.ts.map +1 -0
  159. package/dist/plugins/code-block/highlighter/languages/index.d.ts +3 -0
  160. package/dist/plugins/code-block/highlighter/languages/index.d.ts.map +1 -0
  161. package/dist/plugins/code-block/highlighter/languages/json.d.ts +3 -0
  162. package/dist/plugins/code-block/highlighter/languages/json.d.ts.map +1 -0
  163. package/dist/plugins/code-block/highlighter/languages/xml.d.ts +3 -0
  164. package/dist/plugins/code-block/highlighter/languages/xml.d.ts.map +1 -0
  165. package/dist/plugins/code-block/index.d.ts +5 -1
  166. package/dist/plugins/code-block/index.d.ts.map +1 -1
  167. package/dist/plugins/code-block.mjs +1 -1
  168. package/dist/plugins/code-block.mjs.map +1 -1
  169. package/dist/plugins/font/FontPlugin.d.ts.map +1 -1
  170. package/dist/plugins/font-size/FontSizePlugin.d.ts.map +1 -1
  171. package/dist/plugins/font-size.mjs +1 -1
  172. package/dist/plugins/font-size.mjs.map +1 -1
  173. package/dist/plugins/font.mjs +1 -1
  174. package/dist/plugins/font.mjs.map +1 -1
  175. package/dist/plugins/gap-cursor/GapCursorPlugin.d.ts.map +1 -1
  176. package/dist/plugins/gap-cursor.mjs +1 -1
  177. package/dist/plugins/hard-break.mjs +1 -1
  178. package/dist/plugins/heading/HeadingInputRules.d.ts.map +1 -1
  179. package/dist/plugins/heading/HeadingKeyboardHandlers.d.ts.map +1 -1
  180. package/dist/plugins/heading/HeadingPlugin.d.ts.map +1 -1
  181. package/dist/plugins/heading.mjs +1 -1
  182. package/dist/plugins/highlight/HighlightPlugin.d.ts.map +1 -1
  183. package/dist/plugins/highlight.mjs +1 -1
  184. package/dist/plugins/highlight.mjs.map +1 -1
  185. package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts.map +1 -1
  186. package/dist/plugins/horizontal-rule.mjs +1 -1
  187. package/dist/plugins/horizontal-rule.mjs.map +1 -1
  188. package/dist/plugins/image/ImageCommands.d.ts.map +1 -1
  189. package/dist/plugins/image/ImagePlugin.d.ts +0 -1
  190. package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
  191. package/dist/plugins/image/ImagePopup.d.ts +11 -0
  192. package/dist/plugins/image/ImagePopup.d.ts.map +1 -0
  193. package/dist/plugins/image.mjs +1 -1
  194. package/dist/plugins/image.mjs.map +1 -1
  195. package/dist/plugins/link/LinkPlugin.d.ts.map +1 -1
  196. package/dist/plugins/link.mjs +1 -1
  197. package/dist/plugins/link.mjs.map +1 -1
  198. package/dist/plugins/list/ListPlugin.d.ts.map +1 -1
  199. package/dist/plugins/list.mjs +1 -1
  200. package/dist/plugins/list.mjs.map +1 -1
  201. package/dist/plugins/print/PrintPlugin.d.ts.map +1 -1
  202. package/dist/plugins/print.mjs +1 -1
  203. package/dist/plugins/print.mjs.map +1 -1
  204. package/dist/plugins/shared/ColorMarkOperations.d.ts +1 -2
  205. package/dist/plugins/shared/ColorMarkOperations.d.ts.map +1 -1
  206. package/dist/plugins/shared/ColorPickerPopup.d.ts +1 -8
  207. package/dist/plugins/shared/ColorPickerPopup.d.ts.map +1 -1
  208. package/dist/plugins/shared/PluginHelpers.d.ts +8 -0
  209. package/dist/plugins/shared/PluginHelpers.d.ts.map +1 -1
  210. package/dist/plugins/shared/PopupManager.d.ts.map +1 -1
  211. package/dist/plugins/shared/XmlPatterns.d.ts +10 -0
  212. package/dist/plugins/shared/XmlPatterns.d.ts.map +1 -0
  213. package/dist/plugins/shared/index.d.ts +1 -0
  214. package/dist/plugins/shared/index.d.ts.map +1 -1
  215. package/dist/plugins/shared.mjs +1 -1
  216. package/dist/plugins/shared.mjs.map +1 -1
  217. package/dist/plugins/smart-paste/SmartPasteLocale.d.ts +7 -0
  218. package/dist/plugins/smart-paste/SmartPasteLocale.d.ts.map +1 -0
  219. package/dist/plugins/smart-paste/SmartPastePlugin.d.ts +19 -0
  220. package/dist/plugins/smart-paste/SmartPastePlugin.d.ts.map +1 -0
  221. package/dist/plugins/smart-paste/SmartPasteTypes.d.ts +24 -0
  222. package/dist/plugins/smart-paste/SmartPasteTypes.d.ts.map +1 -0
  223. package/dist/plugins/smart-paste/detectors/JsonDetector.d.ts +6 -0
  224. package/dist/plugins/smart-paste/detectors/JsonDetector.d.ts.map +1 -0
  225. package/dist/plugins/smart-paste/detectors/XmlDetector.d.ts +26 -0
  226. package/dist/plugins/smart-paste/detectors/XmlDetector.d.ts.map +1 -0
  227. package/dist/plugins/smart-paste/index.d.ts +7 -0
  228. package/dist/plugins/smart-paste/index.d.ts.map +1 -0
  229. package/dist/plugins/smart-paste/locales/ar.d.ts +4 -0
  230. package/dist/plugins/smart-paste/locales/ar.d.ts.map +1 -0
  231. package/dist/plugins/smart-paste/locales/de.d.ts +4 -0
  232. package/dist/plugins/smart-paste/locales/de.d.ts.map +1 -0
  233. package/dist/plugins/smart-paste/locales/es.d.ts +4 -0
  234. package/dist/plugins/smart-paste/locales/es.d.ts.map +1 -0
  235. package/dist/plugins/smart-paste/locales/fr.d.ts +4 -0
  236. package/dist/plugins/smart-paste/locales/fr.d.ts.map +1 -0
  237. package/dist/plugins/smart-paste/locales/hi.d.ts +4 -0
  238. package/dist/plugins/smart-paste/locales/hi.d.ts.map +1 -0
  239. package/dist/plugins/smart-paste/locales/pt.d.ts +4 -0
  240. package/dist/plugins/smart-paste/locales/pt.d.ts.map +1 -0
  241. package/dist/plugins/smart-paste/locales/ru.d.ts +4 -0
  242. package/dist/plugins/smart-paste/locales/ru.d.ts.map +1 -0
  243. package/dist/plugins/smart-paste/locales/zh.d.ts +4 -0
  244. package/dist/plugins/smart-paste/locales/zh.d.ts.map +1 -0
  245. package/dist/plugins/smart-paste.mjs +2 -0
  246. package/dist/plugins/smart-paste.mjs.map +1 -0
  247. package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts.map +1 -1
  248. package/dist/plugins/strikethrough.mjs +1 -1
  249. package/dist/plugins/strikethrough.mjs.map +1 -1
  250. package/dist/plugins/super-sub/SuperSubPlugin.d.ts.map +1 -1
  251. package/dist/plugins/super-sub.mjs +1 -1
  252. package/dist/plugins/super-sub.mjs.map +1 -1
  253. package/dist/plugins/table/TableCommands.d.ts +1 -0
  254. package/dist/plugins/table/TableCommands.d.ts.map +1 -1
  255. package/dist/plugins/table/TableContextMenu.d.ts.map +1 -1
  256. package/dist/plugins/table/TableNavigation.d.ts.map +1 -1
  257. package/dist/plugins/table/TablePlugin.d.ts.map +1 -1
  258. package/dist/plugins/table/TableSelection.d.ts.map +1 -1
  259. package/dist/plugins/table/index.d.ts +1 -0
  260. package/dist/plugins/table/index.d.ts.map +1 -1
  261. package/dist/plugins/table.mjs +1 -1
  262. package/dist/plugins/table.mjs.map +1 -1
  263. package/dist/plugins/text-color/TextColorPlugin.d.ts.map +1 -1
  264. package/dist/plugins/text-color.mjs +1 -1
  265. package/dist/plugins/text-color.mjs.map +1 -1
  266. package/dist/plugins/text-direction/TextDirectionCorePlugin.d.ts.map +1 -1
  267. package/dist/plugins/text-direction/TextDirectionPlugin.d.ts.map +1 -1
  268. package/dist/plugins/text-direction-advanced.mjs +1 -1
  269. package/dist/plugins/text-direction-advanced.mjs.map +1 -1
  270. package/dist/plugins/text-direction.mjs +1 -1
  271. package/dist/plugins/text-direction.mjs.map +1 -1
  272. package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts.map +1 -1
  273. package/dist/plugins/text-formatting.mjs +1 -1
  274. package/dist/plugins/text-formatting.mjs.map +1 -1
  275. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts +2 -0
  276. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts.map +1 -1
  277. package/dist/plugins/toolbar/ToolbarPlugin.d.ts.map +1 -1
  278. package/dist/plugins/toolbar.mjs +1 -1
  279. package/dist/plugins/toolbar.mjs.map +1 -1
  280. package/dist/presets/FullPreset.d.ts.map +1 -1
  281. package/dist/presets/PresetTypes.d.ts +2 -0
  282. package/dist/presets/PresetTypes.d.ts.map +1 -1
  283. package/dist/presets/full.mjs +1 -1
  284. package/dist/presets/full.mjs.map +1 -1
  285. package/dist/serialization/DocumentSerializer.d.ts.map +1 -1
  286. package/dist/state/InlineContentOps.d.ts.map +1 -1
  287. package/dist/state/StepInversion.d.ts +7 -0
  288. package/dist/state/StepInversion.d.ts.map +1 -0
  289. package/dist/state/Steps.d.ts +108 -0
  290. package/dist/state/Steps.d.ts.map +1 -0
  291. package/dist/state/Transaction.d.ts +5 -174
  292. package/dist/state/Transaction.d.ts.map +1 -1
  293. package/dist/state/TransactionBuilder.d.ts +69 -0
  294. package/dist/state/TransactionBuilder.d.ts.map +1 -0
  295. package/dist/test/TestUtils.d.ts.map +1 -1
  296. package/dist/view/CaretNavigation.d.ts.map +1 -1
  297. package/dist/view/DomUtils.d.ts +10 -1
  298. package/dist/view/DomUtils.d.ts.map +1 -1
  299. package/dist/view/EditorView.d.ts +10 -60
  300. package/dist/view/EditorView.d.ts.map +1 -1
  301. package/dist/view/EditorViewEvents.d.ts +54 -0
  302. package/dist/view/EditorViewEvents.d.ts.map +1 -0
  303. package/dist/view/EditorViewNavigation.d.ts +47 -0
  304. package/dist/view/EditorViewNavigation.d.ts.map +1 -0
  305. package/dist/view/SelectionSync.d.ts.map +1 -1
  306. package/dist/view/ViewMovementCommands.d.ts.map +1 -1
  307. package/package.json +12 -2
  308. package/dist/chunks/AttributedMarkCommands-BB7lzFct.mjs +0 -2
  309. package/dist/chunks/AttributedMarkCommands-BB7lzFct.mjs.map +0 -1
  310. package/dist/chunks/ColorPickerPopup-DRzFvt7o.mjs.map +0 -1
  311. package/dist/chunks/Commands-P9wS8qtN.mjs +0 -2
  312. package/dist/chunks/Commands-P9wS8qtN.mjs.map +0 -1
  313. package/dist/chunks/Document-BFYAonMF.mjs +0 -2
  314. package/dist/chunks/Document-BFYAonMF.mjs.map +0 -1
  315. package/dist/chunks/DocumentParser-DFcvVMGY.mjs +0 -2
  316. package/dist/chunks/DocumentParser-DFcvVMGY.mjs.map +0 -1
  317. package/dist/chunks/DomUtils-Cdz1eDKM.mjs +0 -2
  318. package/dist/chunks/DomUtils-Cdz1eDKM.mjs.map +0 -1
  319. package/dist/chunks/HTMLUtils-CCvQ5f83.mjs +0 -2
  320. package/dist/chunks/HTMLUtils-CCvQ5f83.mjs.map +0 -1
  321. package/dist/chunks/HeadingPlugin-DYy3IoT_.mjs +0 -2
  322. package/dist/chunks/HeadingPlugin-DYy3IoT_.mjs.map +0 -1
  323. package/dist/chunks/LocaleService-B6Z-wyAF.mjs +0 -2
  324. package/dist/chunks/LocaleService-B6Z-wyAF.mjs.map +0 -1
  325. package/dist/chunks/MarkCommands-B_erV7zz.mjs +0 -2
  326. package/dist/chunks/MarkCommands-B_erV7zz.mjs.map +0 -1
  327. package/dist/chunks/NavigationQueries-ogQuObz7.mjs +0 -2
  328. package/dist/chunks/NavigationQueries-ogQuObz7.mjs.map +0 -1
  329. package/dist/chunks/NotectlEditor-4NFnXLyD.mjs +0 -2
  330. package/dist/chunks/NotectlEditor-4NFnXLyD.mjs.map +0 -1
  331. package/dist/chunks/Plugin-OzM8Oxm_.mjs +0 -2
  332. package/dist/chunks/Plugin-OzM8Oxm_.mjs.map +0 -1
  333. package/dist/chunks/PluginHelpers-DjZt0pQi.mjs +0 -2
  334. package/dist/chunks/PluginHelpers-DjZt0pQi.mjs.map +0 -1
  335. package/dist/chunks/PopupManager-BM8IT6M7.mjs +0 -2
  336. package/dist/chunks/PopupManager-BM8IT6M7.mjs.map +0 -1
  337. package/dist/chunks/PrintTypes-ehbL7ipA.mjs +0 -2
  338. package/dist/chunks/SelectionTransactions-q71GEzgE.mjs +0 -2
  339. package/dist/chunks/index-C8xtb3SM.mjs +0 -2
  340. package/dist/chunks/index-C8xtb3SM.mjs.map +0 -1
  341. package/dist/chunks/index-DAoSt12h.mjs +0 -2
  342. package/dist/chunks/index-DAoSt12h.mjs.map +0 -1
  343. package/dist/input/BlockInsertion.d.ts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TextColorPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-color/TextColorPlugin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAI1D,OAAO,EAEN,KAAK,eAAe,EAEpB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,QAAQ,6BAA6B,CAAC;IAC5C,UAAU,gBAAgB;QACzB,SAAS,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KAC7B;CACD;AAID,MAAM,WAAW,eAAe;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;CAClC;AAsFD,qBAAa,eAAgB,YAAW,MAAM;IAC7C,QAAQ,CAAC,EAAE,eAAe;IAC1B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,MAAM,CAAmB;gBAErB,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAKvC,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAejD,OAAO,CAAC,gBAAgB;IAuCxB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,mBAAmB;CAkC3B"}
1
+ {"version":3,"file":"TextColorPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-color/TextColorPlugin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK1D,OAAO,EAEN,KAAK,eAAe,EAEpB,MAAM,sBAAsB,CAAC;AAI9B,OAAO,QAAQ,6BAA6B,CAAC;IAC5C,UAAU,gBAAgB;QACzB,SAAS,EAAE;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;KAC7B;CACD;AAID,MAAM,WAAW,eAAe;IAC/B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAC;CAClC;AAsFD,qBAAa,eAAgB,YAAW,MAAM;IAC7C,QAAQ,CAAC,EAAE,eAAe;IAC1B,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,MAAM,CAAmB;gBAErB,MAAM,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAKvC,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjD,OAAO,CAAC,gBAAgB;IAuCxB,OAAO,CAAC,gBAAgB;IAMxB,OAAO,CAAC,mBAAmB;CAkC3B"}
@@ -1,2 +1,2 @@
1
- import{C as e}from"../chunks/color-picker-Byjl_xr9.mjs";import{a as t}from"../chunks/LocaleService-B6Z-wyAF.mjs";import{e as o}from"../chunks/HTMLUtils-CCvQ5f83.mjs";import{a as r}from"../chunks/StyleRuntime-BmsLoEa8.mjs";import{r as s,i as c,b as a}from"../chunks/ColorPickerPopup-DRzFvt7o.mjs";import{r as l,i}from"../chunks/ColorValidation-DCSKq9B2.mjs";const f={label:"Text Color",tooltip:"Text Color",resetLabel:"Default",ariaLabelPrefix:"Text color"},n=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("../chunks/ar-CL3QL0tw.mjs"),"./locales/de.ts":()=>import("../chunks/de-D1OAXtxJ.mjs"),"./locales/es.ts":()=>import("../chunks/es-CBk43isB.mjs"),"./locales/fr.ts":()=>import("../chunks/fr-gurfH-7T.mjs"),"./locales/hi.ts":()=>import("../chunks/hi-DtlvSQkD.mjs"),"./locales/pt.ts":()=>import("../chunks/pt-C-Vp7Rxj.mjs"),"./locales/ru.ts":()=>import("../chunks/ru-B3O7WXNM.mjs"),"./locales/zh.ts":()=>import("../chunks/zh-BfeWdPIz.mjs")});async function m(e){if("en"===e)return f;const t=n[`./locales/${e}.ts`];if(!t)return f;try{return(await t()).default}catch{return f}}const p=["#000000","#434343","#666666","#999999","#b7b7b7","#cccccc","#d9d9d9","#efefef","#f3f3f3","#ffffff","#980000","#ff0000","#ff9900","#ffff00","#00ff00","#00ffff","#4a86e8","#0000ff","#9900ff","#ff00ff","#e6b8af","#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#c9daf8","#cfe2f3","#d9d2e9","#ead1dc","#dd7e6b","#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#a4c2f4","#9fc5e8","#b4a7d6","#d5a6bd","#cc4125","#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6d9eeb","#6fa8dc","#8e7cc3","#c27ba0","#a61c00","#cc0000","#e69138","#f1c232","#6aa84f","#45818e","#3c78d8","#3d85c6","#674ea7","#a64d79","#85200c","#990000","#b45f06","#bf9000","#38761d","#134f5c","#1155cc","#0b5394","#351c75","#741b47"];class h{id="textColor";name="Text Color";priority=23;config;colors;locale;constructor(e){this.config={...e},this.colors=l(e?.colors,p,"TextColorPlugin")}async init(o){if(this.config.locale)this.locale=this.config.locale;else{const e=o.getService(t),r=e?.getLocale()??"en";this.locale="en"===r?f:await m(r)}o.registerStyleSheet(e),this.registerMarkSpec(o),this.registerCommands(o),this.registerToolbarItem(o)}registerMarkSpec(e){e.registerMarkSpec({type:"textColor",rank:5,attrs:{color:{default:""}},toDOM(e){const t=document.createElement("span"),o=e.attrs?.color??"";return r(t,"color",o),t},toHTMLString:(e,t,r)=>{const s=String(e.attrs?.color??"");if(!s||!i(s))return t;const c=`color: ${o(s)}`;return`<span${r?.styleAttr(c)??` style="${c}"`}>${t}</span>`},toHTMLStyle:e=>{const t=String(e.attrs?.color??"");return t&&i(t)?`color: ${o(t)}`:null},parseHTML:[{tag:"span",getAttrs:e=>{const t=e.style.color;return!(!t||!i(t))&&{color:t}}}],sanitize:{tags:["span"]}})}registerCommands(e){e.registerCommand("removeTextColor",()=>s(e,e.getState(),"textColor"))}registerToolbarItem(e){const t=['<svg xmlns="http://www.w3.org/2000/svg"',' viewBox="0 0 24 24">','<path d="M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z"/>','<rect x="3" y="19.5" width="18" height="3"',' rx="0.5" fill="#e53935"/>',"</svg>"].join("");e.registerToolbarItem({id:"textColor",group:"format",icon:t,label:this.locale.label,tooltip:this.locale.tooltip,command:"removeTextColor",popupType:"custom",renderPopup:(e,t,o)=>{a(e,t,{markType:"textColor",colors:this.colors,columns:10,resetLabel:this.locale.resetLabel,resetCommand:"removeTextColor",ariaLabelPrefix:this.locale.ariaLabelPrefix,onClose:o})},isActive:e=>c(e,"textColor")})}}export{f as TEXT_COLOR_LOCALE_EN,h as TextColorPlugin,m as loadTextColorLocale};
1
+ import{C as e}from"../chunks/color-picker-Byjl_xr9.mjs";import{a as t}from"../chunks/HTMLUtils-Cxy99Ak2.mjs";import{a as o}from"../chunks/StyleRuntime-BmsLoEa8.mjs";import{r,i as s,b as c}from"../chunks/ColorPickerPopup-D6XjShhv.mjs";import{r as a,i as l}from"../chunks/ColorValidation-DCSKq9B2.mjs";import{r as i}from"../chunks/PluginHelpers-CdPR0MuT.mjs";const f={label:"Text Color",tooltip:"Text Color",resetLabel:"Default",ariaLabelPrefix:"Text color"},n=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("../chunks/ar-CL3QL0tw.mjs"),"./locales/de.ts":()=>import("../chunks/de-D1OAXtxJ.mjs"),"./locales/es.ts":()=>import("../chunks/es-CBk43isB.mjs"),"./locales/fr.ts":()=>import("../chunks/fr-gurfH-7T.mjs"),"./locales/hi.ts":()=>import("../chunks/hi-DtlvSQkD.mjs"),"./locales/pt.ts":()=>import("../chunks/pt-C-Vp7Rxj.mjs"),"./locales/ru.ts":()=>import("../chunks/ru-B3O7WXNM.mjs"),"./locales/zh.ts":()=>import("../chunks/zh-BfeWdPIz.mjs")});async function m(e){if("en"===e)return f;const t=n[`./locales/${e}.ts`];if(!t)return f;try{return(await t()).default}catch{return f}}const p=["#000000","#434343","#666666","#999999","#b7b7b7","#cccccc","#d9d9d9","#efefef","#f3f3f3","#ffffff","#980000","#ff0000","#ff9900","#ffff00","#00ff00","#00ffff","#4a86e8","#0000ff","#9900ff","#ff00ff","#e6b8af","#f4cccc","#fce5cd","#fff2cc","#d9ead3","#d0e0e3","#c9daf8","#cfe2f3","#d9d2e9","#ead1dc","#dd7e6b","#ea9999","#f9cb9c","#ffe599","#b6d7a8","#a2c4c9","#a4c2f4","#9fc5e8","#b4a7d6","#d5a6bd","#cc4125","#e06666","#f6b26b","#ffd966","#93c47d","#76a5af","#6d9eeb","#6fa8dc","#8e7cc3","#c27ba0","#a61c00","#cc0000","#e69138","#f1c232","#6aa84f","#45818e","#3c78d8","#3d85c6","#674ea7","#a64d79","#85200c","#990000","#b45f06","#bf9000","#38761d","#134f5c","#1155cc","#0b5394","#351c75","#741b47"];class d{id="textColor";name="Text Color";priority=23;config;colors;locale;constructor(e){this.config={...e},this.colors=a(e?.colors,p,"TextColorPlugin")}async init(t){this.locale=await i(t,this.config.locale,f,m),t.registerStyleSheet(e),this.registerMarkSpec(t),this.registerCommands(t),this.registerToolbarItem(t)}registerMarkSpec(e){e.registerMarkSpec({type:"textColor",rank:5,attrs:{color:{default:""}},toDOM(e){const t=document.createElement("span"),r=e.attrs?.color??"";return o(t,"color",r),t},toHTMLString:(e,o,r)=>{const s=String(e.attrs?.color??"");if(!s||!l(s))return o;const c=`color: ${t(s)}`;return`<span${r?.styleAttr(c)??` style="${c}"`}>${o}</span>`},toHTMLStyle:e=>{const o=String(e.attrs?.color??"");return o&&l(o)?`color: ${t(o)}`:null},parseHTML:[{tag:"span",getAttrs:e=>{const t=e.style.color;return!(!t||!l(t))&&{color:t}}}],sanitize:{tags:["span"]}})}registerCommands(e){e.registerCommand("removeTextColor",()=>r(e,e.getState(),"textColor"))}registerToolbarItem(e){const t=['<svg xmlns="http://www.w3.org/2000/svg"',' viewBox="0 0 24 24">','<path d="M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2zm-1.38 9L12 5.67 14.38 12H9.62z"/>','<rect x="3" y="19.5" width="18" height="3"',' rx="0.5" fill="#e53935"/>',"</svg>"].join("");e.registerToolbarItem({id:"textColor",group:"format",icon:t,label:this.locale.label,tooltip:this.locale.tooltip,command:"removeTextColor",popupType:"custom",renderPopup:(e,t,o)=>{c(e,t,{markType:"textColor",colors:this.colors,columns:10,resetLabel:this.locale.resetLabel,resetCommand:"removeTextColor",ariaLabelPrefix:this.locale.ariaLabelPrefix,onClose:o})},isActive:e=>s(e,"textColor")})}}export{f as TEXT_COLOR_LOCALE_EN,d as TextColorPlugin,m as loadTextColorLocale};
2
2
  //# sourceMappingURL=text-color.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"text-color.mjs","sources":["../../src/plugins/text-color/TextColorLocale.ts","../../src/plugins/text-color/TextColorPlugin.ts"],"sourcesContent":["/** Locale interface and default English locale for the TextColorPlugin. */\n\n// --- Locale Interface ---\n\nexport interface TextColorLocale {\n\treadonly label: string;\n\treadonly tooltip: string;\n\treadonly resetLabel: string;\n\treadonly ariaLabelPrefix: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_COLOR_LOCALE_EN: TextColorLocale = {\n\tlabel: 'Text Color',\n\ttooltip: 'Text Color',\n\tresetLabel: 'Default',\n\tariaLabelPrefix: 'Text color',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: Record<string, () => Promise<{ default: TextColorLocale }>> =\n\timport.meta.glob<{ default: TextColorLocale }>('./locales/*.ts', { eager: false });\n\nexport async function loadTextColorLocale(lang: string): Promise<TextColorLocale> {\n\tif (lang === 'en') return TEXT_COLOR_LOCALE_EN;\n\tconst loader = localeModules[`./locales/${lang}.ts`];\n\tif (!loader) return TEXT_COLOR_LOCALE_EN;\n\ttry {\n\t\tconst mod = await loader();\n\t\treturn mod.default;\n\t} catch {\n\t\treturn TEXT_COLOR_LOCALE_EN;\n\t}\n}\n","/**\n * TextColorPlugin: registers a text color mark with attrs,\n * toolbar button with a color picker popup, and removeTextColor command.\n */\n\nimport { COLOR_PICKER_CSS } from '../../editor/styles/color-picker.js';\nimport { LocaleServiceKey } from '../../i18n/LocaleService.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport type { HTMLExportContext } from '../../model/NodeSpec.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport { setStyleProperty } from '../../style/StyleRuntime.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { isColorMarkActive, removeColorMark } from '../shared/ColorMarkOperations.js';\nimport { renderColorPickerPopup } from '../shared/ColorPickerPopup.js';\nimport { isValidCSSColor, resolveColors } from '../shared/ColorValidation.js';\nimport {\n\tTEXT_COLOR_LOCALE_EN,\n\ttype TextColorLocale,\n\tloadTextColorLocale,\n} from './TextColorLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\ttextColor: { color: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface TextColorConfig {\n\t/**\n\t * Restricts the color picker to a specific set of hex colors.\n\t * Each value must be a valid hex color code (`#RGB` or `#RRGGBB`).\n\t * Duplicates are removed automatically (case-insensitive).\n\t * When omitted, the full default palette is shown.\n\t */\n\treadonly colors?: readonly string[];\n\treadonly locale?: TextColorLocale;\n}\n\n// --- Color Palette (Google Docs style: 10 columns x 7 rows) ---\n\nconst COLOR_PALETTE: readonly string[] = [\n\t// Row 1 — dark\n\t'#000000',\n\t'#434343',\n\t'#666666',\n\t'#999999',\n\t'#b7b7b7',\n\t'#cccccc',\n\t'#d9d9d9',\n\t'#efefef',\n\t'#f3f3f3',\n\t'#ffffff',\n\t// Row 2 — vivid\n\t'#980000',\n\t'#ff0000',\n\t'#ff9900',\n\t'#ffff00',\n\t'#00ff00',\n\t'#00ffff',\n\t'#4a86e8',\n\t'#0000ff',\n\t'#9900ff',\n\t'#ff00ff',\n\t// Row 3 — light 3\n\t'#e6b8af',\n\t'#f4cccc',\n\t'#fce5cd',\n\t'#fff2cc',\n\t'#d9ead3',\n\t'#d0e0e3',\n\t'#c9daf8',\n\t'#cfe2f3',\n\t'#d9d2e9',\n\t'#ead1dc',\n\t// Row 4 — light 2\n\t'#dd7e6b',\n\t'#ea9999',\n\t'#f9cb9c',\n\t'#ffe599',\n\t'#b6d7a8',\n\t'#a2c4c9',\n\t'#a4c2f4',\n\t'#9fc5e8',\n\t'#b4a7d6',\n\t'#d5a6bd',\n\t// Row 5 — light 1\n\t'#cc4125',\n\t'#e06666',\n\t'#f6b26b',\n\t'#ffd966',\n\t'#93c47d',\n\t'#76a5af',\n\t'#6d9eeb',\n\t'#6fa8dc',\n\t'#8e7cc3',\n\t'#c27ba0',\n\t// Row 6 — dark 1\n\t'#a61c00',\n\t'#cc0000',\n\t'#e69138',\n\t'#f1c232',\n\t'#6aa84f',\n\t'#45818e',\n\t'#3c78d8',\n\t'#3d85c6',\n\t'#674ea7',\n\t'#a64d79',\n\t// Row 7 — dark 2\n\t'#85200c',\n\t'#990000',\n\t'#b45f06',\n\t'#bf9000',\n\t'#38761d',\n\t'#134f5c',\n\t'#1155cc',\n\t'#0b5394',\n\t'#351c75',\n\t'#741b47',\n];\n\n// --- Plugin ---\n\nexport class TextColorPlugin implements Plugin {\n\treadonly id = 'textColor';\n\treadonly name = 'Text Color';\n\treadonly priority = 23;\n\n\tprivate readonly config: TextColorConfig;\n\tprivate readonly colors: readonly string[];\n\tprivate locale!: TextColorLocale;\n\n\tconstructor(config?: Partial<TextColorConfig>) {\n\t\tthis.config = { ...config };\n\t\tthis.colors = resolveColors(config?.colors, COLOR_PALETTE, 'TextColorPlugin');\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tif (this.config.locale) {\n\t\t\tthis.locale = this.config.locale;\n\t\t} else {\n\t\t\tconst service = context.getService(LocaleServiceKey);\n\t\t\tconst lang: string = service?.getLocale() ?? 'en';\n\t\t\tthis.locale = lang === 'en' ? TEXT_COLOR_LOCALE_EN : await loadTextColorLocale(lang);\n\t\t}\n\n\t\tcontext.registerStyleSheet(COLOR_PICKER_CSS);\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'textColor',\n\t\t\trank: 5,\n\t\t\tattrs: {\n\t\t\t\tcolor: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tconst color = mark.attrs?.color ?? '';\n\t\t\t\tsetStyleProperty(span, 'color', color);\n\t\t\t\treturn span;\n\t\t\t},\n\t\t\ttoHTMLString: (mark, content, ctx?: HTMLExportContext) => {\n\t\t\t\tconst color: string = String(mark.attrs?.color ?? '');\n\t\t\t\tif (!color || !isValidCSSColor(color)) return content;\n\t\t\t\tconst decl: string = `color: ${escapeHTML(color)}`;\n\t\t\t\tconst attr: string = ctx?.styleAttr(decl) ?? ` style=\"${decl}\"`;\n\t\t\t\treturn `<span${attr}>${content}</span>`;\n\t\t\t},\n\t\t\ttoHTMLStyle: (mark) => {\n\t\t\t\tconst color: string = String(mark.attrs?.color ?? '');\n\t\t\t\tif (!color || !isValidCSSColor(color)) return null;\n\t\t\t\treturn `color: ${escapeHTML(color)}`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'span',\n\t\t\t\t\tgetAttrs: (el) => {\n\t\t\t\t\t\tconst color: string = el.style.color;\n\t\t\t\t\t\tif (!color || !isValidCSSColor(color)) return false;\n\t\t\t\t\t\treturn { color };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['span'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('removeTextColor', () => {\n\t\t\treturn removeColorMark(context, context.getState(), 'textColor');\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst pathD =\n\t\t\t'M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2z' + 'm-1.38 9L12 5.67 14.38 12H9.62z';\n\t\tconst icon: string = [\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\"',\n\t\t\t' viewBox=\"0 0 24 24\">',\n\t\t\t`<path d=\"${pathD}\"/>`,\n\t\t\t'<rect x=\"3\" y=\"19.5\" width=\"18\" height=\"3\"',\n\t\t\t' rx=\"0.5\" fill=\"#e53935\"/>',\n\t\t\t'</svg>',\n\t\t].join('');\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'textColor',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: this.locale.label,\n\t\t\ttooltip: this.locale.tooltip,\n\t\t\tcommand: 'removeTextColor',\n\t\t\tpopupType: 'custom',\n\t\t\trenderPopup: (container, ctx, onClose) => {\n\t\t\t\trenderColorPickerPopup(container, ctx, {\n\t\t\t\t\tmarkType: 'textColor',\n\t\t\t\t\tcolors: this.colors,\n\t\t\t\t\tcolumns: 10,\n\t\t\t\t\tresetLabel: this.locale.resetLabel,\n\t\t\t\t\tresetCommand: 'removeTextColor',\n\t\t\t\t\tariaLabelPrefix: this.locale.ariaLabelPrefix,\n\t\t\t\t\tonClose,\n\t\t\t\t});\n\t\t\t},\n\t\t\tisActive: (state: EditorState) => isColorMarkActive(state, 'textColor'),\n\t\t});\n\t}\n}\n"],"names":["TEXT_COLOR_LOCALE_EN","label","tooltip","resetLabel","ariaLabelPrefix","localeModules","assign","import","async","loadTextColorLocale","lang","loader","default","COLOR_PALETTE","TextColorPlugin","id","name","priority","config","colors","locale","constructor","this","resolveColors","init","context","service","getService","LocaleServiceKey","getLocale","registerStyleSheet","COLOR_PICKER_CSS","registerMarkSpec","registerCommands","registerToolbarItem","type","rank","attrs","color","toDOM","mark","span","document","createElement","setStyleProperty","toHTMLString","content","ctx","String","isValidCSSColor","decl","escapeHTML","styleAttr","toHTMLStyle","parseHTML","tag","getAttrs","el","style","sanitize","tags","registerCommand","removeColorMark","getState","icon","join","group","command","popupType","renderPopup","container","onClose","renderColorPickerPopup","markType","columns","resetCommand","isActive","state","isColorMarkActive"],"mappings":"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"}
1
+ {"version":3,"file":"text-color.mjs","sources":["../../src/plugins/text-color/TextColorLocale.ts","../../src/plugins/text-color/TextColorPlugin.ts"],"sourcesContent":["/** Locale interface and default English locale for the TextColorPlugin. */\n\n// --- Locale Interface ---\n\nexport interface TextColorLocale {\n\treadonly label: string;\n\treadonly tooltip: string;\n\treadonly resetLabel: string;\n\treadonly ariaLabelPrefix: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_COLOR_LOCALE_EN: TextColorLocale = {\n\tlabel: 'Text Color',\n\ttooltip: 'Text Color',\n\tresetLabel: 'Default',\n\tariaLabelPrefix: 'Text color',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: Record<string, () => Promise<{ default: TextColorLocale }>> =\n\timport.meta.glob<{ default: TextColorLocale }>('./locales/*.ts', { eager: false });\n\nexport async function loadTextColorLocale(lang: string): Promise<TextColorLocale> {\n\tif (lang === 'en') return TEXT_COLOR_LOCALE_EN;\n\tconst loader = localeModules[`./locales/${lang}.ts`];\n\tif (!loader) return TEXT_COLOR_LOCALE_EN;\n\ttry {\n\t\tconst mod = await loader();\n\t\treturn mod.default;\n\t} catch {\n\t\treturn TEXT_COLOR_LOCALE_EN;\n\t}\n}\n","/**\n * TextColorPlugin: registers a text color mark with attrs,\n * toolbar button with a color picker popup, and removeTextColor command.\n */\n\nimport { COLOR_PICKER_CSS } from '../../editor/styles/color-picker.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport type { HTMLExportContext } from '../../model/NodeSpec.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport { setStyleProperty } from '../../style/StyleRuntime.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { isColorMarkActive, removeColorMark } from '../shared/ColorMarkOperations.js';\nimport { renderColorPickerPopup } from '../shared/ColorPickerPopup.js';\nimport { isValidCSSColor, resolveColors } from '../shared/ColorValidation.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport {\n\tTEXT_COLOR_LOCALE_EN,\n\ttype TextColorLocale,\n\tloadTextColorLocale,\n} from './TextColorLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\ttextColor: { color: string };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface TextColorConfig {\n\t/**\n\t * Restricts the color picker to a specific set of hex colors.\n\t * Each value must be a valid hex color code (`#RGB` or `#RRGGBB`).\n\t * Duplicates are removed automatically (case-insensitive).\n\t * When omitted, the full default palette is shown.\n\t */\n\treadonly colors?: readonly string[];\n\treadonly locale?: TextColorLocale;\n}\n\n// --- Color Palette (Google Docs style: 10 columns x 7 rows) ---\n\nconst COLOR_PALETTE: readonly string[] = [\n\t// Row 1 — dark\n\t'#000000',\n\t'#434343',\n\t'#666666',\n\t'#999999',\n\t'#b7b7b7',\n\t'#cccccc',\n\t'#d9d9d9',\n\t'#efefef',\n\t'#f3f3f3',\n\t'#ffffff',\n\t// Row 2 — vivid\n\t'#980000',\n\t'#ff0000',\n\t'#ff9900',\n\t'#ffff00',\n\t'#00ff00',\n\t'#00ffff',\n\t'#4a86e8',\n\t'#0000ff',\n\t'#9900ff',\n\t'#ff00ff',\n\t// Row 3 — light 3\n\t'#e6b8af',\n\t'#f4cccc',\n\t'#fce5cd',\n\t'#fff2cc',\n\t'#d9ead3',\n\t'#d0e0e3',\n\t'#c9daf8',\n\t'#cfe2f3',\n\t'#d9d2e9',\n\t'#ead1dc',\n\t// Row 4 — light 2\n\t'#dd7e6b',\n\t'#ea9999',\n\t'#f9cb9c',\n\t'#ffe599',\n\t'#b6d7a8',\n\t'#a2c4c9',\n\t'#a4c2f4',\n\t'#9fc5e8',\n\t'#b4a7d6',\n\t'#d5a6bd',\n\t// Row 5 — light 1\n\t'#cc4125',\n\t'#e06666',\n\t'#f6b26b',\n\t'#ffd966',\n\t'#93c47d',\n\t'#76a5af',\n\t'#6d9eeb',\n\t'#6fa8dc',\n\t'#8e7cc3',\n\t'#c27ba0',\n\t// Row 6 — dark 1\n\t'#a61c00',\n\t'#cc0000',\n\t'#e69138',\n\t'#f1c232',\n\t'#6aa84f',\n\t'#45818e',\n\t'#3c78d8',\n\t'#3d85c6',\n\t'#674ea7',\n\t'#a64d79',\n\t// Row 7 — dark 2\n\t'#85200c',\n\t'#990000',\n\t'#b45f06',\n\t'#bf9000',\n\t'#38761d',\n\t'#134f5c',\n\t'#1155cc',\n\t'#0b5394',\n\t'#351c75',\n\t'#741b47',\n];\n\n// --- Plugin ---\n\nexport class TextColorPlugin implements Plugin {\n\treadonly id = 'textColor';\n\treadonly name = 'Text Color';\n\treadonly priority = 23;\n\n\tprivate readonly config: TextColorConfig;\n\tprivate readonly colors: readonly string[];\n\tprivate locale!: TextColorLocale;\n\n\tconstructor(config?: Partial<TextColorConfig>) {\n\t\tthis.config = { ...config };\n\t\tthis.colors = resolveColors(config?.colors, COLOR_PALETTE, 'TextColorPlugin');\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tTEXT_COLOR_LOCALE_EN,\n\t\t\tloadTextColorLocale,\n\t\t);\n\n\t\tcontext.registerStyleSheet(COLOR_PICKER_CSS);\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'textColor',\n\t\t\trank: 5,\n\t\t\tattrs: {\n\t\t\t\tcolor: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst span = document.createElement('span');\n\t\t\t\tconst color = mark.attrs?.color ?? '';\n\t\t\t\tsetStyleProperty(span, 'color', color);\n\t\t\t\treturn span;\n\t\t\t},\n\t\t\ttoHTMLString: (mark, content, ctx?: HTMLExportContext) => {\n\t\t\t\tconst color: string = String(mark.attrs?.color ?? '');\n\t\t\t\tif (!color || !isValidCSSColor(color)) return content;\n\t\t\t\tconst decl: string = `color: ${escapeHTML(color)}`;\n\t\t\t\tconst attr: string = ctx?.styleAttr(decl) ?? ` style=\"${decl}\"`;\n\t\t\t\treturn `<span${attr}>${content}</span>`;\n\t\t\t},\n\t\t\ttoHTMLStyle: (mark) => {\n\t\t\t\tconst color: string = String(mark.attrs?.color ?? '');\n\t\t\t\tif (!color || !isValidCSSColor(color)) return null;\n\t\t\t\treturn `color: ${escapeHTML(color)}`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'span',\n\t\t\t\t\tgetAttrs: (el) => {\n\t\t\t\t\t\tconst color: string = el.style.color;\n\t\t\t\t\t\tif (!color || !isValidCSSColor(color)) return false;\n\t\t\t\t\t\treturn { color };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['span'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('removeTextColor', () => {\n\t\t\treturn removeColorMark(context, context.getState(), 'textColor');\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst pathD =\n\t\t\t'M11 3L5.5 17h2.25l1.12-3h6.25l1.12 3h2.25L13 3h-2z' + 'm-1.38 9L12 5.67 14.38 12H9.62z';\n\t\tconst icon: string = [\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\"',\n\t\t\t' viewBox=\"0 0 24 24\">',\n\t\t\t`<path d=\"${pathD}\"/>`,\n\t\t\t'<rect x=\"3\" y=\"19.5\" width=\"18\" height=\"3\"',\n\t\t\t' rx=\"0.5\" fill=\"#e53935\"/>',\n\t\t\t'</svg>',\n\t\t].join('');\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'textColor',\n\t\t\tgroup: 'format',\n\t\t\ticon,\n\t\t\tlabel: this.locale.label,\n\t\t\ttooltip: this.locale.tooltip,\n\t\t\tcommand: 'removeTextColor',\n\t\t\tpopupType: 'custom',\n\t\t\trenderPopup: (container, ctx, onClose) => {\n\t\t\t\trenderColorPickerPopup(container, ctx, {\n\t\t\t\t\tmarkType: 'textColor',\n\t\t\t\t\tcolors: this.colors,\n\t\t\t\t\tcolumns: 10,\n\t\t\t\t\tresetLabel: this.locale.resetLabel,\n\t\t\t\t\tresetCommand: 'removeTextColor',\n\t\t\t\t\tariaLabelPrefix: this.locale.ariaLabelPrefix,\n\t\t\t\t\tonClose,\n\t\t\t\t});\n\t\t\t},\n\t\t\tisActive: (state: EditorState) => isColorMarkActive(state, 'textColor'),\n\t\t});\n\t}\n}\n"],"names":["TEXT_COLOR_LOCALE_EN","label","tooltip","resetLabel","ariaLabelPrefix","localeModules","assign","import","async","loadTextColorLocale","lang","loader","default","COLOR_PALETTE","TextColorPlugin","id","name","priority","config","colors","locale","constructor","this","resolveColors","init","context","resolveLocale","registerStyleSheet","COLOR_PICKER_CSS","registerMarkSpec","registerCommands","registerToolbarItem","type","rank","attrs","color","toDOM","mark","span","document","createElement","setStyleProperty","toHTMLString","content","ctx","String","isValidCSSColor","decl","escapeHTML","styleAttr","toHTMLStyle","parseHTML","tag","getAttrs","el","style","sanitize","tags","registerCommand","removeColorMark","getState","icon","join","group","command","popupType","renderPopup","container","onClose","renderColorPickerPopup","markType","columns","resetCommand","isActive","state","isColorMarkActive"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TextDirectionCorePlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-direction/TextDirectionCorePlugin.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK1D,OAAO,EAEN,KAAK,mBAAmB,EAExB,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IACnC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;CACtC;AAcD,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAInE,CAAC;AAIF;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,MAAM;IACrD,QAAQ,CAAC,EAAE,oBAAoB;IAC/B,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,eAAe,CAAsC;gBAEjD,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAI3C,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBjD,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,cAAc;IA2BtB,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,YAAY;CAIpB"}
1
+ {"version":3,"file":"TextDirectionCorePlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-direction/TextDirectionCorePlugin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK1D,OAAO,EAEN,KAAK,mBAAmB,EAExB,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IACnC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;CACtC;AAcD,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAInE,CAAC;AAIF;;;GAGG;AACH,qBAAa,uBAAwB,YAAW,MAAM;IACrD,QAAQ,CAAC,EAAE,oBAAoB;IAC/B,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,eAAe,CAAsC;gBAEjD,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAI3C,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjD,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,cAAc;IA2BtB,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,eAAe;IAMvB,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,iBAAiB;IAMzB,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,YAAY;CAIpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"TextDirectionPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-direction/TextDirectionPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAeH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK1D,OAAO,EAEN,KAAK,mBAAmB,EAExB,MAAM,0BAA0B,CAAC;AASlC,OAAO,QAAQ,6BAA6B,CAAC;IAC5C,UAAU,gBAAgB;QACzB,GAAG,EAAE;YAAE,GAAG,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;SAAE,CAAC;KACrC;CACD;AAID,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IACnC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;CACtC;AAgBD,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAInE,CAAC;AASF,qBAAa,mBAAoB,YAAW,MAAM;IACjD,QAAQ,CAAC,EAAE,oBAAoB;IAC/B,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,eAAe,CAAsC;gBAEjD,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAI3C,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BjD,OAAO,IAAI,IAAI;IAOf;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,gBAAgB;IA4DxB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,yBAAyB;IAyBjC,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,YAAY;IA0BpB;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,YAAY;IAOpB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,SAAS;CAOjB"}
1
+ {"version":3,"file":"TextDirectionPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-direction/TextDirectionPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAK1D,OAAO,EAEN,KAAK,mBAAmB,EAExB,MAAM,0BAA0B,CAAC;AASlC,OAAO,QAAQ,6BAA6B,CAAC;IAC5C,UAAU,gBAAgB;QACzB,GAAG,EAAE;YAAE,GAAG,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;SAAE,CAAC;KACrC;CACD;AAID,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IACnC,0CAA0C;IAC1C,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC;CACtC;AAgBD,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAInE,CAAC;AASF,qBAAa,mBAAoB,YAAW,MAAM;IACjD,QAAQ,CAAC,EAAE,oBAAoB;IAC/B,QAAQ,CAAC,IAAI,oBAAoB;IACjC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,eAAe,CAAsC;gBAEjD,MAAM,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAI3C,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BjD,OAAO,IAAI,IAAI;IAOf;;;;OAIG;IACH,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,eAAe;IAiCvB,OAAO,CAAC,gBAAgB;IA4DxB,OAAO,CAAC,eAAe;IASvB,OAAO,CAAC,mBAAmB;IAiC3B,OAAO,CAAC,yBAAyB;IAyBjC,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,YAAY;IA0BpB;;;;;OAKG;IACH,OAAO,CAAC,mBAAmB;IAwB3B,OAAO,CAAC,qBAAqB;IAO7B,OAAO,CAAC,YAAY;IAOpB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,SAAS;CAOjB"}
@@ -1,2 +1,2 @@
1
- import{i as t,a as e,r as i}from"../chunks/AttributedMarkCommands-BB7lzFct.mjs";import{a as o}from"../chunks/LocaleService-B6Z-wyAF.mjs";import{e as r}from"../chunks/HTMLUtils-CCvQ5f83.mjs";import{j as n,i as s,h as a}from"../chunks/Selection-6-W6Flxc.mjs";import{m as l}from"../chunks/TypeBrands-Bp_Z_o5Y.mjs";import{a as c}from"../chunks/Platform-CU6itXZo.mjs";import{g as d}from"../chunks/PluginHelpers-DjZt0pQi.mjs";import{f as h}from"../chunks/ShortcutFormatting-BLKS0Gys.mjs";import{d as u,f as m,g,T as p,l as f,S as v}from"../chunks/TextDirectionLocale-DB_aqrMg.mjs";import{i as b,b as T}from"../chunks/Document-BFYAonMF.mjs";function y(t,e,i){const o=t.getNodePath(e.id);if(o)return{type:"setNodeAttr",path:o,attrs:{...e.attrs,dir:i},previousAttrs:e.attrs}}function B(t,e,i,o){const r=e.getBlock(t.blockId);if(!r||!i.has(r.type))return;const n=b(r);if("auto"!==g(r)&&n.length>0)return;const s=T(r,t.offset),a=n.slice(0,s)+t.text+n.slice(s),l=u(a);if(!l)return;const c=y(e,r,l);c&&o.push(c)}function D(t,e,i,o){const r=e.getBlock(t.blockId);if(!r||!i.has(r.type))return;const n=g(r);if("auto"===n)return;const s=b(r),a=T(r,t.from),l=T(r,t.to),c=s.slice(0,a)+s.slice(l);if(0===c.length){const t=y(e,r,"auto");return void(t&&o.push(t))}const d=u(c);if(!d||d===n)return;const h=y(e,r,d);h&&o.push(h)}const S={directableTypes:["paragraph","heading","title","subtitle","table_cell","blockquote","list_item"]},k={ltr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z"/></svg>',rtl:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z"/></svg>',auto:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z"/></svg>'},w=["ltr","rtl","auto"];class L{id="text-direction";name="Text Direction";priority=91;config;locale;directableTypes;shiftDirHandler=null;constructor(t){this.config={...S,...t}}async init(t){if(this.config.locale)this.locale=this.config.locale;else{const e=t.getService(o),i=e?.getLocale()??"en";this.locale="en"===i?p:await f(i)}this.directableTypes=new Set(this.config.directableTypes),this.patchNodeSpecs(t),this.registerBdiMark(t),this.registerCommands(t),this.registerKeymaps(t),this.registerToolbarItem(t),this.registerInlineToolbarItem(t),function(t,e){t.registerMiddleware((t,i,o)=>{let r=!1;const n=t.steps.map(t=>{if("setBlockType"!==t.type)return t;if(!e.has(t.nodeType))return t;const i=t.previousAttrs?.dir;return i&&"auto"!==i?(r=!0,{...t,attrs:{...t.attrs,dir:i}}):t});o(r?{...t,steps:n}:t)},{name:"text-direction:preserve-dir"})}(t,this.directableTypes),function(t,e){t.registerMiddleware((t,i,o)=>{const r=[];for(const n of t.steps)"insertText"===n.type?B(n,i,e,r):"deleteText"===n.type&&D(n,i,e,r);o(r.length>0?{...t,steps:[...t.steps,...r]}:t)},{name:"text-direction:auto-detect"})}(t,this.directableTypes),function(t,e){t.registerMiddleware((t,i,o)=>{let r=!1;const n=t.steps.map(t=>{if("insertNode"!==t.type)return t;if(!e.has(t.node.type))return t;if("auto"!==String(t.node.attrs?.dir??"auto"))return t;const o=b(t.node);if(o.length>0){const e=u(o);if(e)return r=!0,{...t,node:{...t.node,attrs:{...t.node.attrs,dir:e}}}}const n=m(i,t.parentPath,t.index);return n&&"auto"!==n?(r=!0,{...t,node:{...t.node,attrs:{...t.node.attrs,dir:n}}}):t});o(r?{...t,steps:n}:t)},{name:"text-direction:inherit-dir"})}(t,this.directableTypes),c()||(this.shiftDirHandler=new v(t),this.shiftDirHandler.attach(t.getContainer()))}destroy(){this.shiftDirHandler?.detach(),this.shiftDirHandler=null}patchNodeSpecs(t){const e=t.getSchemaRegistry();for(const i of this.config.directableTypes){const t=e.getNodeSpec(i);if(!t)continue;if(t.attrs?.dir)continue;const o=t.toDOM;e.removeNodeSpec(i),e.registerNodeSpec({...t,attrs:{...t.attrs,dir:{default:"auto"}},toDOM(e){const i=o.call(t,e);return x(i,e),i}})}}registerBdiMark(t){t.registerMarkSpec({type:"bdi",rank:10,attrs:{dir:{default:"auto"}},toDOM(t){const e=document.createElement("bdi"),i=String(t.attrs?.dir??"auto");return e.setAttribute("dir",i),e},toHTMLString:(t,e)=>`<bdi dir="${r(String(t.attrs?.dir??"auto"))}">${e}</bdi>`,parseHTML:[{tag:"bdi",getAttrs:t=>{const e=t.getAttribute("dir");return"ltr"===e||"rtl"===e?{dir:e}:{dir:"auto"}}}],sanitize:{tags:["bdi"],attrs:["dir"]}})}registerCommands(t){t.registerCommand("setDirectionLTR",()=>{const e=this.setDirection(t,"ltr");return e&&t.announce(this.locale.announceLTR),e}),t.registerCommand("setDirectionRTL",()=>{const e=this.setDirection(t,"rtl");return e&&t.announce(this.locale.announceRTL),e}),t.registerCommand("setDirectionAuto",()=>{const e=this.setDirection(t,"auto");return e&&t.announce(this.locale.announceAuto),e}),t.registerCommand("toggleBidiLTR",()=>{const e=this.applyBdi(t,"ltr");return e&&t.announce(this.locale.inlineLTR),e}),t.registerCommand("toggleBidiRTL",()=>{const e=this.applyBdi(t,"rtl");return e&&t.announce(this.locale.inlineRTL),e}),t.registerCommand("toggleBidiAuto",()=>{const e=this.applyBdi(t,"auto");return e&&t.announce(this.locale.inlineAuto),e}),t.registerCommand("removeBidi",()=>{const e=this.removeBdi(t);return e&&t.announce(this.locale.announceRemoveBidi),e}),t.registerCommand("toggleBidiIsolation",()=>this.toggleBidiIsolation(t)),t.registerCommand("toggleDirection",()=>{const e=t.getState(),i=d(e);if(!i||!this.directableTypes.has(i.type))return!1;const o=g(i),r="auto"===o?"rtl":"rtl"===o?"ltr":"auto";return this.setDirection(t,r)})}registerKeymaps(t){t.registerKeymap({"Mod-Shift-D":()=>t.executeCommand("toggleDirection"),"Mod-Shift-B":()=>t.executeCommand("toggleBidiIsolation")})}registerToolbarItem(t){const e={ltr:"setDirectionLTR",rtl:"setDirectionRTL",auto:"setDirectionAuto"},i=w.map(t=>({label:this.getDirectionLabel(t),command:e[t],icon:k[t]}));t.registerToolbarItem({id:"text-direction",group:"block",icon:k.auto,label:this.locale.toolbarLabel,tooltip:`${this.locale.toolbarTooltip} (${h("Mod-Shift-D")})`,command:"setDirectionAuto",popupType:"dropdown",popupConfig:{items:i},isActive:t=>this.isNonDefaultDirection(t),isEnabled:t=>this.isDirectable(t),getIcon:t=>{const e=d(t);if(!e)return k.auto;const i=g(e);return k[i]??k.auto}})}registerInlineToolbarItem(e){const i=[{label:this.locale.inlineLTR,command:"toggleBidiLTR",icon:k.ltr},{label:this.locale.inlineRTL,command:"toggleBidiRTL",icon:k.rtl},{label:this.locale.inlineAuto,command:"toggleBidiAuto",icon:k.auto},{label:this.locale.announceRemoveBidi,command:"removeBidi"}];e.registerToolbarItem({id:"inline-direction",group:"format",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 4v7h2V4h2v7h2V4h1V2H10a3 3 0 1 0 0 6zm-3.5 9.5L3 17l3.5 3.5V18h3v-2h-3v-2.5zm14 0L17 17l3.5 3.5V18h-3v-2h3v-2.5zM11 16h2v6h-2z"/></svg>',label:this.locale.inlineLabel,tooltip:`${this.locale.inlineTooltip} (${h("Mod-Shift-B")})`,command:"toggleBidiIsolation",popupType:"dropdown",popupConfig:{items:i},isActive:e=>t(e,"bdi"),isEnabled:t=>{const e=t.selection;return n(e)&&!s(e)}})}getDirectionLabel(t){return"ltr"===t?this.locale.ltr:"rtl"===t?this.locale.rtl:this.locale.auto}setDirection(t,e){const i=t.getState(),o=this.getSelectedBlockIds(i);if(0===o.length)return!1;const r=i.transaction("command");let n=!1;for(const a of o){const t=i.getBlock(a);if(!t||!this.directableTypes.has(t.type))continue;const o=i.getNodePath(a);o&&(r.setNodeAttr(o,{...t.attrs,dir:e}),n=!0)}if(!n)return!1;const s=r.setSelection(i.selection).build();return t.dispatch(s),!0}getSelectedBlockIds(t){const e=t.selection;if(a(e))return[e.nodeId];if(!n(e))return[];const i=e.anchor.blockId,o=e.head.blockId;if(i===o)return[i];const r=t.getBlockOrder(),s=r.indexOf(i),l=r.indexOf(o);if(-1===s||-1===l)return[];const c=Math.min(s,l),d=Math.max(s,l);return r.slice(c,d+1)}isNonDefaultDirection(t){const e=d(t);if(!e||!this.directableTypes.has(e.type))return!1;const i=e.attrs?.dir;return null!=i&&"auto"!==i}isDirectable(t){const e=d(t);return null!=e&&this.directableTypes.has(e.type)}toggleBidiIsolation(e){const i=e.getState();if(t(i,"bdi")){const t=this.removeBdi(e);return t&&e.announce(this.locale.announceRemoveBidi),t}const o=d(i),r="rtl"===(o?g(o):"auto")?"ltr":"rtl",n=this.applyBdi(e,r);if(n){const t="ltr"===r?this.locale.inlineLTR:this.locale.inlineRTL;e.announce(t)}return n}applyBdi(t,i){const o=t.getState(),r={type:l("bdi"),attrs:{dir:i}},n=e(o,r);return!!n&&(t.dispatch(n),!0)}removeBdi(t){const e=t.getState(),o=i(e,l("bdi"));return!!o&&(t.dispatch(o),!0)}}function x(t,e){const i=e.attrs?.dir;"ltr"!==i&&"rtl"!==i&&"auto"!==i||t.setAttribute("dir",i)}export{k as DIRECTION_ICONS,p as TEXT_DIRECTION_LOCALE_EN,L as TextDirectionAdvancedPlugin,u as detectTextDirection,m as findSiblingDirection,g as getBlockDir,f as loadTextDirectionLocale};
1
+ import{i as t,a as e,r as i}from"../chunks/AttributedMarkCommands-BY1BSYWM.mjs";import{a as o}from"../chunks/HTMLUtils-Cxy99Ak2.mjs";import{j as r,i as n,h as s}from"../chunks/Selection-DhbizDM4.mjs";import{m as a}from"../chunks/TypeBrands-Bp_Z_o5Y.mjs";import{a as l}from"../chunks/Platform-CU6itXZo.mjs";import{r as c,g as d}from"../chunks/PluginHelpers-CdPR0MuT.mjs";import{f as u}from"../chunks/ShortcutFormatting-BLKS0Gys.mjs";import{d as h,f as m,g,S as p,l as f,T as b}from"../chunks/TextDirectionLocale-CKz0ZrH_.mjs";import{i as v,b as T}from"../chunks/Document-3pNX7ear.mjs";function y(t,e,i){const o=t.getNodePath(e.id);if(o)return{type:"setNodeAttr",path:o,attrs:{...e.attrs,dir:i},previousAttrs:e.attrs}}function B(t,e,i,o){const r=e.getBlock(t.blockId);if(!r||!i.has(r.type))return;const n=v(r);if("auto"!==g(r)&&n.length>0)return;const s=T(r,t.offset),a=n.slice(0,s)+t.text+n.slice(s),l=h(a);if(!l)return;const c=y(e,r,l);c&&o.push(c)}function D(t,e,i,o){const r=e.getBlock(t.blockId);if(!r||!i.has(r.type))return;const n=g(r);if("auto"===n)return;const s=v(r),a=T(r,t.from),l=T(r,t.to),c=s.slice(0,a)+s.slice(l);if(0===c.length){const t=y(e,r,"auto");return void(t&&o.push(t))}const d=h(c);if(!d||d===n)return;const u=y(e,r,d);u&&o.push(u)}const w={directableTypes:["paragraph","heading","title","subtitle","table_cell","blockquote","list_item"]},k={ltr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z"/></svg>',rtl:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z"/></svg>',auto:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z"/></svg>'},S=["ltr","rtl","auto"];class x{id="text-direction";name="Text Direction";priority=91;config;locale;directableTypes;shiftDirHandler=null;constructor(t){this.config={...w,...t}}async init(t){this.locale=await c(t,this.config.locale,b,f),this.directableTypes=new Set(this.config.directableTypes),this.patchNodeSpecs(t),this.registerBdiMark(t),this.registerCommands(t),this.registerKeymaps(t),this.registerToolbarItem(t),this.registerInlineToolbarItem(t),function(t,e){t.registerMiddleware((t,i,o)=>{let r=!1;const n=t.steps.map(t=>{if("setBlockType"!==t.type)return t;if(!e.has(t.nodeType))return t;const i=t.previousAttrs?.dir;return i&&"auto"!==i?(r=!0,{...t,attrs:{...t.attrs,dir:i}}):t});o(r?{...t,steps:n}:t)},{name:"text-direction:preserve-dir"})}(t,this.directableTypes),function(t,e){t.registerMiddleware((t,i,o)=>{const r=[];for(const n of t.steps)"insertText"===n.type?B(n,i,e,r):"deleteText"===n.type&&D(n,i,e,r);o(r.length>0?{...t,steps:[...t.steps,...r]}:t)},{name:"text-direction:auto-detect"})}(t,this.directableTypes),function(t,e){t.registerMiddleware((t,i,o)=>{let r=!1;const n=t.steps.map(t=>{if("insertNode"!==t.type)return t;if(!e.has(t.node.type))return t;if("auto"!==String(t.node.attrs?.dir??"auto"))return t;const o=v(t.node);if(o.length>0){const e=h(o);if(e)return r=!0,{...t,node:{...t.node,attrs:{...t.node.attrs,dir:e}}}}const n=m(i,t.parentPath,t.index);return n&&"auto"!==n?(r=!0,{...t,node:{...t.node,attrs:{...t.node.attrs,dir:n}}}):t});o(r?{...t,steps:n}:t)},{name:"text-direction:inherit-dir"})}(t,this.directableTypes),l()||(this.shiftDirHandler=new p(t),this.shiftDirHandler.attach(t.getContainer()))}destroy(){this.shiftDirHandler?.detach(),this.shiftDirHandler=null}patchNodeSpecs(t){const e=t.getSchemaRegistry();for(const i of this.config.directableTypes){const t=e.getNodeSpec(i);if(!t)continue;if(t.attrs?.dir)continue;const o=t.toDOM;e.removeNodeSpec(i),e.registerNodeSpec({...t,attrs:{...t.attrs,dir:{default:"auto"}},toDOM(e){const i=o.call(t,e);return L(i,e),i}})}}registerBdiMark(t){t.registerMarkSpec({type:"bdi",rank:10,attrs:{dir:{default:"auto"}},toDOM(t){const e=document.createElement("bdi"),i=String(t.attrs?.dir??"auto");return e.setAttribute("dir",i),e},toHTMLString:(t,e)=>`<bdi dir="${o(String(t.attrs?.dir??"auto"))}">${e}</bdi>`,parseHTML:[{tag:"bdi",getAttrs:t=>{const e=t.getAttribute("dir");return"ltr"===e||"rtl"===e?{dir:e}:{dir:"auto"}}}],sanitize:{tags:["bdi"],attrs:["dir"]}})}registerCommands(t){t.registerCommand("setDirectionLTR",()=>{const e=this.setDirection(t,"ltr");return e&&t.announce(this.locale.announceLTR),e}),t.registerCommand("setDirectionRTL",()=>{const e=this.setDirection(t,"rtl");return e&&t.announce(this.locale.announceRTL),e}),t.registerCommand("setDirectionAuto",()=>{const e=this.setDirection(t,"auto");return e&&t.announce(this.locale.announceAuto),e}),t.registerCommand("toggleBidiLTR",()=>{const e=this.applyBdi(t,"ltr");return e&&t.announce(this.locale.inlineLTR),e}),t.registerCommand("toggleBidiRTL",()=>{const e=this.applyBdi(t,"rtl");return e&&t.announce(this.locale.inlineRTL),e}),t.registerCommand("toggleBidiAuto",()=>{const e=this.applyBdi(t,"auto");return e&&t.announce(this.locale.inlineAuto),e}),t.registerCommand("removeBidi",()=>{const e=this.removeBdi(t);return e&&t.announce(this.locale.announceRemoveBidi),e}),t.registerCommand("toggleBidiIsolation",()=>this.toggleBidiIsolation(t)),t.registerCommand("toggleDirection",()=>{const e=t.getState(),i=d(e);if(!i||!this.directableTypes.has(i.type))return!1;const o=g(i),r="auto"===o?"rtl":"rtl"===o?"ltr":"auto";return this.setDirection(t,r)})}registerKeymaps(t){t.registerKeymap({"Mod-Shift-D":()=>t.executeCommand("toggleDirection"),"Mod-Shift-B":()=>t.executeCommand("toggleBidiIsolation")})}registerToolbarItem(t){const e={ltr:"setDirectionLTR",rtl:"setDirectionRTL",auto:"setDirectionAuto"},i=S.map(t=>({label:this.getDirectionLabel(t),command:e[t],icon:k[t]}));t.registerToolbarItem({id:"text-direction",group:"block",icon:k.auto,label:this.locale.toolbarLabel,tooltip:`${this.locale.toolbarTooltip} (${u("Mod-Shift-D")})`,command:"setDirectionAuto",popupType:"dropdown",popupConfig:{items:i},isActive:t=>this.isNonDefaultDirection(t),isEnabled:t=>this.isDirectable(t),getIcon:t=>{const e=d(t);if(!e)return k.auto;const i=g(e);return k[i]??k.auto}})}registerInlineToolbarItem(e){const i=[{label:this.locale.inlineLTR,command:"toggleBidiLTR",icon:k.ltr},{label:this.locale.inlineRTL,command:"toggleBidiRTL",icon:k.rtl},{label:this.locale.inlineAuto,command:"toggleBidiAuto",icon:k.auto},{label:this.locale.announceRemoveBidi,command:"removeBidi"}];e.registerToolbarItem({id:"inline-direction",group:"format",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 4v7h2V4h2v7h2V4h1V2H10a3 3 0 1 0 0 6zm-3.5 9.5L3 17l3.5 3.5V18h3v-2h-3v-2.5zm14 0L17 17l3.5 3.5V18h-3v-2h3v-2.5zM11 16h2v6h-2z"/></svg>',label:this.locale.inlineLabel,tooltip:`${this.locale.inlineTooltip} (${u("Mod-Shift-B")})`,command:"toggleBidiIsolation",popupType:"dropdown",popupConfig:{items:i},isActive:e=>t(e,"bdi"),isEnabled:t=>{const e=t.selection;return r(e)&&!n(e)}})}getDirectionLabel(t){return"ltr"===t?this.locale.ltr:"rtl"===t?this.locale.rtl:this.locale.auto}setDirection(t,e){const i=t.getState(),o=this.getSelectedBlockIds(i);if(0===o.length)return!1;const r=i.transaction("command");let n=!1;for(const a of o){const t=i.getBlock(a);if(!t||!this.directableTypes.has(t.type))continue;const o=i.getNodePath(a);o&&(r.setNodeAttr(o,{...t.attrs,dir:e}),n=!0)}if(!n)return!1;const s=r.setSelection(i.selection).build();return t.dispatch(s),!0}getSelectedBlockIds(t){const e=t.selection;if(s(e))return[e.nodeId];if(!r(e))return[];const i=e.anchor.blockId,o=e.head.blockId;if(i===o)return[i];const n=t.getBlockOrder(),a=n.indexOf(i),l=n.indexOf(o);if(-1===a||-1===l)return[];const c=Math.min(a,l),d=Math.max(a,l);return n.slice(c,d+1)}isNonDefaultDirection(t){const e=d(t);if(!e||!this.directableTypes.has(e.type))return!1;const i=e.attrs?.dir;return null!=i&&"auto"!==i}isDirectable(t){const e=d(t);return null!=e&&this.directableTypes.has(e.type)}toggleBidiIsolation(e){const i=e.getState();if(t(i,"bdi")){const t=this.removeBdi(e);return t&&e.announce(this.locale.announceRemoveBidi),t}const o=d(i),r="rtl"===(o?g(o):"auto")?"ltr":"rtl",n=this.applyBdi(e,r);if(n){const t="ltr"===r?this.locale.inlineLTR:this.locale.inlineRTL;e.announce(t)}return n}applyBdi(t,i){const o=t.getState(),r={type:a("bdi"),attrs:{dir:i}},n=e(o,r);return!!n&&(t.dispatch(n),!0)}removeBdi(t){const e=t.getState(),o=i(e,a("bdi"));return!!o&&(t.dispatch(o),!0)}}function L(t,e){const i=e.attrs?.dir;"ltr"!==i&&"rtl"!==i&&"auto"!==i||t.setAttribute("dir",i)}export{k as DIRECTION_ICONS,b as TEXT_DIRECTION_LOCALE_EN,x as TextDirectionAdvancedPlugin,h as detectTextDirection,m as findSiblingDirection,g as getBlockDir,f as loadTextDirectionLocale};
2
2
  //# sourceMappingURL=text-direction-advanced.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"text-direction-advanced.mjs","sources":["../../src/plugins/text-direction/TextDirectionMiddleware.ts","../../src/plugins/text-direction/TextDirectionPlugin.ts"],"sourcesContent":["/**\n * Middleware registrations for the TextDirectionPlugin.\n * Separated from the main plugin file for maintainability.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { blockOffsetToTextOffset, getBlockText } from '../../model/Document.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Step } from '../../state/Transaction.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { detectTextDirection, findSiblingDirection, getBlockDir } from './DirectionDetection.js';\nimport type { TextDirection } from './TextDirectionPlugin.js';\n\n/**\n * Preserves the `dir` attribute when other plugins change the block\n * type (e.g. paragraph -> heading) via `setBlockType`, which replaces attrs.\n */\nexport function registerPreserveDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, _state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'setBlockType') return step;\n\t\t\t\tif (!directableTypes.has(step.nodeType)) return step;\n\n\t\t\t\tconst prevDir = step.previousAttrs?.dir;\n\t\t\t\tif (!prevDir || prevDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tattrs: { ...step.attrs, dir: prevDir },\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:preserve-dir' },\n\t);\n}\n\n/**\n * Auto-detects text direction on `insertText` and `deleteText` steps\n * for blocks with `dir=\"auto\"` (or blocks whose content changes direction).\n * Uses the first strong directional character to determine LTR vs RTL.\n */\nexport function registerAutoDetectMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tconst extraSteps: Step[] = [];\n\n\t\t\tfor (const step of tr.steps) {\n\t\t\t\tif (step.type === 'insertText') {\n\t\t\t\t\thandleInsertText(step, state, directableTypes, extraSteps);\n\t\t\t\t} else if (step.type === 'deleteText') {\n\t\t\t\t\thandleDeleteText(step, state, directableTypes, extraSteps);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (extraSteps.length > 0) {\n\t\t\t\tnext({ ...tr, steps: [...tr.steps, ...extraSteps] });\n\t\t\t} else {\n\t\t\t\tnext(tr);\n\t\t\t}\n\t\t},\n\t\t{ name: 'text-direction:auto-detect' },\n\t);\n}\n\n/** Builds a `setNodeAttr` step to change the `dir` attribute of a block. */\nfunction buildDirChangeStep(\n\tstate: EditorState,\n\tblock: BlockNode,\n\tdir: TextDirection | 'auto',\n): Step | undefined {\n\tconst path = state.getNodePath(block.id);\n\tif (!path) return undefined;\n\n\treturn {\n\t\ttype: 'setNodeAttr',\n\t\tpath,\n\t\tattrs: { ...block.attrs, dir },\n\t\tpreviousAttrs: block.attrs as Record<string, string | number | boolean>,\n\t};\n}\n\n/** Handles direction detection after text insertion. */\nfunction handleInsertText(\n\tstep: Extract<Step, { type: 'insertText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tconst existingText: string = getBlockText(block);\n\tif (getBlockDir(block) !== 'auto' && existingText.length > 0) return;\n\n\tconst textOffset: number = blockOffsetToTextOffset(block, step.offset);\n\tconst textAfter: string =\n\t\texistingText.slice(0, textOffset) + step.text + existingText.slice(textOffset);\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\n/** Handles direction re-detection after text deletion. */\nfunction handleDeleteText(\n\tstep: Extract<Step, { type: 'deleteText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tconst currentDir: TextDirection = getBlockDir(block);\n\tif (currentDir === 'auto') return;\n\n\tconst existingText: string = getBlockText(block);\n\tconst fromText: number = blockOffsetToTextOffset(block, step.from);\n\tconst toText: number = blockOffsetToTextOffset(block, step.to);\n\tconst textAfter: string = existingText.slice(0, fromText) + existingText.slice(toText);\n\n\tif (textAfter.length === 0) {\n\t\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, 'auto');\n\t\tif (dirStep) extraSteps.push(dirStep);\n\t\treturn;\n\t}\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected || detected === currentDir) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\n/**\n * Inherits `dir` from the nearest sibling when inserting a new block\n * (e.g. via GapCursor or NodeSelection).\n */\nexport function registerInheritDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'insertNode') return step;\n\t\t\t\tif (!directableTypes.has(step.node.type)) return step;\n\n\t\t\t\tconst newDir: string = String(step.node.attrs?.dir ?? 'auto');\n\t\t\t\tif (newDir !== 'auto') return step;\n\n\t\t\t\t// Detect direction from inserted node's text content\n\t\t\t\tconst nodeText: string = getBlockText(step.node);\n\t\t\t\tif (nodeText.length > 0) {\n\t\t\t\t\tconst detected: TextDirection | null = detectTextDirection(nodeText);\n\t\t\t\t\tif (detected) {\n\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...step,\n\t\t\t\t\t\t\tnode: {\n\t\t\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: detected },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fall back to sibling direction for empty blocks\n\t\t\t\tconst siblingDir: string | undefined = findSiblingDirection(\n\t\t\t\t\tstate,\n\t\t\t\t\tstep.parentPath,\n\t\t\t\t\tstep.index,\n\t\t\t\t);\n\t\t\t\tif (!siblingDir || siblingDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tnode: {\n\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: siblingDir },\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:inherit-dir' },\n\t);\n}\n","/**\n * TextDirectionPlugin: adds block-level text direction (`dir` attribute)\n * and inline bidi isolation (`<bdi>` mark) for RTL language support.\n *\n * Block-level: patches NodeSpecs for directable types to render the HTML\n * `dir` attribute. Provides `setDirectionLTR`, `setDirectionRTL`, and\n * `setDirectionAuto` commands with a toolbar dropdown.\n *\n * Inline: registers a `bdi` mark for bidi isolation of inline spans,\n * with `toggleBidiLTR`, `toggleBidiRTL`, `toggleBidiAuto`, and\n * `removeBidi` commands.\n */\n\nimport {\n\tapplyAttributedMark,\n\tisAttributedMarkActive,\n\tremoveAttributedMark,\n} from '../../commands/AttributedMarkCommands.js';\nimport { LocaleServiceKey } from '../../i18n/LocaleService.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport { isCollapsed, isNodeSelection, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport { isMac } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { getSelectedBlock } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { getBlockDir } from './DirectionDetection.js';\nimport { ShiftDirectionHandler } from './ShiftDirectionHandler.js';\nimport {\n\tTEXT_DIRECTION_LOCALE_EN,\n\ttype TextDirectionLocale,\n\tloadTextDirectionLocale,\n} from './TextDirectionLocale.js';\nimport {\n\tregisterAutoDetectMiddleware,\n\tregisterInheritDirMiddleware,\n\tregisterPreserveDirMiddleware,\n} from './TextDirectionMiddleware.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tbdi: { dir: 'ltr' | 'rtl' | 'auto' };\n\t}\n}\n\n// --- Public Types ---\n\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\n\nexport interface TextDirectionConfig {\n\t/** Block types that support direction. */\n\treadonly directableTypes: readonly string[];\n\treadonly locale?: TextDirectionLocale;\n}\n\n// --- Constants ---\n\nconst DEFAULT_CONFIG: TextDirectionConfig = {\n\tdirectableTypes: [\n\t\t'paragraph',\n\t\t'heading',\n\t\t'title',\n\t\t'subtitle',\n\t\t'table_cell',\n\t\t'blockquote',\n\t\t'list_item',\n\t],\n};\n\nexport const DIRECTION_ICONS: Readonly<Record<TextDirection, string>> = {\n\tltr: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z\"/></svg>',\n\trtl: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z\"/></svg>',\n\tauto: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z\"/></svg>',\n};\n\nconst ALL_DIRECTIONS: readonly TextDirection[] = ['ltr', 'rtl', 'auto'];\n\nconst INLINE_BDI_ICON: string =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4v7h2V4h2v7h2V4h1V2H10a3 3 0 1 0 0 6zm-3.5 9.5L3 17l3.5 3.5V18h3v-2h-3v-2.5zm14 0L17 17l3.5 3.5V18h-3v-2h3v-2.5zM11 16h2v6h-2z\"/></svg>';\n\n// --- Plugin ---\n\nexport class TextDirectionPlugin implements Plugin {\n\treadonly id = 'text-direction';\n\treadonly name = 'Text Direction';\n\treadonly priority = 91;\n\n\tprivate readonly config: TextDirectionConfig;\n\tprivate locale!: TextDirectionLocale;\n\tprivate directableTypes!: ReadonlySet<string>;\n\tprivate shiftDirHandler: ShiftDirectionHandler | null = null;\n\n\tconstructor(config?: Partial<TextDirectionConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tif (this.config.locale) {\n\t\t\tthis.locale = this.config.locale;\n\t\t} else {\n\t\t\tconst service = context.getService(LocaleServiceKey);\n\t\t\tconst lang: string = service?.getLocale() ?? 'en';\n\t\t\tthis.locale = lang === 'en' ? TEXT_DIRECTION_LOCALE_EN : await loadTextDirectionLocale(lang);\n\t\t}\n\n\t\tthis.directableTypes = new Set(this.config.directableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerBdiMark(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\t\tthis.registerInlineToolbarItem(context);\n\t\tregisterPreserveDirMiddleware(context, this.directableTypes);\n\t\tregisterAutoDetectMiddleware(context, this.directableTypes);\n\t\tregisterInheritDirMiddleware(context, this.directableTypes);\n\n\t\t// Ctrl+Shift direction shortcuts (Windows/Linux convention)\n\t\tif (!isMac()) {\n\t\t\tthis.shiftDirHandler = new ShiftDirectionHandler(context);\n\t\t\tthis.shiftDirHandler.attach(context.getContainer());\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.shiftDirHandler?.detach();\n\t\tthis.shiftDirHandler = null;\n\t}\n\n\t// --- NodeSpec Patching ---\n\n\t/**\n\t * Patches existing NodeSpecs for directable block types to support the\n\t * `dir` attribute and render it as an HTML attribute. Skips types\n\t * that already define a `dir` attribute in their spec.\n\t */\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tconst registry = context.getSchemaRegistry();\n\n\t\tfor (const type of this.config.directableTypes) {\n\t\t\tconst spec = registry.getNodeSpec(type);\n\t\t\tif (!spec) continue;\n\n\t\t\tif (spec.attrs?.dir) continue;\n\n\t\t\tconst originalToDOM = spec.toDOM;\n\n\t\t\tregistry.removeNodeSpec(type);\n\t\t\tregistry.registerNodeSpec({\n\t\t\t\t...spec,\n\t\t\t\tattrs: {\n\t\t\t\t\t...spec.attrs,\n\t\t\t\t\tdir: { default: 'auto' },\n\t\t\t\t},\n\t\t\t\ttoDOM(node) {\n\t\t\t\t\tconst el = originalToDOM.call(spec, node);\n\t\t\t\t\tapplyDirection(el, node);\n\t\t\t\t\treturn el;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\t// --- Inline <bdi> Mark ---\n\n\tprivate registerBdiMark(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'bdi',\n\t\t\trank: 10,\n\t\t\tattrs: {\n\t\t\t\tdir: { default: 'auto' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst el: HTMLElement = document.createElement('bdi');\n\t\t\t\tconst dir: string = String(mark.attrs?.dir ?? 'auto');\n\t\t\t\tel.setAttribute('dir', dir);\n\t\t\t\treturn el;\n\t\t\t},\n\t\t\ttoHTMLString: (mark, content) => {\n\t\t\t\tconst dir: string = escapeHTML(String(mark.attrs?.dir ?? 'auto'));\n\t\t\t\treturn `<bdi dir=\"${dir}\">${content}</bdi>`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'bdi',\n\t\t\t\t\tgetAttrs: (el) => {\n\t\t\t\t\t\tconst dir: string | null = el.getAttribute('dir');\n\t\t\t\t\t\tif (dir === 'ltr' || dir === 'rtl') return { dir };\n\t\t\t\t\t\treturn { dir: 'auto' };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['bdi'], attrs: ['dir'] },\n\t\t});\n\t}\n\n\t// --- Commands ---\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('setDirectionLTR', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.announceLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionRTL', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.announceRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionAuto', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.announceAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiLTR', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.inlineLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiRTL', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.inlineRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiAuto', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.inlineAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('removeBidi', () => {\n\t\t\tconst result: boolean = this.removeBdi(context);\n\t\t\tif (result) context.announce(this.locale.announceRemoveBidi);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiIsolation', () => {\n\t\t\treturn this.toggleBidiIsolation(context);\n\t\t});\n\n\t\tcontext.registerCommand('toggleDirection', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst block = getSelectedBlock(state);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\n\t\t\tconst current: TextDirection = getBlockDir(block);\n\t\t\tconst next: TextDirection = current === 'auto' ? 'rtl' : current === 'rtl' ? 'ltr' : 'auto';\n\t\t\treturn this.setDirection(context, next);\n\t\t});\n\t}\n\n\t// --- Keymaps ---\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-D': () => context.executeCommand('toggleDirection'),\n\t\t\t'Mod-Shift-B': () => context.executeCommand('toggleBidiIsolation'),\n\t\t});\n\t}\n\n\t// --- Toolbar ---\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst commandNames: Readonly<Record<TextDirection, string>> = {\n\t\t\tltr: 'setDirectionLTR',\n\t\t\trtl: 'setDirectionRTL',\n\t\t\tauto: 'setDirectionAuto',\n\t\t};\n\n\t\tconst dropdownItems = ALL_DIRECTIONS.map((dir) => ({\n\t\t\tlabel: this.getDirectionLabel(dir),\n\t\t\tcommand: commandNames[dir],\n\t\t\ticon: DIRECTION_ICONS[dir],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-direction',\n\t\t\tgroup: 'block',\n\t\t\ticon: DIRECTION_ICONS.auto,\n\t\t\tlabel: this.locale.toolbarLabel,\n\t\t\ttooltip: `${this.locale.toolbarTooltip} (${formatShortcut('Mod-Shift-D')})`,\n\t\t\tcommand: 'setDirectionAuto',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tisActive: (state) => this.isNonDefaultDirection(state),\n\t\t\tisEnabled: (state) => this.isDirectable(state),\n\t\t\tgetIcon: (state) => {\n\t\t\t\tconst block = getSelectedBlock(state);\n\t\t\t\tif (!block) return DIRECTION_ICONS.auto;\n\t\t\t\tconst dir: TextDirection = getBlockDir(block);\n\t\t\t\treturn DIRECTION_ICONS[dir] ?? DIRECTION_ICONS.auto;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerInlineToolbarItem(context: PluginContext): void {\n\t\tconst inlineItems = [\n\t\t\t{ label: this.locale.inlineLTR, command: 'toggleBidiLTR', icon: DIRECTION_ICONS.ltr },\n\t\t\t{ label: this.locale.inlineRTL, command: 'toggleBidiRTL', icon: DIRECTION_ICONS.rtl },\n\t\t\t{ label: this.locale.inlineAuto, command: 'toggleBidiAuto', icon: DIRECTION_ICONS.auto },\n\t\t\t{ label: this.locale.announceRemoveBidi, command: 'removeBidi' },\n\t\t];\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'inline-direction',\n\t\t\tgroup: 'format',\n\t\t\ticon: INLINE_BDI_ICON,\n\t\t\tlabel: this.locale.inlineLabel,\n\t\t\ttooltip: `${this.locale.inlineTooltip} (${formatShortcut('Mod-Shift-B')})`,\n\t\t\tcommand: 'toggleBidiIsolation',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: inlineItems },\n\t\t\tisActive: (state) => isAttributedMarkActive(state, 'bdi'),\n\t\t\tisEnabled: (state) => {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\treturn isTextSelection(sel) && !isCollapsed(sel);\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate getDirectionLabel(dir: TextDirection): string {\n\t\tif (dir === 'ltr') return this.locale.ltr;\n\t\tif (dir === 'rtl') return this.locale.rtl;\n\t\treturn this.locale.auto;\n\t}\n\n\t// --- Direction Logic ---\n\n\tprivate setDirection(context: PluginContext, direction: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst blockIds: BlockId[] = this.getSelectedBlockIds(state);\n\t\tif (blockIds.length === 0) return false;\n\n\t\tconst tb = state.transaction('command');\n\t\tlet changed = false;\n\n\t\tfor (const id of blockIds) {\n\t\t\tconst block = state.getBlock(id);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) continue;\n\n\t\t\tconst path = state.getNodePath(id);\n\t\t\tif (!path) continue;\n\n\t\t\ttb.setNodeAttr(path, { ...block.attrs, dir: direction });\n\t\t\tchanged = true;\n\t\t}\n\n\t\tif (!changed) return false;\n\n\t\tconst tr = tb.setSelection(state.selection).build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns all block IDs covered by the current selection.\n\t * Only handles TextSelection and NodeSelection — other selection types\n\t * (e.g. GapCursorSelection) return an empty array intentionally, since\n\t * gap cursors sit between blocks and have no associated block content.\n\t */\n\tprivate getSelectedBlockIds(state: EditorState): BlockId[] {\n\t\tconst sel = state.selection;\n\n\t\tif (isNodeSelection(sel)) {\n\t\t\treturn [sel.nodeId];\n\t\t}\n\n\t\tif (!isTextSelection(sel)) return [];\n\n\t\tconst anchorId: BlockId = sel.anchor.blockId;\n\t\tconst headId: BlockId = sel.head.blockId;\n\n\t\tif (anchorId === headId) return [anchorId];\n\n\t\tconst order: readonly BlockId[] = state.getBlockOrder();\n\t\tconst anchorIdx: number = order.indexOf(anchorId);\n\t\tconst headIdx: number = order.indexOf(headId);\n\t\tif (anchorIdx === -1 || headIdx === -1) return [];\n\n\t\tconst from: number = Math.min(anchorIdx, headIdx);\n\t\tconst to: number = Math.max(anchorIdx, headIdx);\n\t\treturn order.slice(from, to + 1) as BlockId[];\n\t}\n\n\tprivate isNonDefaultDirection(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\t\tconst dir = block.attrs?.dir;\n\t\treturn dir != null && dir !== 'auto';\n\t}\n\n\tprivate isDirectable(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\treturn block != null && this.directableTypes.has(block.type);\n\t}\n\n\t// --- Inline bdi mark operations ---\n\n\t/**\n\t * Cycles inline bidi isolation: no-bdi → bdi (opposite of block dir) →\n\t * remove. Applies the opposite direction of the current block for the\n\t * common case (e.g., LTR word in an RTL block gets bdi-ltr).\n\t */\n\tprivate toggleBidiIsolation(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tif (isAttributedMarkActive(state, 'bdi')) {\n\t\t\tconst result: boolean = this.removeBdi(context);\n\t\t\tif (result) context.announce(this.locale.announceRemoveBidi);\n\t\t\treturn result;\n\t\t}\n\t\tconst block = getSelectedBlock(state);\n\t\tconst blockDir: TextDirection = block ? getBlockDir(block) : 'auto';\n\t\tconst bdiDir: TextDirection = blockDir === 'rtl' ? 'ltr' : 'rtl';\n\t\tconst result: boolean = this.applyBdi(context, bdiDir);\n\t\tif (result) {\n\t\t\tconst announcement: string = bdiDir === 'ltr' ? this.locale.inlineLTR : this.locale.inlineRTL;\n\t\t\tcontext.announce(announcement);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate applyBdi(context: PluginContext, dir: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst mark = { type: markType('bdi'), attrs: { dir } };\n\t\tconst tr = applyAttributedMark(state, mark);\n\t\tif (!tr) return false;\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate removeBdi(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst tr = removeAttributedMark(state, markType('bdi'));\n\t\tif (!tr) return false;\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n}\n\n// --- Helpers ---\n\nfunction applyDirection(el: HTMLElement, node: BlockNode): void {\n\tconst dir = node.attrs?.dir;\n\tif (dir === 'ltr' || dir === 'rtl' || dir === 'auto') {\n\t\tel.setAttribute('dir', dir);\n\t}\n}\n"],"names":["buildDirChangeStep","state","block","dir","path","getNodePath","id","type","attrs","previousAttrs","handleInsertText","step","directableTypes","extraSteps","getBlock","blockId","has","existingText","getBlockText","getBlockDir","length","textOffset","blockOffsetToTextOffset","offset","textAfter","slice","text","detected","detectTextDirection","dirStep","push","handleDeleteText","currentDir","fromText","from","toText","to","DEFAULT_CONFIG","DIRECTION_ICONS","ltr","rtl","auto","ALL_DIRECTIONS","TextDirectionPlugin","name","priority","config","locale","shiftDirHandler","constructor","this","init","context","service","getService","LocaleServiceKey","lang","getLocale","TEXT_DIRECTION_LOCALE_EN","loadTextDirectionLocale","Set","patchNodeSpecs","registerBdiMark","registerCommands","registerKeymaps","registerToolbarItem","registerInlineToolbarItem","registerMiddleware","tr","_state","next","patched","patchedSteps","steps","map","nodeType","prevDir","registerPreserveDirMiddleware","registerAutoDetectMiddleware","node","String","nodeText","siblingDir","findSiblingDirection","parentPath","index","registerInheritDirMiddleware","isMac","ShiftDirectionHandler","attach","getContainer","destroy","detach","registry","getSchemaRegistry","spec","getNodeSpec","originalToDOM","toDOM","removeNodeSpec","registerNodeSpec","default","el","call","applyDirection","registerMarkSpec","rank","mark","document","createElement","setAttribute","toHTMLString","content","escapeHTML","parseHTML","tag","getAttrs","getAttribute","sanitize","tags","registerCommand","result","setDirection","announce","announceLTR","announceRTL","announceAuto","applyBdi","inlineLTR","inlineRTL","inlineAuto","removeBdi","announceRemoveBidi","toggleBidiIsolation","getState","getSelectedBlock","current","registerKeymap","executeCommand","commandNames","dropdownItems","label","getDirectionLabel","command","icon","group","toolbarLabel","tooltip","toolbarTooltip","formatShortcut","popupType","popupConfig","items","isActive","isNonDefaultDirection","isEnabled","isDirectable","getIcon","inlineItems","inlineLabel","inlineTooltip","isAttributedMarkActive","sel","selection","isTextSelection","isCollapsed","direction","blockIds","getSelectedBlockIds","tb","transaction","changed","setNodeAttr","setSelection","build","dispatch","isNodeSelection","nodeId","anchorId","anchor","headId","head","order","getBlockOrder","anchorIdx","indexOf","headIdx","Math","min","max","bdiDir","announcement","markType","applyAttributedMark","removeAttributedMark"],"mappings":"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"}
1
+ {"version":3,"file":"text-direction-advanced.mjs","sources":["../../src/plugins/text-direction/TextDirectionMiddleware.ts","../../src/plugins/text-direction/TextDirectionPlugin.ts"],"sourcesContent":["/**\n * Middleware registrations for the TextDirectionPlugin.\n * Separated from the main plugin file for maintainability.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { blockOffsetToTextOffset, getBlockText } from '../../model/Document.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Step } from '../../state/Transaction.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { detectTextDirection, findSiblingDirection, getBlockDir } from './DirectionDetection.js';\nimport type { TextDirection } from './TextDirectionPlugin.js';\n\n/**\n * Preserves the `dir` attribute when other plugins change the block\n * type (e.g. paragraph -> heading) via `setBlockType`, which replaces attrs.\n */\nexport function registerPreserveDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, _state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'setBlockType') return step;\n\t\t\t\tif (!directableTypes.has(step.nodeType)) return step;\n\n\t\t\t\tconst prevDir = step.previousAttrs?.dir;\n\t\t\t\tif (!prevDir || prevDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tattrs: { ...step.attrs, dir: prevDir },\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:preserve-dir' },\n\t);\n}\n\n/**\n * Auto-detects text direction on `insertText` and `deleteText` steps\n * for blocks with `dir=\"auto\"` (or blocks whose content changes direction).\n * Uses the first strong directional character to determine LTR vs RTL.\n */\nexport function registerAutoDetectMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tconst extraSteps: Step[] = [];\n\n\t\t\tfor (const step of tr.steps) {\n\t\t\t\tif (step.type === 'insertText') {\n\t\t\t\t\thandleInsertText(step, state, directableTypes, extraSteps);\n\t\t\t\t} else if (step.type === 'deleteText') {\n\t\t\t\t\thandleDeleteText(step, state, directableTypes, extraSteps);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (extraSteps.length > 0) {\n\t\t\t\tnext({ ...tr, steps: [...tr.steps, ...extraSteps] });\n\t\t\t} else {\n\t\t\t\tnext(tr);\n\t\t\t}\n\t\t},\n\t\t{ name: 'text-direction:auto-detect' },\n\t);\n}\n\n/** Builds a `setNodeAttr` step to change the `dir` attribute of a block. */\nfunction buildDirChangeStep(\n\tstate: EditorState,\n\tblock: BlockNode,\n\tdir: TextDirection | 'auto',\n): Step | undefined {\n\tconst path = state.getNodePath(block.id);\n\tif (!path) return undefined;\n\n\treturn {\n\t\ttype: 'setNodeAttr',\n\t\tpath,\n\t\tattrs: { ...block.attrs, dir },\n\t\tpreviousAttrs: block.attrs as Record<string, string | number | boolean>,\n\t};\n}\n\n/** Handles direction detection after text insertion. */\nfunction handleInsertText(\n\tstep: Extract<Step, { type: 'insertText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tconst existingText: string = getBlockText(block);\n\tif (getBlockDir(block) !== 'auto' && existingText.length > 0) return;\n\n\tconst textOffset: number = blockOffsetToTextOffset(block, step.offset);\n\tconst textAfter: string =\n\t\texistingText.slice(0, textOffset) + step.text + existingText.slice(textOffset);\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\n/** Handles direction re-detection after text deletion. */\nfunction handleDeleteText(\n\tstep: Extract<Step, { type: 'deleteText' }>,\n\tstate: EditorState,\n\tdirectableTypes: ReadonlySet<string>,\n\textraSteps: Step[],\n): void {\n\tconst block = state.getBlock(step.blockId);\n\tif (!block || !directableTypes.has(block.type)) return;\n\n\tconst currentDir: TextDirection = getBlockDir(block);\n\tif (currentDir === 'auto') return;\n\n\tconst existingText: string = getBlockText(block);\n\tconst fromText: number = blockOffsetToTextOffset(block, step.from);\n\tconst toText: number = blockOffsetToTextOffset(block, step.to);\n\tconst textAfter: string = existingText.slice(0, fromText) + existingText.slice(toText);\n\n\tif (textAfter.length === 0) {\n\t\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, 'auto');\n\t\tif (dirStep) extraSteps.push(dirStep);\n\t\treturn;\n\t}\n\n\tconst detected: TextDirection | null = detectTextDirection(textAfter);\n\tif (!detected || detected === currentDir) return;\n\n\tconst dirStep: Step | undefined = buildDirChangeStep(state, block, detected);\n\tif (dirStep) extraSteps.push(dirStep);\n}\n\n/**\n * Inherits `dir` from the nearest sibling when inserting a new block\n * (e.g. via GapCursor or NodeSelection).\n */\nexport function registerInheritDirMiddleware(\n\tcontext: PluginContext,\n\tdirectableTypes: ReadonlySet<string>,\n): void {\n\tcontext.registerMiddleware(\n\t\t(tr, state, next) => {\n\t\t\tlet patched = false;\n\n\t\t\tconst patchedSteps = tr.steps.map((step) => {\n\t\t\t\tif (step.type !== 'insertNode') return step;\n\t\t\t\tif (!directableTypes.has(step.node.type)) return step;\n\n\t\t\t\tconst newDir: string = String(step.node.attrs?.dir ?? 'auto');\n\t\t\t\tif (newDir !== 'auto') return step;\n\n\t\t\t\t// Detect direction from inserted node's text content\n\t\t\t\tconst nodeText: string = getBlockText(step.node);\n\t\t\t\tif (nodeText.length > 0) {\n\t\t\t\t\tconst detected: TextDirection | null = detectTextDirection(nodeText);\n\t\t\t\t\tif (detected) {\n\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...step,\n\t\t\t\t\t\t\tnode: {\n\t\t\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: detected },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fall back to sibling direction for empty blocks\n\t\t\t\tconst siblingDir: string | undefined = findSiblingDirection(\n\t\t\t\t\tstate,\n\t\t\t\t\tstep.parentPath,\n\t\t\t\t\tstep.index,\n\t\t\t\t);\n\t\t\t\tif (!siblingDir || siblingDir === 'auto') return step;\n\n\t\t\t\tpatched = true;\n\t\t\t\treturn {\n\t\t\t\t\t...step,\n\t\t\t\t\tnode: {\n\t\t\t\t\t\t...step.node,\n\t\t\t\t\t\tattrs: { ...step.node.attrs, dir: siblingDir },\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t});\n\n\t\t\tnext(patched ? { ...tr, steps: patchedSteps } : tr);\n\t\t},\n\t\t{ name: 'text-direction:inherit-dir' },\n\t);\n}\n","/**\n * TextDirectionPlugin: adds block-level text direction (`dir` attribute)\n * and inline bidi isolation (`<bdi>` mark) for RTL language support.\n *\n * Block-level: patches NodeSpecs for directable types to render the HTML\n * `dir` attribute. Provides `setDirectionLTR`, `setDirectionRTL`, and\n * `setDirectionAuto` commands with a toolbar dropdown.\n *\n * Inline: registers a `bdi` mark for bidi isolation of inline spans,\n * with `toggleBidiLTR`, `toggleBidiRTL`, `toggleBidiAuto`, and\n * `removeBidi` commands.\n */\n\nimport {\n\tapplyAttributedMark,\n\tisAttributedMarkActive,\n\tremoveAttributedMark,\n} from '../../commands/AttributedMarkCommands.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport { isCollapsed, isNodeSelection, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport { isMac } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { getSelectedBlock, resolveLocale } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { getBlockDir } from './DirectionDetection.js';\nimport { ShiftDirectionHandler } from './ShiftDirectionHandler.js';\nimport {\n\tTEXT_DIRECTION_LOCALE_EN,\n\ttype TextDirectionLocale,\n\tloadTextDirectionLocale,\n} from './TextDirectionLocale.js';\nimport {\n\tregisterAutoDetectMiddleware,\n\tregisterInheritDirMiddleware,\n\tregisterPreserveDirMiddleware,\n} from './TextDirectionMiddleware.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tbdi: { dir: 'ltr' | 'rtl' | 'auto' };\n\t}\n}\n\n// --- Public Types ---\n\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\n\nexport interface TextDirectionConfig {\n\t/** Block types that support direction. */\n\treadonly directableTypes: readonly string[];\n\treadonly locale?: TextDirectionLocale;\n}\n\n// --- Constants ---\n\nconst DEFAULT_CONFIG: TextDirectionConfig = {\n\tdirectableTypes: [\n\t\t'paragraph',\n\t\t'heading',\n\t\t'title',\n\t\t'subtitle',\n\t\t'table_cell',\n\t\t'blockquote',\n\t\t'list_item',\n\t],\n};\n\nexport const DIRECTION_ICONS: Readonly<Record<TextDirection, string>> = {\n\tltr: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z\"/></svg>',\n\trtl: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z\"/></svg>',\n\tauto: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z\"/></svg>',\n};\n\nconst ALL_DIRECTIONS: readonly TextDirection[] = ['ltr', 'rtl', 'auto'];\n\nconst INLINE_BDI_ICON: string =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4v7h2V4h2v7h2V4h1V2H10a3 3 0 1 0 0 6zm-3.5 9.5L3 17l3.5 3.5V18h3v-2h-3v-2.5zm14 0L17 17l3.5 3.5V18h-3v-2h3v-2.5zM11 16h2v6h-2z\"/></svg>';\n\n// --- Plugin ---\n\nexport class TextDirectionPlugin implements Plugin {\n\treadonly id = 'text-direction';\n\treadonly name = 'Text Direction';\n\treadonly priority = 91;\n\n\tprivate readonly config: TextDirectionConfig;\n\tprivate locale!: TextDirectionLocale;\n\tprivate directableTypes!: ReadonlySet<string>;\n\tprivate shiftDirHandler: ShiftDirectionHandler | null = null;\n\n\tconstructor(config?: Partial<TextDirectionConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tTEXT_DIRECTION_LOCALE_EN,\n\t\t\tloadTextDirectionLocale,\n\t\t);\n\n\t\tthis.directableTypes = new Set(this.config.directableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerBdiMark(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\t\tthis.registerInlineToolbarItem(context);\n\t\tregisterPreserveDirMiddleware(context, this.directableTypes);\n\t\tregisterAutoDetectMiddleware(context, this.directableTypes);\n\t\tregisterInheritDirMiddleware(context, this.directableTypes);\n\n\t\t// Ctrl+Shift direction shortcuts (Windows/Linux convention)\n\t\tif (!isMac()) {\n\t\t\tthis.shiftDirHandler = new ShiftDirectionHandler(context);\n\t\t\tthis.shiftDirHandler.attach(context.getContainer());\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.shiftDirHandler?.detach();\n\t\tthis.shiftDirHandler = null;\n\t}\n\n\t// --- NodeSpec Patching ---\n\n\t/**\n\t * Patches existing NodeSpecs for directable block types to support the\n\t * `dir` attribute and render it as an HTML attribute. Skips types\n\t * that already define a `dir` attribute in their spec.\n\t */\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tconst registry = context.getSchemaRegistry();\n\n\t\tfor (const type of this.config.directableTypes) {\n\t\t\tconst spec = registry.getNodeSpec(type);\n\t\t\tif (!spec) continue;\n\n\t\t\tif (spec.attrs?.dir) continue;\n\n\t\t\tconst originalToDOM = spec.toDOM;\n\n\t\t\tregistry.removeNodeSpec(type);\n\t\t\tregistry.registerNodeSpec({\n\t\t\t\t...spec,\n\t\t\t\tattrs: {\n\t\t\t\t\t...spec.attrs,\n\t\t\t\t\tdir: { default: 'auto' },\n\t\t\t\t},\n\t\t\t\ttoDOM(node) {\n\t\t\t\t\tconst el = originalToDOM.call(spec, node);\n\t\t\t\t\tapplyDirection(el, node);\n\t\t\t\t\treturn el;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\t// --- Inline <bdi> Mark ---\n\n\tprivate registerBdiMark(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'bdi',\n\t\t\trank: 10,\n\t\t\tattrs: {\n\t\t\t\tdir: { default: 'auto' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst el: HTMLElement = document.createElement('bdi');\n\t\t\t\tconst dir: string = String(mark.attrs?.dir ?? 'auto');\n\t\t\t\tel.setAttribute('dir', dir);\n\t\t\t\treturn el;\n\t\t\t},\n\t\t\ttoHTMLString: (mark, content) => {\n\t\t\t\tconst dir: string = escapeHTML(String(mark.attrs?.dir ?? 'auto'));\n\t\t\t\treturn `<bdi dir=\"${dir}\">${content}</bdi>`;\n\t\t\t},\n\t\t\tparseHTML: [\n\t\t\t\t{\n\t\t\t\t\ttag: 'bdi',\n\t\t\t\t\tgetAttrs: (el) => {\n\t\t\t\t\t\tconst dir: string | null = el.getAttribute('dir');\n\t\t\t\t\t\tif (dir === 'ltr' || dir === 'rtl') return { dir };\n\t\t\t\t\t\treturn { dir: 'auto' };\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t\tsanitize: { tags: ['bdi'], attrs: ['dir'] },\n\t\t});\n\t}\n\n\t// --- Commands ---\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('setDirectionLTR', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.announceLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionRTL', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.announceRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionAuto', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.announceAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiLTR', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.inlineLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiRTL', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.inlineRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiAuto', () => {\n\t\t\tconst result: boolean = this.applyBdi(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.inlineAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('removeBidi', () => {\n\t\t\tconst result: boolean = this.removeBdi(context);\n\t\t\tif (result) context.announce(this.locale.announceRemoveBidi);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleBidiIsolation', () => {\n\t\t\treturn this.toggleBidiIsolation(context);\n\t\t});\n\n\t\tcontext.registerCommand('toggleDirection', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst block = getSelectedBlock(state);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\n\t\t\tconst current: TextDirection = getBlockDir(block);\n\t\t\tconst next: TextDirection = current === 'auto' ? 'rtl' : current === 'rtl' ? 'ltr' : 'auto';\n\t\t\treturn this.setDirection(context, next);\n\t\t});\n\t}\n\n\t// --- Keymaps ---\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-D': () => context.executeCommand('toggleDirection'),\n\t\t\t'Mod-Shift-B': () => context.executeCommand('toggleBidiIsolation'),\n\t\t});\n\t}\n\n\t// --- Toolbar ---\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst commandNames: Readonly<Record<TextDirection, string>> = {\n\t\t\tltr: 'setDirectionLTR',\n\t\t\trtl: 'setDirectionRTL',\n\t\t\tauto: 'setDirectionAuto',\n\t\t};\n\n\t\tconst dropdownItems = ALL_DIRECTIONS.map((dir) => ({\n\t\t\tlabel: this.getDirectionLabel(dir),\n\t\t\tcommand: commandNames[dir],\n\t\t\ticon: DIRECTION_ICONS[dir],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-direction',\n\t\t\tgroup: 'block',\n\t\t\ticon: DIRECTION_ICONS.auto,\n\t\t\tlabel: this.locale.toolbarLabel,\n\t\t\ttooltip: `${this.locale.toolbarTooltip} (${formatShortcut('Mod-Shift-D')})`,\n\t\t\tcommand: 'setDirectionAuto',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tisActive: (state) => this.isNonDefaultDirection(state),\n\t\t\tisEnabled: (state) => this.isDirectable(state),\n\t\t\tgetIcon: (state) => {\n\t\t\t\tconst block = getSelectedBlock(state);\n\t\t\t\tif (!block) return DIRECTION_ICONS.auto;\n\t\t\t\tconst dir: TextDirection = getBlockDir(block);\n\t\t\t\treturn DIRECTION_ICONS[dir] ?? DIRECTION_ICONS.auto;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerInlineToolbarItem(context: PluginContext): void {\n\t\tconst inlineItems = [\n\t\t\t{ label: this.locale.inlineLTR, command: 'toggleBidiLTR', icon: DIRECTION_ICONS.ltr },\n\t\t\t{ label: this.locale.inlineRTL, command: 'toggleBidiRTL', icon: DIRECTION_ICONS.rtl },\n\t\t\t{ label: this.locale.inlineAuto, command: 'toggleBidiAuto', icon: DIRECTION_ICONS.auto },\n\t\t\t{ label: this.locale.announceRemoveBidi, command: 'removeBidi' },\n\t\t];\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'inline-direction',\n\t\t\tgroup: 'format',\n\t\t\ticon: INLINE_BDI_ICON,\n\t\t\tlabel: this.locale.inlineLabel,\n\t\t\ttooltip: `${this.locale.inlineTooltip} (${formatShortcut('Mod-Shift-B')})`,\n\t\t\tcommand: 'toggleBidiIsolation',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: inlineItems },\n\t\t\tisActive: (state) => isAttributedMarkActive(state, 'bdi'),\n\t\t\tisEnabled: (state) => {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\treturn isTextSelection(sel) && !isCollapsed(sel);\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate getDirectionLabel(dir: TextDirection): string {\n\t\tif (dir === 'ltr') return this.locale.ltr;\n\t\tif (dir === 'rtl') return this.locale.rtl;\n\t\treturn this.locale.auto;\n\t}\n\n\t// --- Direction Logic ---\n\n\tprivate setDirection(context: PluginContext, direction: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst blockIds: BlockId[] = this.getSelectedBlockIds(state);\n\t\tif (blockIds.length === 0) return false;\n\n\t\tconst tb = state.transaction('command');\n\t\tlet changed = false;\n\n\t\tfor (const id of blockIds) {\n\t\t\tconst block = state.getBlock(id);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) continue;\n\n\t\t\tconst path = state.getNodePath(id);\n\t\t\tif (!path) continue;\n\n\t\t\ttb.setNodeAttr(path, { ...block.attrs, dir: direction });\n\t\t\tchanged = true;\n\t\t}\n\n\t\tif (!changed) return false;\n\n\t\tconst tr = tb.setSelection(state.selection).build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Returns all block IDs covered by the current selection.\n\t * Only handles TextSelection and NodeSelection — other selection types\n\t * (e.g. GapCursorSelection) return an empty array intentionally, since\n\t * gap cursors sit between blocks and have no associated block content.\n\t */\n\tprivate getSelectedBlockIds(state: EditorState): BlockId[] {\n\t\tconst sel = state.selection;\n\n\t\tif (isNodeSelection(sel)) {\n\t\t\treturn [sel.nodeId];\n\t\t}\n\n\t\tif (!isTextSelection(sel)) return [];\n\n\t\tconst anchorId: BlockId = sel.anchor.blockId;\n\t\tconst headId: BlockId = sel.head.blockId;\n\n\t\tif (anchorId === headId) return [anchorId];\n\n\t\tconst order: readonly BlockId[] = state.getBlockOrder();\n\t\tconst anchorIdx: number = order.indexOf(anchorId);\n\t\tconst headIdx: number = order.indexOf(headId);\n\t\tif (anchorIdx === -1 || headIdx === -1) return [];\n\n\t\tconst from: number = Math.min(anchorIdx, headIdx);\n\t\tconst to: number = Math.max(anchorIdx, headIdx);\n\t\treturn order.slice(from, to + 1) as BlockId[];\n\t}\n\n\tprivate isNonDefaultDirection(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\t\tconst dir = block.attrs?.dir;\n\t\treturn dir != null && dir !== 'auto';\n\t}\n\n\tprivate isDirectable(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\treturn block != null && this.directableTypes.has(block.type);\n\t}\n\n\t// --- Inline bdi mark operations ---\n\n\t/**\n\t * Cycles inline bidi isolation: no-bdi → bdi (opposite of block dir) →\n\t * remove. Applies the opposite direction of the current block for the\n\t * common case (e.g., LTR word in an RTL block gets bdi-ltr).\n\t */\n\tprivate toggleBidiIsolation(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tif (isAttributedMarkActive(state, 'bdi')) {\n\t\t\tconst result: boolean = this.removeBdi(context);\n\t\t\tif (result) context.announce(this.locale.announceRemoveBidi);\n\t\t\treturn result;\n\t\t}\n\t\tconst block = getSelectedBlock(state);\n\t\tconst blockDir: TextDirection = block ? getBlockDir(block) : 'auto';\n\t\tconst bdiDir: TextDirection = blockDir === 'rtl' ? 'ltr' : 'rtl';\n\t\tconst result: boolean = this.applyBdi(context, bdiDir);\n\t\tif (result) {\n\t\t\tconst announcement: string = bdiDir === 'ltr' ? this.locale.inlineLTR : this.locale.inlineRTL;\n\t\t\tcontext.announce(announcement);\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate applyBdi(context: PluginContext, dir: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst mark = { type: markType('bdi'), attrs: { dir } };\n\t\tconst tr = applyAttributedMark(state, mark);\n\t\tif (!tr) return false;\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate removeBdi(context: PluginContext): boolean {\n\t\tconst state = context.getState();\n\t\tconst tr = removeAttributedMark(state, markType('bdi'));\n\t\tif (!tr) return false;\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n}\n\n// --- Helpers ---\n\nfunction applyDirection(el: HTMLElement, node: BlockNode): void {\n\tconst dir = node.attrs?.dir;\n\tif (dir === 'ltr' || dir === 'rtl' || dir === 'auto') {\n\t\tel.setAttribute('dir', dir);\n\t}\n}\n"],"names":["buildDirChangeStep","state","block","dir","path","getNodePath","id","type","attrs","previousAttrs","handleInsertText","step","directableTypes","extraSteps","getBlock","blockId","has","existingText","getBlockText","getBlockDir","length","textOffset","blockOffsetToTextOffset","offset","textAfter","slice","text","detected","detectTextDirection","dirStep","push","handleDeleteText","currentDir","fromText","from","toText","to","DEFAULT_CONFIG","DIRECTION_ICONS","ltr","rtl","auto","ALL_DIRECTIONS","TextDirectionPlugin","name","priority","config","locale","shiftDirHandler","constructor","this","init","context","resolveLocale","TEXT_DIRECTION_LOCALE_EN","loadTextDirectionLocale","Set","patchNodeSpecs","registerBdiMark","registerCommands","registerKeymaps","registerToolbarItem","registerInlineToolbarItem","registerMiddleware","tr","_state","next","patched","patchedSteps","steps","map","nodeType","prevDir","registerPreserveDirMiddleware","registerAutoDetectMiddleware","node","String","nodeText","siblingDir","findSiblingDirection","parentPath","index","registerInheritDirMiddleware","isMac","ShiftDirectionHandler","attach","getContainer","destroy","detach","registry","getSchemaRegistry","spec","getNodeSpec","originalToDOM","toDOM","removeNodeSpec","registerNodeSpec","default","el","call","applyDirection","registerMarkSpec","rank","mark","document","createElement","setAttribute","toHTMLString","content","escapeHTML","parseHTML","tag","getAttrs","getAttribute","sanitize","tags","registerCommand","result","setDirection","announce","announceLTR","announceRTL","announceAuto","applyBdi","inlineLTR","inlineRTL","inlineAuto","removeBdi","announceRemoveBidi","toggleBidiIsolation","getState","getSelectedBlock","current","registerKeymap","executeCommand","commandNames","dropdownItems","label","getDirectionLabel","command","icon","group","toolbarLabel","tooltip","toolbarTooltip","formatShortcut","popupType","popupConfig","items","isActive","isNonDefaultDirection","isEnabled","isDirectable","getIcon","inlineItems","inlineLabel","inlineTooltip","isAttributedMarkActive","sel","selection","isTextSelection","isCollapsed","direction","blockIds","getSelectedBlockIds","tb","transaction","changed","setNodeAttr","setSelection","build","dispatch","isNodeSelection","nodeId","anchorId","anchor","headId","head","order","getBlockOrder","anchorIdx","indexOf","headIdx","Math","min","max","bdiDir","announcement","markType","applyAttributedMark","removeAttributedMark"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{a as t}from"../chunks/LocaleService-B6Z-wyAF.mjs";import{h as e,j as i}from"../chunks/Selection-6-W6Flxc.mjs";import{a as o}from"../chunks/Platform-CU6itXZo.mjs";import{g as r}from"../chunks/PluginHelpers-DjZt0pQi.mjs";import{f as s}from"../chunks/ShortcutFormatting-BLKS0Gys.mjs";import{T as n,l as c,S as a,g as l}from"../chunks/TextDirectionLocale-DB_aqrMg.mjs";import{d as h,f as u}from"../chunks/TextDirectionLocale-DB_aqrMg.mjs";const d={directableTypes:["paragraph","heading","title","subtitle","table_cell","blockquote","list_item"]},m={ltr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z"/></svg>',rtl:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z"/></svg>',auto:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z"/></svg>'},g=["ltr","rtl","auto"];class p{id="text-direction";name="Text Direction";priority=91;config;locale;directableTypes;shiftDirHandler=null;constructor(t){this.config={...d,...t}}async init(e){if(this.config.locale)this.locale=this.config.locale;else{const i=e.getService(t),o=i?.getLocale()??"en";this.locale="en"===o?n:await c(o)}this.directableTypes=new Set(this.config.directableTypes),this.patchNodeSpecs(e),this.registerCommands(e),this.registerKeymaps(e),this.registerToolbarItem(e),o()||(this.shiftDirHandler=new a(e),this.shiftDirHandler.attach(e.getContainer()))}destroy(){this.shiftDirHandler?.detach(),this.shiftDirHandler=null}patchNodeSpecs(t){const e=t.getSchemaRegistry();for(const i of this.config.directableTypes){const t=e.getNodeSpec(i);if(!t)continue;if(t.attrs?.dir)continue;const o=t.toDOM;e.removeNodeSpec(i),e.registerNodeSpec({...t,attrs:{...t.attrs,dir:{default:"auto"}},toDOM(e){const i=o.call(t,e);return f(i,e),i}})}}registerCommands(t){t.registerCommand("setDirectionLTR",()=>{const e=this.setDirection(t,"ltr");return e&&t.announce(this.locale.announceLTR),e}),t.registerCommand("setDirectionRTL",()=>{const e=this.setDirection(t,"rtl");return e&&t.announce(this.locale.announceRTL),e}),t.registerCommand("setDirectionAuto",()=>{const e=this.setDirection(t,"auto");return e&&t.announce(this.locale.announceAuto),e}),t.registerCommand("toggleDirection",()=>{const e=t.getState(),i=r(e);if(!i||!this.directableTypes.has(i.type))return!1;const o=l(i),s="auto"===o?"rtl":"rtl"===o?"ltr":"auto";return this.setDirection(t,s)})}registerKeymaps(t){t.registerKeymap({"Mod-Shift-D":()=>t.executeCommand("toggleDirection")})}registerToolbarItem(t){const e={ltr:"setDirectionLTR",rtl:"setDirectionRTL",auto:"setDirectionAuto"},i=g.map(t=>({label:this.getDirectionLabel(t),command:e[t],icon:m[t]}));t.registerToolbarItem({id:"text-direction",group:"block",icon:m.auto,label:this.locale.toolbarLabel,tooltip:`${this.locale.toolbarTooltip} (${s("Mod-Shift-D")})`,command:"setDirectionAuto",popupType:"dropdown",popupConfig:{items:i},isActive:t=>this.isNonDefaultDirection(t),isEnabled:t=>this.isDirectable(t),getIcon:t=>{const e=r(t);if(!e)return m.auto;const i=l(e);return m[i]??m.auto}})}getDirectionLabel(t){return"ltr"===t?this.locale.ltr:"rtl"===t?this.locale.rtl:this.locale.auto}setDirection(t,e){const i=t.getState(),o=this.getSelectedBlockIds(i);if(0===o.length)return!1;const r=i.transaction("command");let s=!1;for(const c of o){const t=i.getBlock(c);if(!t||!this.directableTypes.has(t.type))continue;const o=i.getNodePath(c);o&&(r.setNodeAttr(o,{...t.attrs,dir:e}),s=!0)}if(!s)return!1;const n=r.setSelection(i.selection).build();return t.dispatch(n),!0}getSelectedBlockIds(t){const o=t.selection;if(e(o))return[o.nodeId];if(!i(o))return[];const r=o.anchor.blockId,s=o.head.blockId;if(r===s)return[r];const n=t.getBlockOrder(),c=n.indexOf(r),a=n.indexOf(s);if(-1===c||-1===a)return[];const l=Math.min(c,a),h=Math.max(c,a);return n.slice(l,h+1)}isNonDefaultDirection(t){const e=r(t);if(!e||!this.directableTypes.has(e.type))return!1;const i=e.attrs?.dir;return null!=i&&"auto"!==i}isDirectable(t){const e=r(t);return null!=e&&this.directableTypes.has(e.type)}}function f(t,e){const i=e.attrs?.dir;"ltr"!==i&&"rtl"!==i&&"auto"!==i||t.setAttribute("dir",i)}export{m as DIRECTION_ICONS,n as TEXT_DIRECTION_LOCALE_EN,p as TextDirectionPlugin,h as detectTextDirection,u as findSiblingDirection,l as getBlockDir,c as loadTextDirectionLocale};
1
+ import{h as t,j as e}from"../chunks/Selection-DhbizDM4.mjs";import{a as i}from"../chunks/Platform-CU6itXZo.mjs";import{r as o,g as r}from"../chunks/PluginHelpers-CdPR0MuT.mjs";import{f as s}from"../chunks/ShortcutFormatting-BLKS0Gys.mjs";import{S as n,g as c,l as a,T as l}from"../chunks/TextDirectionLocale-CKz0ZrH_.mjs";import{d as h,f as u}from"../chunks/TextDirectionLocale-CKz0ZrH_.mjs";const d={directableTypes:["paragraph","heading","title","subtitle","table_cell","blockquote","list_item"]},m={ltr:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z"/></svg>',rtl:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z"/></svg>',auto:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z"/></svg>'},g=["ltr","rtl","auto"];class p{id="text-direction";name="Text Direction";priority=91;config;locale;directableTypes;shiftDirHandler=null;constructor(t){this.config={...d,...t}}async init(t){this.locale=await o(t,this.config.locale,l,a),this.directableTypes=new Set(this.config.directableTypes),this.patchNodeSpecs(t),this.registerCommands(t),this.registerKeymaps(t),this.registerToolbarItem(t),i()||(this.shiftDirHandler=new n(t),this.shiftDirHandler.attach(t.getContainer()))}destroy(){this.shiftDirHandler?.detach(),this.shiftDirHandler=null}patchNodeSpecs(t){const e=t.getSchemaRegistry();for(const i of this.config.directableTypes){const t=e.getNodeSpec(i);if(!t)continue;if(t.attrs?.dir)continue;const o=t.toDOM;e.removeNodeSpec(i),e.registerNodeSpec({...t,attrs:{...t.attrs,dir:{default:"auto"}},toDOM(e){const i=o.call(t,e);return f(i,e),i}})}}registerCommands(t){t.registerCommand("setDirectionLTR",()=>{const e=this.setDirection(t,"ltr");return e&&t.announce(this.locale.announceLTR),e}),t.registerCommand("setDirectionRTL",()=>{const e=this.setDirection(t,"rtl");return e&&t.announce(this.locale.announceRTL),e}),t.registerCommand("setDirectionAuto",()=>{const e=this.setDirection(t,"auto");return e&&t.announce(this.locale.announceAuto),e}),t.registerCommand("toggleDirection",()=>{const e=t.getState(),i=r(e);if(!i||!this.directableTypes.has(i.type))return!1;const o=c(i),s="auto"===o?"rtl":"rtl"===o?"ltr":"auto";return this.setDirection(t,s)})}registerKeymaps(t){t.registerKeymap({"Mod-Shift-D":()=>t.executeCommand("toggleDirection")})}registerToolbarItem(t){const e={ltr:"setDirectionLTR",rtl:"setDirectionRTL",auto:"setDirectionAuto"},i=g.map(t=>({label:this.getDirectionLabel(t),command:e[t],icon:m[t]}));t.registerToolbarItem({id:"text-direction",group:"block",icon:m.auto,label:this.locale.toolbarLabel,tooltip:`${this.locale.toolbarTooltip} (${s("Mod-Shift-D")})`,command:"setDirectionAuto",popupType:"dropdown",popupConfig:{items:i},isActive:t=>this.isNonDefaultDirection(t),isEnabled:t=>this.isDirectable(t),getIcon:t=>{const e=r(t);if(!e)return m.auto;const i=c(e);return m[i]??m.auto}})}getDirectionLabel(t){return"ltr"===t?this.locale.ltr:"rtl"===t?this.locale.rtl:this.locale.auto}setDirection(t,e){const i=t.getState(),o=this.getSelectedBlockIds(i);if(0===o.length)return!1;const r=i.transaction("command");let s=!1;for(const c of o){const t=i.getBlock(c);if(!t||!this.directableTypes.has(t.type))continue;const o=i.getNodePath(c);o&&(r.setNodeAttr(o,{...t.attrs,dir:e}),s=!0)}if(!s)return!1;const n=r.setSelection(i.selection).build();return t.dispatch(n),!0}getSelectedBlockIds(i){const o=i.selection;if(t(o))return[o.nodeId];if(!e(o))return[];const r=o.anchor.blockId,s=o.head.blockId;if(r===s)return[r];const n=i.getBlockOrder(),c=n.indexOf(r),a=n.indexOf(s);if(-1===c||-1===a)return[];const l=Math.min(c,a),h=Math.max(c,a);return n.slice(l,h+1)}isNonDefaultDirection(t){const e=r(t);if(!e||!this.directableTypes.has(e.type))return!1;const i=e.attrs?.dir;return null!=i&&"auto"!==i}isDirectable(t){const e=r(t);return null!=e&&this.directableTypes.has(e.type)}}function f(t,e){const i=e.attrs?.dir;"ltr"!==i&&"rtl"!==i&&"auto"!==i||t.setAttribute("dir",i)}export{m as DIRECTION_ICONS,l as TEXT_DIRECTION_LOCALE_EN,p as TextDirectionPlugin,h as detectTextDirection,u as findSiblingDirection,c as getBlockDir,a as loadTextDirectionLocale};
2
2
  //# sourceMappingURL=text-direction.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"text-direction.mjs","sources":["../../src/plugins/text-direction/TextDirectionCorePlugin.ts"],"sourcesContent":["import { LocaleServiceKey } from '../../i18n/LocaleService.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport { isNodeSelection, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { isMac } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { getSelectedBlock } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { getBlockDir } from './DirectionDetection.js';\nimport { ShiftDirectionHandler } from './ShiftDirectionHandler.js';\nimport {\n\tTEXT_DIRECTION_LOCALE_EN,\n\ttype TextDirectionLocale,\n\tloadTextDirectionLocale,\n} from './TextDirectionLocale.js';\n\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\n\nexport interface TextDirectionConfig {\n\t/** Block types that support direction. */\n\treadonly directableTypes: readonly string[];\n\treadonly locale?: TextDirectionLocale;\n}\n\nconst DEFAULT_CONFIG: TextDirectionConfig = {\n\tdirectableTypes: [\n\t\t'paragraph',\n\t\t'heading',\n\t\t'title',\n\t\t'subtitle',\n\t\t'table_cell',\n\t\t'blockquote',\n\t\t'list_item',\n\t],\n};\n\nexport const DIRECTION_ICONS: Readonly<Record<TextDirection, string>> = {\n\tltr: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z\"/></svg>',\n\trtl: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z\"/></svg>',\n\tauto: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z\"/></svg>',\n};\n\nconst ALL_DIRECTIONS: readonly TextDirection[] = ['ltr', 'rtl', 'auto'];\n\n/**\n * Lean text-direction plugin.\n * Includes block-level direction controls and toolbar integration only.\n */\nexport class TextDirectionCorePlugin implements Plugin {\n\treadonly id = 'text-direction';\n\treadonly name = 'Text Direction';\n\treadonly priority = 91;\n\n\tprivate readonly config: TextDirectionConfig;\n\tprivate locale!: TextDirectionLocale;\n\tprivate directableTypes!: ReadonlySet<string>;\n\tprivate shiftDirHandler: ShiftDirectionHandler | null = null;\n\n\tconstructor(config?: Partial<TextDirectionConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tif (this.config.locale) {\n\t\t\tthis.locale = this.config.locale;\n\t\t} else {\n\t\t\tconst service = context.getService(LocaleServiceKey);\n\t\t\tconst lang: string = service?.getLocale() ?? 'en';\n\t\t\tthis.locale = lang === 'en' ? TEXT_DIRECTION_LOCALE_EN : await loadTextDirectionLocale(lang);\n\t\t}\n\n\t\tthis.directableTypes = new Set(this.config.directableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\n\t\t// Ctrl+Shift direction shortcuts (Windows/Linux convention)\n\t\tif (!isMac()) {\n\t\t\tthis.shiftDirHandler = new ShiftDirectionHandler(context);\n\t\t\tthis.shiftDirHandler.attach(context.getContainer());\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.shiftDirHandler?.detach();\n\t\tthis.shiftDirHandler = null;\n\t}\n\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tconst registry = context.getSchemaRegistry();\n\n\t\tfor (const type of this.config.directableTypes) {\n\t\t\tconst spec = registry.getNodeSpec(type);\n\t\t\tif (!spec) continue;\n\n\t\t\tif (spec.attrs?.dir) continue;\n\n\t\t\tconst originalToDOM = spec.toDOM;\n\n\t\t\tregistry.removeNodeSpec(type);\n\t\t\tregistry.registerNodeSpec({\n\t\t\t\t...spec,\n\t\t\t\tattrs: {\n\t\t\t\t\t...spec.attrs,\n\t\t\t\t\tdir: { default: 'auto' },\n\t\t\t\t},\n\t\t\t\ttoDOM(node) {\n\t\t\t\t\tconst el = originalToDOM.call(spec, node);\n\t\t\t\t\tapplyDirection(el, node);\n\t\t\t\t\treturn el;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('setDirectionLTR', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.announceLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionRTL', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.announceRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionAuto', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.announceAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleDirection', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst block = getSelectedBlock(state);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\n\t\t\tconst current: TextDirection = getBlockDir(block);\n\t\t\tconst next: TextDirection = current === 'auto' ? 'rtl' : current === 'rtl' ? 'ltr' : 'auto';\n\t\t\treturn this.setDirection(context, next);\n\t\t});\n\t}\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-D': () => context.executeCommand('toggleDirection'),\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst commandNames: Readonly<Record<TextDirection, string>> = {\n\t\t\tltr: 'setDirectionLTR',\n\t\t\trtl: 'setDirectionRTL',\n\t\t\tauto: 'setDirectionAuto',\n\t\t};\n\n\t\tconst dropdownItems = ALL_DIRECTIONS.map((dir) => ({\n\t\t\tlabel: this.getDirectionLabel(dir),\n\t\t\tcommand: commandNames[dir],\n\t\t\ticon: DIRECTION_ICONS[dir],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-direction',\n\t\t\tgroup: 'block',\n\t\t\ticon: DIRECTION_ICONS.auto,\n\t\t\tlabel: this.locale.toolbarLabel,\n\t\t\ttooltip: `${this.locale.toolbarTooltip} (${formatShortcut('Mod-Shift-D')})`,\n\t\t\tcommand: 'setDirectionAuto',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tisActive: (state) => this.isNonDefaultDirection(state),\n\t\t\tisEnabled: (state) => this.isDirectable(state),\n\t\t\tgetIcon: (state) => {\n\t\t\t\tconst block = getSelectedBlock(state);\n\t\t\t\tif (!block) return DIRECTION_ICONS.auto;\n\t\t\t\tconst dir: TextDirection = getBlockDir(block);\n\t\t\t\treturn DIRECTION_ICONS[dir] ?? DIRECTION_ICONS.auto;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate getDirectionLabel(dir: TextDirection): string {\n\t\tif (dir === 'ltr') return this.locale.ltr;\n\t\tif (dir === 'rtl') return this.locale.rtl;\n\t\treturn this.locale.auto;\n\t}\n\n\tprivate setDirection(context: PluginContext, direction: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst blockIds: BlockId[] = this.getSelectedBlockIds(state);\n\t\tif (blockIds.length === 0) return false;\n\n\t\tconst tb = state.transaction('command');\n\t\tlet changed = false;\n\n\t\tfor (const id of blockIds) {\n\t\t\tconst block = state.getBlock(id);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) continue;\n\n\t\t\tconst path = state.getNodePath(id);\n\t\t\tif (!path) continue;\n\n\t\t\ttb.setNodeAttr(path, { ...block.attrs, dir: direction });\n\t\t\tchanged = true;\n\t\t}\n\n\t\tif (!changed) return false;\n\n\t\tconst tr = tb.setSelection(state.selection).build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate getSelectedBlockIds(state: EditorState): BlockId[] {\n\t\tconst sel = state.selection;\n\n\t\tif (isNodeSelection(sel)) {\n\t\t\treturn [sel.nodeId];\n\t\t}\n\n\t\tif (!isTextSelection(sel)) return [];\n\n\t\tconst anchorId: BlockId = sel.anchor.blockId;\n\t\tconst headId: BlockId = sel.head.blockId;\n\n\t\tif (anchorId === headId) return [anchorId];\n\n\t\tconst order: readonly BlockId[] = state.getBlockOrder();\n\t\tconst anchorIdx: number = order.indexOf(anchorId);\n\t\tconst headIdx: number = order.indexOf(headId);\n\t\tif (anchorIdx === -1 || headIdx === -1) return [];\n\n\t\tconst from: number = Math.min(anchorIdx, headIdx);\n\t\tconst to: number = Math.max(anchorIdx, headIdx);\n\t\treturn order.slice(from, to + 1) as BlockId[];\n\t}\n\n\tprivate isNonDefaultDirection(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\t\tconst dir = block.attrs?.dir;\n\t\treturn dir != null && dir !== 'auto';\n\t}\n\n\tprivate isDirectable(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\treturn block != null && this.directableTypes.has(block.type);\n\t}\n}\n\nfunction applyDirection(el: HTMLElement, node: BlockNode): void {\n\tconst dir = node.attrs?.dir;\n\tif (dir === 'ltr' || dir === 'rtl' || dir === 'auto') {\n\t\tel.setAttribute('dir', dir);\n\t}\n}\n"],"names":["DEFAULT_CONFIG","directableTypes","DIRECTION_ICONS","ltr","rtl","auto","ALL_DIRECTIONS","TextDirectionCorePlugin","id","name","priority","config","locale","shiftDirHandler","constructor","this","init","context","service","getService","LocaleServiceKey","lang","getLocale","TEXT_DIRECTION_LOCALE_EN","loadTextDirectionLocale","Set","patchNodeSpecs","registerCommands","registerKeymaps","registerToolbarItem","isMac","ShiftDirectionHandler","attach","getContainer","destroy","detach","registry","getSchemaRegistry","type","spec","getNodeSpec","attrs","dir","originalToDOM","toDOM","removeNodeSpec","registerNodeSpec","default","node","el","call","applyDirection","registerCommand","result","setDirection","announce","announceLTR","announceRTL","announceAuto","state","getState","block","getSelectedBlock","has","current","getBlockDir","next","registerKeymap","executeCommand","commandNames","dropdownItems","map","label","getDirectionLabel","command","icon","group","toolbarLabel","tooltip","toolbarTooltip","formatShortcut","popupType","popupConfig","items","isActive","isNonDefaultDirection","isEnabled","isDirectable","getIcon","direction","blockIds","getSelectedBlockIds","length","tb","transaction","changed","getBlock","path","getNodePath","setNodeAttr","tr","setSelection","selection","build","dispatch","sel","isNodeSelection","nodeId","isTextSelection","anchorId","anchor","blockId","headId","head","order","getBlockOrder","anchorIdx","indexOf","headIdx","from","Math","min","to","max","slice","setAttribute"],"mappings":"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"}
1
+ {"version":3,"file":"text-direction.mjs","sources":["../../src/plugins/text-direction/TextDirectionCorePlugin.ts"],"sourcesContent":["import type { BlockNode } from '../../model/Document.js';\nimport { isNodeSelection, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { isMac } from '../../platform/Platform.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { getSelectedBlock, resolveLocale } from '../shared/PluginHelpers.js';\nimport { formatShortcut } from '../shared/ShortcutFormatting.js';\nimport { getBlockDir } from './DirectionDetection.js';\nimport { ShiftDirectionHandler } from './ShiftDirectionHandler.js';\nimport {\n\tTEXT_DIRECTION_LOCALE_EN,\n\ttype TextDirectionLocale,\n\tloadTextDirectionLocale,\n} from './TextDirectionLocale.js';\n\nexport type TextDirection = 'ltr' | 'rtl' | 'auto';\n\nexport interface TextDirectionConfig {\n\t/** Block types that support direction. */\n\treadonly directableTypes: readonly string[];\n\treadonly locale?: TextDirectionLocale;\n}\n\nconst DEFAULT_CONFIG: TextDirectionConfig = {\n\tdirectableTypes: [\n\t\t'paragraph',\n\t\t'heading',\n\t\t'title',\n\t\t'subtitle',\n\t\t'table_cell',\n\t\t'blockquote',\n\t\t'list_item',\n\t],\n};\n\nexport const DIRECTION_ICONS: Readonly<Record<TextDirection, string>> = {\n\tltr: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm12 8l-4-4v3H5v2h12v3l4-4z\"/></svg>',\n\trtl: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 10v5h2V4h2v11h2V4h2V2h-8C7.79 2 6 3.79 6 6s1.79 4 4 4zM8 14l-4 4 4 4v-3h12v-2H8v-3z\"/></svg>',\n\tauto: '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M9 10v5h2V4h2v11h2V4h2V2H9C6.79 2 5 3.79 5 6s1.79 4 4 4zm3 8l-4-4v3H3v2h5v3l4-4zm7 0v-3l4 4-4 4v-3h-5v-2h5z\"/></svg>',\n};\n\nconst ALL_DIRECTIONS: readonly TextDirection[] = ['ltr', 'rtl', 'auto'];\n\n/**\n * Lean text-direction plugin.\n * Includes block-level direction controls and toolbar integration only.\n */\nexport class TextDirectionCorePlugin implements Plugin {\n\treadonly id = 'text-direction';\n\treadonly name = 'Text Direction';\n\treadonly priority = 91;\n\n\tprivate readonly config: TextDirectionConfig;\n\tprivate locale!: TextDirectionLocale;\n\tprivate directableTypes!: ReadonlySet<string>;\n\tprivate shiftDirHandler: ShiftDirectionHandler | null = null;\n\n\tconstructor(config?: Partial<TextDirectionConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.locale = await resolveLocale(\n\t\t\tcontext,\n\t\t\tthis.config.locale,\n\t\t\tTEXT_DIRECTION_LOCALE_EN,\n\t\t\tloadTextDirectionLocale,\n\t\t);\n\n\t\tthis.directableTypes = new Set(this.config.directableTypes);\n\t\tthis.patchNodeSpecs(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymaps(context);\n\t\tthis.registerToolbarItem(context);\n\n\t\t// Ctrl+Shift direction shortcuts (Windows/Linux convention)\n\t\tif (!isMac()) {\n\t\t\tthis.shiftDirHandler = new ShiftDirectionHandler(context);\n\t\t\tthis.shiftDirHandler.attach(context.getContainer());\n\t\t}\n\t}\n\n\tdestroy(): void {\n\t\tthis.shiftDirHandler?.detach();\n\t\tthis.shiftDirHandler = null;\n\t}\n\n\tprivate patchNodeSpecs(context: PluginContext): void {\n\t\tconst registry = context.getSchemaRegistry();\n\n\t\tfor (const type of this.config.directableTypes) {\n\t\t\tconst spec = registry.getNodeSpec(type);\n\t\t\tif (!spec) continue;\n\n\t\t\tif (spec.attrs?.dir) continue;\n\n\t\t\tconst originalToDOM = spec.toDOM;\n\n\t\t\tregistry.removeNodeSpec(type);\n\t\t\tregistry.registerNodeSpec({\n\t\t\t\t...spec,\n\t\t\t\tattrs: {\n\t\t\t\t\t...spec.attrs,\n\t\t\t\t\tdir: { default: 'auto' },\n\t\t\t\t},\n\t\t\t\ttoDOM(node) {\n\t\t\t\t\tconst el = originalToDOM.call(spec, node);\n\t\t\t\t\tapplyDirection(el, node);\n\t\t\t\t\treturn el;\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('setDirectionLTR', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'ltr');\n\t\t\tif (result) context.announce(this.locale.announceLTR);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionRTL', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'rtl');\n\t\t\tif (result) context.announce(this.locale.announceRTL);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('setDirectionAuto', () => {\n\t\t\tconst result: boolean = this.setDirection(context, 'auto');\n\t\t\tif (result) context.announce(this.locale.announceAuto);\n\t\t\treturn result;\n\t\t});\n\n\t\tcontext.registerCommand('toggleDirection', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst block = getSelectedBlock(state);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\n\t\t\tconst current: TextDirection = getBlockDir(block);\n\t\t\tconst next: TextDirection = current === 'auto' ? 'rtl' : current === 'rtl' ? 'ltr' : 'auto';\n\t\t\treturn this.setDirection(context, next);\n\t\t});\n\t}\n\n\tprivate registerKeymaps(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-D': () => context.executeCommand('toggleDirection'),\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst commandNames: Readonly<Record<TextDirection, string>> = {\n\t\t\tltr: 'setDirectionLTR',\n\t\t\trtl: 'setDirectionRTL',\n\t\t\tauto: 'setDirectionAuto',\n\t\t};\n\n\t\tconst dropdownItems = ALL_DIRECTIONS.map((dir) => ({\n\t\t\tlabel: this.getDirectionLabel(dir),\n\t\t\tcommand: commandNames[dir],\n\t\t\ticon: DIRECTION_ICONS[dir],\n\t\t}));\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'text-direction',\n\t\t\tgroup: 'block',\n\t\t\ticon: DIRECTION_ICONS.auto,\n\t\t\tlabel: this.locale.toolbarLabel,\n\t\t\ttooltip: `${this.locale.toolbarTooltip} (${formatShortcut('Mod-Shift-D')})`,\n\t\t\tcommand: 'setDirectionAuto',\n\t\t\tpopupType: 'dropdown',\n\t\t\tpopupConfig: { items: dropdownItems },\n\t\t\tisActive: (state) => this.isNonDefaultDirection(state),\n\t\t\tisEnabled: (state) => this.isDirectable(state),\n\t\t\tgetIcon: (state) => {\n\t\t\t\tconst block = getSelectedBlock(state);\n\t\t\t\tif (!block) return DIRECTION_ICONS.auto;\n\t\t\t\tconst dir: TextDirection = getBlockDir(block);\n\t\t\t\treturn DIRECTION_ICONS[dir] ?? DIRECTION_ICONS.auto;\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate getDirectionLabel(dir: TextDirection): string {\n\t\tif (dir === 'ltr') return this.locale.ltr;\n\t\tif (dir === 'rtl') return this.locale.rtl;\n\t\treturn this.locale.auto;\n\t}\n\n\tprivate setDirection(context: PluginContext, direction: TextDirection): boolean {\n\t\tconst state = context.getState();\n\t\tconst blockIds: BlockId[] = this.getSelectedBlockIds(state);\n\t\tif (blockIds.length === 0) return false;\n\n\t\tconst tb = state.transaction('command');\n\t\tlet changed = false;\n\n\t\tfor (const id of blockIds) {\n\t\t\tconst block = state.getBlock(id);\n\t\t\tif (!block || !this.directableTypes.has(block.type)) continue;\n\n\t\t\tconst path = state.getNodePath(id);\n\t\t\tif (!path) continue;\n\n\t\t\ttb.setNodeAttr(path, { ...block.attrs, dir: direction });\n\t\t\tchanged = true;\n\t\t}\n\n\t\tif (!changed) return false;\n\n\t\tconst tr = tb.setSelection(state.selection).build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate getSelectedBlockIds(state: EditorState): BlockId[] {\n\t\tconst sel = state.selection;\n\n\t\tif (isNodeSelection(sel)) {\n\t\t\treturn [sel.nodeId];\n\t\t}\n\n\t\tif (!isTextSelection(sel)) return [];\n\n\t\tconst anchorId: BlockId = sel.anchor.blockId;\n\t\tconst headId: BlockId = sel.head.blockId;\n\n\t\tif (anchorId === headId) return [anchorId];\n\n\t\tconst order: readonly BlockId[] = state.getBlockOrder();\n\t\tconst anchorIdx: number = order.indexOf(anchorId);\n\t\tconst headIdx: number = order.indexOf(headId);\n\t\tif (anchorIdx === -1 || headIdx === -1) return [];\n\n\t\tconst from: number = Math.min(anchorIdx, headIdx);\n\t\tconst to: number = Math.max(anchorIdx, headIdx);\n\t\treturn order.slice(from, to + 1) as BlockId[];\n\t}\n\n\tprivate isNonDefaultDirection(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\tif (!block || !this.directableTypes.has(block.type)) return false;\n\t\tconst dir = block.attrs?.dir;\n\t\treturn dir != null && dir !== 'auto';\n\t}\n\n\tprivate isDirectable(state: EditorState): boolean {\n\t\tconst block = getSelectedBlock(state);\n\t\treturn block != null && this.directableTypes.has(block.type);\n\t}\n}\n\nfunction applyDirection(el: HTMLElement, node: BlockNode): void {\n\tconst dir = node.attrs?.dir;\n\tif (dir === 'ltr' || dir === 'rtl' || dir === 'auto') {\n\t\tel.setAttribute('dir', dir);\n\t}\n}\n"],"names":["DEFAULT_CONFIG","directableTypes","DIRECTION_ICONS","ltr","rtl","auto","ALL_DIRECTIONS","TextDirectionCorePlugin","id","name","priority","config","locale","shiftDirHandler","constructor","this","init","context","resolveLocale","TEXT_DIRECTION_LOCALE_EN","loadTextDirectionLocale","Set","patchNodeSpecs","registerCommands","registerKeymaps","registerToolbarItem","isMac","ShiftDirectionHandler","attach","getContainer","destroy","detach","registry","getSchemaRegistry","type","spec","getNodeSpec","attrs","dir","originalToDOM","toDOM","removeNodeSpec","registerNodeSpec","default","node","el","call","applyDirection","registerCommand","result","setDirection","announce","announceLTR","announceRTL","announceAuto","state","getState","block","getSelectedBlock","has","current","getBlockDir","next","registerKeymap","executeCommand","commandNames","dropdownItems","map","label","getDirectionLabel","command","icon","group","toolbarLabel","tooltip","toolbarTooltip","formatShortcut","popupType","popupConfig","items","isActive","isNonDefaultDirection","isEnabled","isDirectable","getIcon","direction","blockIds","getSelectedBlockIds","length","tb","transaction","changed","getBlock","path","getNodePath","setNodeAttr","tr","setSelection","selection","build","dispatch","sel","isNodeSelection","nodeId","isTextSelection","anchorId","anchor","blockId","headId","head","order","getBlockOrder","anchorIdx","indexOf","headIdx","from","Math","min","to","max","slice","setAttribute"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TextFormattingPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-formatting/TextFormattingPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE1D,OAAO,EAEN,KAAK,oBAAoB,EAEzB,MAAM,2BAA2B,CAAC;AAInC,mDAAmD;AACnD,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,2BAA2B,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC;CACvC;AAuGD,qBAAa,oBAAqB,YAAW,MAAM;IAClD,QAAQ,CAAC,EAAE,qBAAqB;IAChC,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,MAAM,CAAwB;gBAE1B,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAI5C,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBjD,OAAO,CAAC,YAAY;IAsCpB,OAAO,CAAC,eAAe;IAWvB;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAoBpC,OAAO,CAAC,YAAY;IAKpB,qEAAqE;IACrE,OAAO,CAAC,gBAAgB;CAMxB"}
1
+ {"version":3,"file":"TextFormattingPlugin.d.ts","sourceRoot":"","sources":["../../../src/plugins/text-formatting/TextFormattingPlugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,EAEN,KAAK,oBAAoB,EAEzB,MAAM,2BAA2B,CAAC;AAInC,mDAAmD;AACnD,MAAM,WAAW,2BAA2B;IAC3C,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,2BAA2B,CAAC;IAC/C,QAAQ,CAAC,MAAM,CAAC,EAAE,oBAAoB,CAAC;CACvC;AAuGD,qBAAa,oBAAqB,YAAW,MAAM;IAClD,QAAQ,CAAC,EAAE,qBAAqB;IAChC,QAAQ,CAAC,IAAI,qBAAqB;IAClC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,MAAM,CAAwB;gBAE1B,MAAM,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC;IAI5C,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBjD,OAAO,CAAC,YAAY;IAsCpB,OAAO,CAAC,eAAe;IAWvB;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAoBpC,OAAO,CAAC,YAAY;IAKpB,qEAAqE;IACrE,OAAO,CAAC,gBAAgB;CAMxB"}
@@ -1,2 +1,2 @@
1
- import{a as t}from"../chunks/LocaleService-B6Z-wyAF.mjs";import{m as e}from"../chunks/TypeBrands-Bp_Z_o5Y.mjs";import{f as s}from"../chunks/ShortcutFormatting-BLKS0Gys.mjs";import{c as i,i as o}from"../chunks/MarkCommands-B_erV7zz.mjs";const n={boldLabel:"Bold",italicLabel:"Italic",underlineLabel:"Underline"},r=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("../chunks/ar-BYNFEVLc.mjs"),"./locales/de.ts":()=>import("../chunks/de-CFD_Wgik.mjs"),"./locales/es.ts":()=>import("../chunks/es-Ce-AEYxc.mjs"),"./locales/fr.ts":()=>import("../chunks/fr-B-_yKIAY.mjs"),"./locales/hi.ts":()=>import("../chunks/hi-BMIt3y_-.mjs"),"./locales/pt.ts":()=>import("../chunks/pt-Dx9UkZ3j.mjs"),"./locales/ru.ts":()=>import("../chunks/ru-BCriPw-8.mjs"),"./locales/zh.ts":()=>import("../chunks/zh-CY01pMD4.mjs")});async function a(t){if("en"===t)return n;const e=r[`./locales/${t}.ts`];if(!e)return n;try{return(await e()).default}catch{return n}}const c={bold:!0,italic:!0,underline:!0},l=[{type:"bold",configKey:"bold",rank:0,tag:"strong",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/></svg>',keyBinding:"Mod-B",toHTMLString:t=>`<strong>${t}</strong>`,parseHTML:[{tag:"strong"},{tag:"b",getAttrs:t=>{const e=t.style.fontWeight;return"normal"!==e&&"400"!==e&&{}}},{tag:"span",getAttrs:t=>{const e=t.style.fontWeight;if(!e)return!1;if("bold"===e)return{};const s=Number.parseInt(e,10);return!Number.isNaN(s)&&s>=700&&{}}}],sanitize:{tags:["strong","b"]}},{type:"italic",configKey:"italic",rank:1,tag:"em",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/></svg>',keyBinding:"Mod-I",toHTMLString:t=>`<em>${t}</em>`,parseHTML:[{tag:"em"},{tag:"i"},{tag:"span",getAttrs:t=>"italic"===t.style.fontStyle&&{}}],sanitize:{tags:["em","i"]}},{type:"underline",configKey:"underline",rank:2,tag:"u",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z"/></svg>',keyBinding:"Mod-U",toHTMLString:t=>`<u>${t}</u>`,parseHTML:[{tag:"u"},{tag:"span",getAttrs:t=>!!t.style.textDecoration.includes("underline")&&{}}],sanitize:{tags:["u"]}}];class g{id="text-formatting";name="Text Formatting";priority=20;config;locale;constructor(t){this.config={...c,...t}}async init(e){if(this.config.locale)this.locale=this.config.locale;else{const s=e.getService(t),i=s?.getLocale()??"en";this.locale="en"===i?n:await a(i)}const s=l.filter(t=>this.config[t.configKey]);for(const t of s)this.registerMark(e,t);this.registerKeymaps(e,s),this.registerDisabledToolbarItems(e)}registerMark(t,n){const r=m(n.type),a=this.isToolbarVisible(n.configKey);if(t.registerMarkSpec({type:n.type,rank:n.rank,toDOM:()=>document.createElement(n.tag),toHTMLString:(t,e)=>n.toHTMLString(e),parseHTML:n.parseHTML,sanitize:n.sanitize}),t.registerCommand(r,()=>{const s=i(t.getState(),e(n.type));return!!s&&(t.dispatch(s),!0)}),a){const i=this.getMarkLabel(n.type);t.registerToolbarItem({id:n.type,group:"format",icon:n.icon,label:i,tooltip:`${i} (${s(n.keyBinding)})`,command:r,isActive:t=>o(t,e(n.type))})}}registerKeymaps(t,e){const s={};for(const i of e){const e=m(i.type);s[i.keyBinding]=()=>t.executeCommand(e)}Object.keys(s).length>0&&t.registerKeymap(s)}registerDisabledToolbarItems(t){if(this.config.toolbar)for(const e of l){const s=this.config[e.configKey],i=this.config.toolbar[e.configKey]??!0;!s&&i&&t.registerToolbarItem({id:e.type,group:"format",icon:e.icon,label:this.getMarkLabel(e.type),command:m(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)}}function m(t){return`toggle${t.charAt(0).toUpperCase()}${t.slice(1)}`}export{n as TEXT_FORMATTING_LOCALE_EN,g as TextFormattingPlugin,a as loadTextFormattingLocale};
1
+ import{m as t}from"../chunks/TypeBrands-Bp_Z_o5Y.mjs";import{r as e,t as s}from"../chunks/PluginHelpers-CdPR0MuT.mjs";import{f as i}from"../chunks/ShortcutFormatting-BLKS0Gys.mjs";import{c as o,i as r}from"../chunks/MarkCommands-CeCa4WSC.mjs";const n={boldLabel:"Bold",italicLabel:"Italic",underlineLabel:"Underline"},a=/* @__PURE__ */Object.assign({"./locales/ar.ts":()=>import("../chunks/ar-BYNFEVLc.mjs"),"./locales/de.ts":()=>import("../chunks/de-CFD_Wgik.mjs"),"./locales/es.ts":()=>import("../chunks/es-Ce-AEYxc.mjs"),"./locales/fr.ts":()=>import("../chunks/fr-B-_yKIAY.mjs"),"./locales/hi.ts":()=>import("../chunks/hi-BMIt3y_-.mjs"),"./locales/pt.ts":()=>import("../chunks/pt-Dx9UkZ3j.mjs"),"./locales/ru.ts":()=>import("../chunks/ru-BCriPw-8.mjs"),"./locales/zh.ts":()=>import("../chunks/zh-CY01pMD4.mjs")});async function c(t){if("en"===t)return n;const e=a[`./locales/${t}.ts`];if(!e)return n;try{return(await e()).default}catch{return n}}const l={bold:!0,italic:!0,underline:!0},g=[{type:"bold",configKey:"bold",rank:0,tag:"strong",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/></svg>',keyBinding:"Mod-B",toHTMLString:t=>`<strong>${t}</strong>`,parseHTML:[{tag:"strong"},{tag:"b",getAttrs:t=>{const e=t.style.fontWeight;return"normal"!==e&&"400"!==e&&{}}},{tag:"span",getAttrs:t=>{const e=t.style.fontWeight;if(!e)return!1;if("bold"===e)return{};const s=Number.parseInt(e,10);return!Number.isNaN(s)&&s>=700&&{}}}],sanitize:{tags:["strong","b"]}},{type:"italic",configKey:"italic",rank:1,tag:"em",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/></svg>',keyBinding:"Mod-I",toHTMLString:t=>`<em>${t}</em>`,parseHTML:[{tag:"em"},{tag:"i"},{tag:"span",getAttrs:t=>"italic"===t.style.fontStyle&&{}}],sanitize:{tags:["em","i"]}},{type:"underline",configKey:"underline",rank:2,tag:"u",icon:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z"/></svg>',keyBinding:"Mod-U",toHTMLString:t=>`<u>${t}</u>`,parseHTML:[{tag:"u"},{tag:"span",getAttrs:t=>!!t.style.textDecoration.includes("underline")&&{}}],sanitize:{tags:["u"]}}];class m{id="text-formatting";name="Text Formatting";priority=20;config;locale;constructor(t){this.config={...l,...t}}async init(t){this.locale=await e(t,this.config.locale,n,c);const s=g.filter(t=>this.config[t.configKey]);for(const e of s)this.registerMark(t,e);this.registerKeymaps(t,s),this.registerDisabledToolbarItems(t)}registerMark(e,n){const a=s(n.type),c=this.isToolbarVisible(n.configKey);if(e.registerMarkSpec({type:n.type,rank:n.rank,toDOM:()=>document.createElement(n.tag),toHTMLString:(t,e)=>n.toHTMLString(e),parseHTML:n.parseHTML,sanitize:n.sanitize}),e.registerCommand(a,()=>{const s=o(e.getState(),t(n.type));return!!s&&(e.dispatch(s),!0)}),c){const s=this.getMarkLabel(n.type);e.registerToolbarItem({id:n.type,group:"format",icon:n.icon,label:s,tooltip:`${s} (${i(n.keyBinding)})`,command:a,isActive:e=>r(e,t(n.type))})}}registerKeymaps(t,e){const i={};for(const o of e){const e=s(o.type);i[o.keyBinding]=()=>t.executeCommand(e)}Object.keys(i).length>0&&t.registerKeymap(i)}registerDisabledToolbarItems(t){if(this.config.toolbar)for(const e of g){const i=this.config[e.configKey],o=this.config.toolbar[e.configKey]??!0;!i&&o&&t.registerToolbarItem({id:e.type,group:"format",icon:e.icon,label:this.getMarkLabel(e.type),command:s(e.type),isEnabled:()=>!1})}}getMarkLabel(t){const e=`${t}Label`;return this.locale[e]}isToolbarVisible(t){return!this.config.toolbar||(this.config.toolbar[t]??!0)}}export{n as TEXT_FORMATTING_LOCALE_EN,m as TextFormattingPlugin,c as loadTextFormattingLocale};
2
2
  //# sourceMappingURL=text-formatting.mjs.map