@notectl/core 1.0.6 → 1.0.9

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 (268) hide show
  1. package/README.md +78 -56
  2. package/custom-elements.json +344 -0
  3. package/dist/chunks/{AttrRegistry-DTsHyDVA.mjs → AttrRegistry-D-przlzb.mjs} +4 -4
  4. package/dist/chunks/{AttrRegistry-DTsHyDVA.mjs.map → AttrRegistry-D-przlzb.mjs.map} +1 -1
  5. package/dist/chunks/ColorNames-iaWsSZx1.mjs +35 -0
  6. package/dist/chunks/ColorNames-iaWsSZx1.mjs.map +1 -0
  7. package/dist/chunks/ColorValidation-Dyy4Bye8.mjs +140 -0
  8. package/dist/chunks/ColorValidation-Dyy4Bye8.mjs.map +1 -0
  9. package/dist/chunks/{Commands-DLP85Mp5.mjs → Commands-CSpSwGXv.mjs} +13 -13
  10. package/dist/chunks/{Commands-DLP85Mp5.mjs.map → Commands-CSpSwGXv.mjs.map} +1 -1
  11. package/dist/chunks/ToolbarKeyboardNav-B32OMv8r.mjs +46 -0
  12. package/dist/chunks/ToolbarKeyboardNav-B32OMv8r.mjs.map +1 -0
  13. package/dist/chunks/ToolbarPlugin-DFkl1uYO.mjs +818 -0
  14. package/dist/chunks/ToolbarPlugin-DFkl1uYO.mjs.map +1 -0
  15. package/dist/chunks/index-BCvuDpVr.mjs +191 -0
  16. package/dist/chunks/index-BCvuDpVr.mjs.map +1 -0
  17. package/dist/chunks/index-BFsYGsBR.mjs +92 -0
  18. package/dist/chunks/index-BFsYGsBR.mjs.map +1 -0
  19. package/dist/chunks/index-BIL37LSL.mjs +73 -0
  20. package/dist/chunks/index-BIL37LSL.mjs.map +1 -0
  21. package/dist/chunks/index-BL56fbXt.mjs +402 -0
  22. package/dist/chunks/index-BL56fbXt.mjs.map +1 -0
  23. package/dist/chunks/index-BQ8iIYLn.mjs +209 -0
  24. package/dist/chunks/index-BQ8iIYLn.mjs.map +1 -0
  25. package/dist/chunks/index-BRYzYOYC.mjs +63 -0
  26. package/dist/chunks/index-BRYzYOYC.mjs.map +1 -0
  27. package/dist/chunks/index-BSFLNveF.mjs +953 -0
  28. package/dist/chunks/index-BSFLNveF.mjs.map +1 -0
  29. package/dist/chunks/index-BTJfyJlJ.mjs +187 -0
  30. package/dist/chunks/index-BTJfyJlJ.mjs.map +1 -0
  31. package/dist/chunks/index-Bsp4LC5t.mjs +130 -0
  32. package/dist/chunks/index-Bsp4LC5t.mjs.map +1 -0
  33. package/dist/chunks/index-DA8TG2S8.mjs +220 -0
  34. package/dist/chunks/index-DA8TG2S8.mjs.map +1 -0
  35. package/dist/chunks/index-DAFCISBN.mjs +100 -0
  36. package/dist/chunks/index-DAFCISBN.mjs.map +1 -0
  37. package/dist/chunks/index-DC1EK22F.mjs +41 -0
  38. package/dist/chunks/index-DC1EK22F.mjs.map +1 -0
  39. package/dist/chunks/index-DGrRWMlW.mjs +541 -0
  40. package/dist/chunks/index-DGrRWMlW.mjs.map +1 -0
  41. package/dist/chunks/index-DfO_fKw6.mjs +39 -0
  42. package/dist/chunks/index-DfO_fKw6.mjs.map +1 -0
  43. package/dist/chunks/index-o6hDR07y.mjs +41 -0
  44. package/dist/chunks/index-o6hDR07y.mjs.map +1 -0
  45. package/dist/chunks/index-uTnc9y7M.mjs +62 -0
  46. package/dist/chunks/index-uTnc9y7M.mjs.map +1 -0
  47. package/dist/chunks/resolvePluginLocale-B4w1OkPy.mjs +34 -0
  48. package/dist/chunks/resolvePluginLocale-B4w1OkPy.mjs.map +1 -0
  49. package/dist/editor/DocumentSerializer.d.ts.map +1 -1
  50. package/dist/editor/NotectlEditor.d.ts +37 -5
  51. package/dist/editor/NotectlEditor.d.ts.map +1 -1
  52. package/dist/editor/PaperLayoutController.d.ts +27 -0
  53. package/dist/editor/PaperLayoutController.d.ts.map +1 -0
  54. package/dist/editor/PaperSize.d.ts +35 -0
  55. package/dist/editor/PaperSize.d.ts.map +1 -0
  56. package/dist/editor/styles/color-picker.d.ts +1 -1
  57. package/dist/editor/styles/color-picker.d.ts.map +1 -1
  58. package/dist/editor/styles/list.d.ts +2 -0
  59. package/dist/editor/styles/list.d.ts.map +1 -1
  60. package/dist/editor/styles/paper.d.ts +3 -0
  61. package/dist/editor/styles/paper.d.ts.map +1 -0
  62. package/dist/editor/styles/table.d.ts +1 -1
  63. package/dist/editor/styles/table.d.ts.map +1 -1
  64. package/dist/editor/styles/toolbar.d.ts +1 -1
  65. package/dist/editor/styles/toolbar.d.ts.map +1 -1
  66. package/dist/editor/styles.d.ts.map +1 -1
  67. package/dist/i18n/Locale.d.ts +17 -0
  68. package/dist/i18n/Locale.d.ts.map +1 -0
  69. package/dist/i18n/LocaleService.d.ts +8 -0
  70. package/dist/i18n/LocaleService.d.ts.map +1 -0
  71. package/dist/i18n/index.d.ts +4 -0
  72. package/dist/i18n/index.d.ts.map +1 -0
  73. package/dist/i18n/resolvePluginLocale.d.ts +3 -0
  74. package/dist/i18n/resolvePluginLocale.d.ts.map +1 -0
  75. package/dist/index.d.ts +48 -3
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/input/ClipboardHandler.d.ts +2 -0
  78. package/dist/input/ClipboardHandler.d.ts.map +1 -1
  79. package/dist/input/InputHandler.d.ts +2 -0
  80. package/dist/input/InputHandler.d.ts.map +1 -1
  81. package/dist/input/KeyboardHandler.d.ts +2 -0
  82. package/dist/input/KeyboardHandler.d.ts.map +1 -1
  83. package/dist/input/LegacyHTMLNormalizer.d.ts +18 -0
  84. package/dist/input/LegacyHTMLNormalizer.d.ts.map +1 -0
  85. package/dist/input/PasteHandler.d.ts +4 -0
  86. package/dist/input/PasteHandler.d.ts.map +1 -1
  87. package/dist/model/HTMLParser.d.ts +13 -0
  88. package/dist/model/HTMLParser.d.ts.map +1 -1
  89. package/dist/model/SchemaRegistry.d.ts +2 -2
  90. package/dist/model/SchemaRegistry.d.ts.map +1 -1
  91. package/dist/notectl-core.mjs +2297 -1971
  92. package/dist/notectl-core.mjs.map +1 -1
  93. package/dist/notectl-core.umd.js +2894 -1825
  94. package/dist/notectl-core.umd.js.map +1 -1
  95. package/dist/plugins/Plugin.d.ts +17 -2
  96. package/dist/plugins/Plugin.d.ts.map +1 -1
  97. package/dist/plugins/PluginManager.d.ts +22 -1
  98. package/dist/plugins/PluginManager.d.ts.map +1 -1
  99. package/dist/plugins/alignment/AlignmentLocale.d.ts +19 -0
  100. package/dist/plugins/alignment/AlignmentLocale.d.ts.map +1 -0
  101. package/dist/plugins/alignment/AlignmentPlugin.d.ts +4 -0
  102. package/dist/plugins/alignment/AlignmentPlugin.d.ts.map +1 -1
  103. package/dist/plugins/alignment.mjs +3 -89
  104. package/dist/plugins/alignment.mjs.map +1 -1
  105. package/dist/plugins/blockquote/BlockquoteLocale.d.ts +17 -0
  106. package/dist/plugins/blockquote/BlockquoteLocale.d.ts.map +1 -0
  107. package/dist/plugins/blockquote/BlockquotePlugin.d.ts +3 -0
  108. package/dist/plugins/blockquote/BlockquotePlugin.d.ts.map +1 -1
  109. package/dist/plugins/blockquote.mjs +2 -55
  110. package/dist/plugins/blockquote.mjs.map +1 -1
  111. package/dist/plugins/code-block/CodeBlockLocale.d.ts +17 -0
  112. package/dist/plugins/code-block/CodeBlockLocale.d.ts.map +1 -0
  113. package/dist/plugins/code-block/CodeBlockPlugin.d.ts +1 -0
  114. package/dist/plugins/code-block/CodeBlockPlugin.d.ts.map +1 -1
  115. package/dist/plugins/code-block/CodeBlockTypes.d.ts +2 -0
  116. package/dist/plugins/code-block/CodeBlockTypes.d.ts.map +1 -1
  117. package/dist/plugins/code-block.mjs +3 -3
  118. package/dist/plugins/font/FontLocale.d.ts +15 -0
  119. package/dist/plugins/font/FontLocale.d.ts.map +1 -0
  120. package/dist/plugins/font/FontPlugin.d.ts +3 -0
  121. package/dist/plugins/font/FontPlugin.d.ts.map +1 -1
  122. package/dist/plugins/font-size/FontSizeLocale.d.ts +17 -0
  123. package/dist/plugins/font-size/FontSizeLocale.d.ts.map +1 -0
  124. package/dist/plugins/font-size/FontSizePlugin.d.ts +3 -0
  125. package/dist/plugins/font-size/FontSizePlugin.d.ts.map +1 -1
  126. package/dist/plugins/font-size/FontSizePopup.d.ts +2 -0
  127. package/dist/plugins/font-size/FontSizePopup.d.ts.map +1 -1
  128. package/dist/plugins/font-size.mjs +2 -201
  129. package/dist/plugins/font-size.mjs.map +1 -1
  130. package/dist/plugins/font.mjs +2 -183
  131. package/dist/plugins/font.mjs.map +1 -1
  132. package/dist/plugins/hard-break.mjs +1 -1
  133. package/dist/plugins/heading/HeadingBlockTypePicker.d.ts +14 -0
  134. package/dist/plugins/heading/HeadingBlockTypePicker.d.ts.map +1 -0
  135. package/dist/plugins/heading/HeadingCommands.d.ts +5 -0
  136. package/dist/plugins/heading/HeadingCommands.d.ts.map +1 -0
  137. package/dist/plugins/heading/HeadingInputRules.d.ts +5 -0
  138. package/dist/plugins/heading/HeadingInputRules.d.ts.map +1 -0
  139. package/dist/plugins/heading/HeadingKeyboardHandlers.d.ts +5 -0
  140. package/dist/plugins/heading/HeadingKeyboardHandlers.d.ts.map +1 -0
  141. package/dist/plugins/heading/HeadingLocale.d.ts +26 -0
  142. package/dist/plugins/heading/HeadingLocale.d.ts.map +1 -0
  143. package/dist/plugins/heading/HeadingPlugin.d.ts +4 -40
  144. package/dist/plugins/heading/HeadingPlugin.d.ts.map +1 -1
  145. package/dist/plugins/heading.mjs +1 -184
  146. package/dist/plugins/heading.mjs.map +1 -1
  147. package/dist/plugins/highlight/HighlightLocale.d.ts +17 -0
  148. package/dist/plugins/highlight/HighlightLocale.d.ts.map +1 -0
  149. package/dist/plugins/highlight/HighlightPlugin.d.ts +3 -5
  150. package/dist/plugins/highlight/HighlightPlugin.d.ts.map +1 -1
  151. package/dist/plugins/highlight.mjs +2 -123
  152. package/dist/plugins/highlight.mjs.map +1 -1
  153. package/dist/plugins/horizontal-rule/HorizontalRuleLocale.d.ts +15 -0
  154. package/dist/plugins/horizontal-rule/HorizontalRuleLocale.d.ts.map +1 -0
  155. package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts +4 -0
  156. package/dist/plugins/horizontal-rule/HorizontalRulePlugin.d.ts.map +1 -1
  157. package/dist/plugins/horizontal-rule.mjs +2 -56
  158. package/dist/plugins/horizontal-rule.mjs.map +1 -1
  159. package/dist/plugins/image/ImageLocale.d.ts +25 -0
  160. package/dist/plugins/image/ImageLocale.d.ts.map +1 -0
  161. package/dist/plugins/image/ImagePlugin.d.ts +1 -0
  162. package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
  163. package/dist/plugins/image/ImageUpload.d.ts +3 -0
  164. package/dist/plugins/image/ImageUpload.d.ts.map +1 -1
  165. package/dist/plugins/image.mjs +4 -378
  166. package/dist/plugins/image.mjs.map +1 -1
  167. package/dist/plugins/link/LinkLocale.d.ts +23 -0
  168. package/dist/plugins/link/LinkLocale.d.ts.map +1 -0
  169. package/dist/plugins/link/LinkPlugin.d.ts +3 -0
  170. package/dist/plugins/link/LinkPlugin.d.ts.map +1 -1
  171. package/dist/plugins/link.mjs +2 -124
  172. package/dist/plugins/link.mjs.map +1 -1
  173. package/dist/plugins/list/ListLocale.d.ts +18 -0
  174. package/dist/plugins/list/ListLocale.d.ts.map +1 -0
  175. package/dist/plugins/list/ListPlugin.d.ts +13 -0
  176. package/dist/plugins/list/ListPlugin.d.ts.map +1 -1
  177. package/dist/plugins/list.mjs +2 -190
  178. package/dist/plugins/list.mjs.map +1 -1
  179. package/dist/plugins/print/PrintLocale.d.ts +16 -0
  180. package/dist/plugins/print/PrintLocale.d.ts.map +1 -0
  181. package/dist/plugins/print/PrintPlugin.d.ts +1 -0
  182. package/dist/plugins/print/PrintPlugin.d.ts.map +1 -1
  183. package/dist/plugins/print/PrintStyleCollector.d.ts +7 -0
  184. package/dist/plugins/print/PrintStyleCollector.d.ts.map +1 -1
  185. package/dist/plugins/print/PrintTypes.d.ts +5 -0
  186. package/dist/plugins/print/PrintTypes.d.ts.map +1 -1
  187. package/dist/plugins/shared/ColorMarkOperations.d.ts +28 -0
  188. package/dist/plugins/shared/ColorMarkOperations.d.ts.map +1 -0
  189. package/dist/plugins/shared/ColorNames.d.ts +22 -0
  190. package/dist/plugins/shared/ColorNames.d.ts.map +1 -0
  191. package/dist/plugins/shared/ColorPickerPopup.d.ts +31 -0
  192. package/dist/plugins/shared/ColorPickerPopup.d.ts.map +1 -0
  193. package/dist/plugins/shared/ColorValidation.d.ts +14 -0
  194. package/dist/plugins/shared/ColorValidation.d.ts.map +1 -0
  195. package/dist/plugins/strikethrough/StrikethroughLocale.d.ts +17 -0
  196. package/dist/plugins/strikethrough/StrikethroughLocale.d.ts.map +1 -0
  197. package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts +3 -0
  198. package/dist/plugins/strikethrough/StrikethroughPlugin.d.ts.map +1 -1
  199. package/dist/plugins/strikethrough.mjs +2 -32
  200. package/dist/plugins/strikethrough.mjs.map +1 -1
  201. package/dist/plugins/super-sub/SuperSubLocale.d.ts +19 -0
  202. package/dist/plugins/super-sub/SuperSubLocale.d.ts.map +1 -0
  203. package/dist/plugins/super-sub/SuperSubPlugin.d.ts +3 -0
  204. package/dist/plugins/super-sub/SuperSubPlugin.d.ts.map +1 -1
  205. package/dist/plugins/super-sub.mjs +2 -78
  206. package/dist/plugins/super-sub.mjs.map +1 -1
  207. package/dist/plugins/table/TableBorderColor.d.ts +24 -0
  208. package/dist/plugins/table/TableBorderColor.d.ts.map +1 -0
  209. package/dist/plugins/table/TableCommands.d.ts +9 -8
  210. package/dist/plugins/table/TableCommands.d.ts.map +1 -1
  211. package/dist/plugins/table/TableContextMenu.d.ts +14 -0
  212. package/dist/plugins/table/TableContextMenu.d.ts.map +1 -0
  213. package/dist/plugins/table/TableControls.d.ts +3 -1
  214. package/dist/plugins/table/TableControls.d.ts.map +1 -1
  215. package/dist/plugins/table/TableControlsDOM.d.ts +13 -1
  216. package/dist/plugins/table/TableControlsDOM.d.ts.map +1 -1
  217. package/dist/plugins/table/TableLocale.d.ts +48 -0
  218. package/dist/plugins/table/TableLocale.d.ts.map +1 -0
  219. package/dist/plugins/table/TableNavigation.d.ts +2 -1
  220. package/dist/plugins/table/TableNavigation.d.ts.map +1 -1
  221. package/dist/plugins/table/TableNodeViews.d.ts +3 -1
  222. package/dist/plugins/table/TableNodeViews.d.ts.map +1 -1
  223. package/dist/plugins/table/TablePlugin.d.ts +7 -1
  224. package/dist/plugins/table/TablePlugin.d.ts.map +1 -1
  225. package/dist/plugins/table/index.d.ts +3 -0
  226. package/dist/plugins/table/index.d.ts.map +1 -1
  227. package/dist/plugins/table.mjs +18 -660
  228. package/dist/plugins/table.mjs.map +1 -1
  229. package/dist/plugins/text-color/TextColorLocale.d.ts +17 -0
  230. package/dist/plugins/text-color/TextColorLocale.d.ts.map +1 -0
  231. package/dist/plugins/text-color/TextColorPlugin.d.ts +3 -5
  232. package/dist/plugins/text-color/TextColorPlugin.d.ts.map +1 -1
  233. package/dist/plugins/text-color.mjs +2 -123
  234. package/dist/plugins/text-color.mjs.map +1 -1
  235. package/dist/plugins/text-formatting/TextFormattingLocale.d.ts +18 -0
  236. package/dist/plugins/text-formatting/TextFormattingLocale.d.ts.map +1 -0
  237. package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts +4 -0
  238. package/dist/plugins/text-formatting/TextFormattingPlugin.d.ts.map +1 -1
  239. package/dist/plugins/text-formatting.mjs +2 -49
  240. package/dist/plugins/text-formatting.mjs.map +1 -1
  241. package/dist/plugins/toolbar/ToolbarLocale.d.ts +15 -0
  242. package/dist/plugins/toolbar/ToolbarLocale.d.ts.map +1 -0
  243. package/dist/plugins/toolbar/ToolbarOverflowBehavior.d.ts +23 -0
  244. package/dist/plugins/toolbar/ToolbarOverflowBehavior.d.ts.map +1 -0
  245. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts +56 -0
  246. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts.map +1 -0
  247. package/dist/plugins/toolbar/ToolbarPlugin.d.ts +18 -0
  248. package/dist/plugins/toolbar/ToolbarPlugin.d.ts.map +1 -1
  249. package/dist/plugins/toolbar.mjs +1 -1
  250. package/dist/state/EditorState.d.ts +4 -1
  251. package/dist/state/EditorState.d.ts.map +1 -1
  252. package/dist/state/ReadonlyGuard.d.ts +6 -0
  253. package/dist/state/ReadonlyGuard.d.ts.map +1 -0
  254. package/dist/state/Transaction.d.ts +4 -0
  255. package/dist/state/Transaction.d.ts.map +1 -1
  256. package/dist/view/EditorView.d.ts +2 -0
  257. package/dist/view/EditorView.d.ts.map +1 -1
  258. package/package.json +3 -2
  259. package/dist/chunks/Plugin-B9OZ6Y4c.mjs +0 -15
  260. package/dist/chunks/Plugin-B9OZ6Y4c.mjs.map +0 -1
  261. package/dist/chunks/ToolbarPlugin-sJTiZr-S.mjs +0 -398
  262. package/dist/chunks/ToolbarPlugin-sJTiZr-S.mjs.map +0 -1
  263. package/dist/chunks/color-picker-Csf0wx5a.mjs +0 -5
  264. package/dist/chunks/color-picker-Csf0wx5a.mjs.map +0 -1
  265. package/dist/chunks/index-QvKiO9_4.mjs +0 -538
  266. package/dist/chunks/index-QvKiO9_4.mjs.map +0 -1
  267. package/dist/input/SourceNormalizer.d.ts +0 -7
  268. package/dist/input/SourceNormalizer.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BFsYGsBR.mjs","sources":["../../src/plugins/super-sub/SuperSubLocale.ts","../../src/plugins/super-sub/SuperSubPlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the SuperSubPlugin.\n */\n\n// --- Locale Interface ---\n\nexport interface SuperSubLocale {\n\treadonly superscriptLabel: string;\n\treadonly superscriptTooltip: (shortcut: string) => string;\n\treadonly subscriptLabel: string;\n\treadonly subscriptTooltip: (shortcut: string) => string;\n}\n\n// --- Default English Locale ---\n\nexport const SUPER_SUB_LOCALE_EN: SuperSubLocale = {\n\tsuperscriptLabel: 'Superscript',\n\tsuperscriptTooltip: (shortcut: string) => `Superscript (${shortcut})`,\n\tsubscriptLabel: 'Subscript',\n\tsubscriptTooltip: (shortcut: string) => `Subscript (${shortcut})`,\n};\n\n// --- German Locale ---\n\nexport const SUPER_SUB_LOCALE_DE: SuperSubLocale = {\n\tsuperscriptLabel: 'Hochgestellt',\n\tsuperscriptTooltip: (shortcut: string) => `Hochgestellt (${shortcut})`,\n\tsubscriptLabel: 'Tiefgestellt',\n\tsubscriptTooltip: (shortcut: string) => `Tiefgestellt (${shortcut})`,\n};\n\n// --- Spanish Locale ---\n\nexport const SUPER_SUB_LOCALE_ES: SuperSubLocale = {\n\tsuperscriptLabel: 'Superíndice',\n\tsuperscriptTooltip: (shortcut: string) => `Superíndice (${shortcut})`,\n\tsubscriptLabel: 'Subíndice',\n\tsubscriptTooltip: (shortcut: string) => `Subíndice (${shortcut})`,\n};\n\n// --- French Locale ---\n\nexport const SUPER_SUB_LOCALE_FR: SuperSubLocale = {\n\tsuperscriptLabel: 'Exposant',\n\tsuperscriptTooltip: (shortcut: string) => `Exposant (${shortcut})`,\n\tsubscriptLabel: 'Indice',\n\tsubscriptTooltip: (shortcut: string) => `Indice (${shortcut})`,\n};\n\n// --- Chinese (Simplified) Locale ---\n\nexport const SUPER_SUB_LOCALE_ZH: SuperSubLocale = {\n\tsuperscriptLabel: '上标',\n\tsuperscriptTooltip: (shortcut: string) => `上标 (${shortcut})`,\n\tsubscriptLabel: '下标',\n\tsubscriptTooltip: (shortcut: string) => `下标 (${shortcut})`,\n};\n\n// --- Russian Locale ---\n\nexport const SUPER_SUB_LOCALE_RU: SuperSubLocale = {\n\tsuperscriptLabel: 'Надстрочный',\n\tsuperscriptTooltip: (shortcut: string) => `Надстрочный (${shortcut})`,\n\tsubscriptLabel: 'Подстрочный',\n\tsubscriptTooltip: (shortcut: string) => `Подстрочный (${shortcut})`,\n};\n\n// --- Arabic Locale ---\n\nexport const SUPER_SUB_LOCALE_AR: SuperSubLocale = {\n\tsuperscriptLabel: 'مرتفع',\n\tsuperscriptTooltip: (shortcut: string) => `مرتفع (${shortcut})`,\n\tsubscriptLabel: 'منخفض',\n\tsubscriptTooltip: (shortcut: string) => `منخفض (${shortcut})`,\n};\n\n// --- Hindi Locale ---\n\nexport const SUPER_SUB_LOCALE_HI: SuperSubLocale = {\n\tsuperscriptLabel: 'सुपरस्क्रिप्ट',\n\tsuperscriptTooltip: (shortcut: string) => `सुपरस्क्रिप्ट (${shortcut})`,\n\tsubscriptLabel: 'सबस्क्रिप्ट',\n\tsubscriptTooltip: (shortcut: string) => `सबस्क्रिप्ट (${shortcut})`,\n};\n\n// --- Locale Map ---\n\nexport const SUPER_SUB_LOCALES: Record<string, SuperSubLocale> = {\n\ten: SUPER_SUB_LOCALE_EN,\n\tde: SUPER_SUB_LOCALE_DE,\n\tes: SUPER_SUB_LOCALE_ES,\n\tfr: SUPER_SUB_LOCALE_FR,\n\tzh: SUPER_SUB_LOCALE_ZH,\n\tru: SUPER_SUB_LOCALE_RU,\n\tar: SUPER_SUB_LOCALE_AR,\n\thi: SUPER_SUB_LOCALE_HI,\n};\n","/**\n * SuperSubPlugin: registers superscript and subscript inline marks with\n * MarkSpecs, toggle commands, keyboard shortcuts, toolbar buttons, and\n * a middleware that enforces mutual exclusivity between the two marks.\n *\n * Data-driven — each mark type is defined declaratively and all\n * registrations are derived from the same definition table.\n */\n\nimport { isMarkActive, toggleMark } from '../../commands/Commands.js';\nimport { resolvePluginLocale } from '../../i18n/resolvePluginLocale.js';\nimport type { Mark } from '../../model/Document.js';\nimport type { ParseRule } from '../../model/ParseRule.js';\nimport type { SanitizeConfig } from '../../model/SanitizeConfig.js';\nimport { markType as mkType } from '../../model/TypeBrands.js';\nimport type { RemoveMarkStep, Step } from '../../state/Transaction.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\nimport { SUPER_SUB_LOCALES, type SuperSubLocale } from './SuperSubLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tsuperscript: Record<string, never>;\n\t\tsubscript: Record<string, never>;\n\t}\n}\n\n// --- Configuration ---\n\n/** Controls toolbar button visibility per mark. */\nexport interface SuperSubToolbarConfig {\n\treadonly superscript?: boolean;\n\treadonly subscript?: boolean;\n}\n\n/** Controls which marks are enabled and which toolbar buttons are shown. */\nexport interface SuperSubConfig {\n\treadonly superscript: boolean;\n\treadonly subscript: boolean;\n\treadonly toolbar?: SuperSubToolbarConfig;\n\t/** When true, a separator is rendered after the last toolbar item. */\n\treadonly separatorAfter?: boolean;\n\treadonly locale?: SuperSubLocale;\n}\n\nconst DEFAULT_CONFIG: SuperSubConfig = {\n\tsuperscript: true,\n\tsubscript: true,\n};\n\n// --- Mark Definitions ---\n\ninterface MarkDefinition {\n\treadonly type: 'superscript' | 'subscript';\n\treadonly opposite: 'superscript' | 'subscript';\n\treadonly configKey: keyof Omit<SuperSubConfig, 'toolbar' | 'separatorAfter' | 'locale'>;\n\treadonly rank: number;\n\treadonly tag: string;\n\treadonly label: string;\n\treadonly icon: string;\n\treadonly keyBinding: string;\n\treadonly toolbarPriority: number;\n\treadonly toHTMLString: (content: string) => string;\n\treadonly parseHTML: readonly ParseRule[];\n\treadonly sanitize: SanitizeConfig;\n}\n\nconst SUPERSCRIPT_ICON: string = [\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">',\n\t'<path d=\"M16 7.41L11.41 12 16 16.59 14.59 18l-6-6 6-6z\"',\n\t' fill=\"none\"/>',\n\t'<path d=\"M9.64 7.64c.23-.5.36-1.05.36-1.64',\n\t' 0-2.21-1.79-4-4-4H2v14h4.36c2.34 0 4.24-1.9',\n\t' 4.24-4.24 0-1.6-.89-2.99-2.2-3.71zM4.5 4.5H6c.83',\n\t' 0 1.5.67 1.5 1.5S6.83 7.5 6 7.5H4.5v-3zm2 9H4.5v-3H6.5c.83',\n\t' 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z\" fill=\"none\"/>',\n\t'<path d=\"M15.97 3.84c0-.47.19-.91.53-1.21.34-.31.8-.49',\n\t' 1.3-.49.5 0 .95.18 1.28.48.32.3.5.7.51 1.15h1.59c-.02',\n\t'-.96-.43-1.83-1.13-2.42C19.36.77 18.45.44 17.5.44c-.88',\n\t' 0-1.74.28-2.39.8-.67.53-1.06 1.28-1.06 2.1 0 .76.34',\n\t' 1.47.93 1.97.59.49 1.41.84 2.32 1.15.7.24 1.26.5 1.62.8.35.3.53.64.53',\n\t' 1.02 0 .48-.2.93-.55 1.24-.36.3-.84.48-1.37.48-.55 0-1.04-.2-1.39-.54',\n\t'-.34-.33-.53-.8-.53-1.32h-1.58c.01 1.02.43 1.95 1.16 2.57.72.62 1.67.96',\n\t' 2.67.96.92 0 1.81-.3 2.46-.84.67-.56 1.04-1.33 1.04-2.18 0-.81-.36-1.56',\n\t'-.99-2.08-.62-.51-1.48-.88-2.43-1.2-.67-.23-1.2-.47-1.52-.75-.32-.27-.46',\n\t'-.59-.46-.94z\"/>',\n\t'<path d=\"M5.88 20h2.66l3.4-5.42L15.3 20h2.67l-4.73-7.38',\n\t' 4.37-6.62h-2.6l-3.07 4.98L8.92 6h-2.6l4.26 6.58z\"/>',\n\t'</svg>',\n].join('');\n\nconst SUBSCRIPT_ICON: string = [\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">',\n\t'<path d=\"M15.97 16.84c0-.47.19-.91.53-1.21.34-.31.8-.49',\n\t' 1.3-.49.5 0 .95.18 1.28.48.32.3.5.7.51 1.15h1.59c-.02',\n\t'-.96-.43-1.83-1.13-2.42-.7-.58-1.61-.91-2.56-.91-.88',\n\t' 0-1.74.28-2.39.8-.67.53-1.06 1.28-1.06 2.1 0 .76.34',\n\t' 1.47.93 1.97.59.49 1.41.84 2.32 1.15.7.24 1.26.5 1.62.8.35.3.53.64.53',\n\t' 1.02 0 .48-.2.93-.55 1.24-.36.3-.84.48-1.37.48-.55 0-1.04-.2-1.39-.54',\n\t'-.34-.33-.53-.8-.53-1.32h-1.58c.01 1.02.43 1.95 1.16 2.57.72.62 1.67.96',\n\t' 2.67.96.92 0 1.81-.3 2.46-.84.67-.56 1.04-1.33 1.04-2.18 0-.81-.36-1.56',\n\t'-.99-2.08-.62-.51-1.48-.88-2.43-1.2-.67-.23-1.2-.47-1.52-.75-.32-.27-.46',\n\t'-.59-.46-.94z\"/>',\n\t'<path d=\"M5.88 18h2.66l3.4-5.42L15.3 18h2.67l-4.73-7.38',\n\t' 4.37-6.62h-2.6l-3.07 4.98L8.92 4h-2.6l4.26 6.58z\"/>',\n\t'</svg>',\n].join('');\n\nconst MARK_DEFINITIONS: readonly MarkDefinition[] = [\n\t{\n\t\ttype: 'superscript',\n\t\topposite: 'subscript',\n\t\tconfigKey: 'superscript',\n\t\trank: 4,\n\t\ttag: 'sup',\n\t\tlabel: 'Superscript',\n\t\ticon: SUPERSCRIPT_ICON,\n\t\tkeyBinding: 'Mod-.',\n\t\ttoolbarPriority: 50,\n\t\ttoHTMLString: (content) => `<sup>${content}</sup>`,\n\t\tparseHTML: [{ tag: 'sup' }],\n\t\tsanitize: { tags: ['sup'] },\n\t},\n\t{\n\t\ttype: 'subscript',\n\t\topposite: 'superscript',\n\t\tconfigKey: 'subscript',\n\t\trank: 4,\n\t\ttag: 'sub',\n\t\tlabel: 'Subscript',\n\t\ticon: SUBSCRIPT_ICON,\n\t\tkeyBinding: 'Mod-,',\n\t\ttoolbarPriority: 51,\n\t\ttoHTMLString: (content) => `<sub>${content}</sub>`,\n\t\tparseHTML: [{ tag: 'sub' }],\n\t\tsanitize: { tags: ['sub'] },\n\t},\n];\n\n// --- Plugin ---\n\nexport class SuperSubPlugin implements Plugin {\n\treadonly id = 'super-sub';\n\treadonly name = 'Superscript & Subscript';\n\treadonly priority = 23;\n\n\tprivate readonly config: SuperSubConfig;\n\tprivate locale!: SuperSubLocale;\n\n\tconstructor(config?: Partial<SuperSubConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.locale = resolvePluginLocale(SUPER_SUB_LOCALES, context, this.config.locale);\n\n\t\tconst enabledMarks: MarkDefinition[] = MARK_DEFINITIONS.filter(\n\t\t\t(def) => this.config[def.configKey],\n\t\t);\n\n\t\tconst visibleToolbarMarks: MarkDefinition[] = enabledMarks.filter((def) =>\n\t\t\tthis.isToolbarVisible(def.configKey),\n\t\t);\n\t\tconst lastVisibleMark: MarkDefinition | undefined = visibleToolbarMarks.at(-1);\n\n\t\tfor (const def of enabledMarks) {\n\t\t\tconst isSeparatorTarget: boolean = !!this.config.separatorAfter && def === lastVisibleMark;\n\t\t\tthis.registerMark(context, def, isSeparatorTarget);\n\t\t}\n\n\t\tthis.registerKeymaps(context, enabledMarks);\n\t\tthis.registerExclusivityMiddleware(context, enabledMarks);\n\t\tthis.registerDisabledToolbarItems(context);\n\t}\n\n\tprivate registerMark(context: PluginContext, def: MarkDefinition, separatorAfter: boolean): void {\n\t\tconst commandName: string = toCommandName(def.type);\n\t\tconst toolbarVisible: boolean = this.isToolbarVisible(def.configKey);\n\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: def.type,\n\t\t\trank: def.rank,\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement(def.tag);\n\t\t\t},\n\t\t\ttoHTMLString: (_mark, content) => def.toHTMLString(content),\n\t\t\tparseHTML: def.parseHTML,\n\t\t\tsanitize: def.sanitize,\n\t\t});\n\n\t\tcontext.registerCommand(commandName, () => {\n\t\t\tconst tr = toggleMark(context.getState(), mkType(def.type));\n\t\t\tif (tr) {\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\n\t\tif (toolbarVisible) {\n\t\t\tconst label: string =\n\t\t\t\tdef.type === 'superscript' ? this.locale.superscriptLabel : this.locale.subscriptLabel;\n\t\t\tconst tooltip: string =\n\t\t\t\tdef.type === 'superscript'\n\t\t\t\t\t? this.locale.superscriptTooltip(formatShortcut(def.keyBinding))\n\t\t\t\t\t: this.locale.subscriptTooltip(formatShortcut(def.keyBinding));\n\t\t\tcontext.registerToolbarItem({\n\t\t\t\tid: def.type,\n\t\t\t\tgroup: 'format',\n\t\t\t\ticon: def.icon,\n\t\t\t\tlabel,\n\t\t\t\ttooltip,\n\t\t\t\tcommand: commandName,\n\t\t\t\tpriority: def.toolbarPriority,\n\t\t\t\tseparatorAfter,\n\t\t\t\tisActive: (state) => isMarkActive(state, mkType(def.type)),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerKeymaps(context: PluginContext, marks: readonly MarkDefinition[]): void {\n\t\tconst keymap: Record<string, () => boolean> = {};\n\t\tfor (const def of marks) {\n\t\t\tconst commandName: string = toCommandName(def.type);\n\t\t\tkeymap[def.keyBinding] = () => context.executeCommand(commandName);\n\t\t}\n\t\tif (Object.keys(keymap).length > 0) {\n\t\t\tcontext.registerKeymap(keymap);\n\t\t}\n\t}\n\n\t/**\n\t * Ensures superscript and subscript are mutually exclusive.\n\t * When an addMark step for one type is found, a removeMark step\n\t * for the opposite type is injected. For stored marks, the opposite\n\t * mark is filtered out.\n\t */\n\tprivate registerExclusivityMiddleware(\n\t\tcontext: PluginContext,\n\t\tenabledMarks: readonly MarkDefinition[],\n\t): void {\n\t\tconst bothEnabled: boolean =\n\t\t\tenabledMarks.some((d) => d.type === 'superscript') &&\n\t\t\tenabledMarks.some((d) => d.type === 'subscript');\n\n\t\tif (!bothEnabled) return;\n\n\t\tcontext.registerMiddleware(\n\t\t\t(tr, _state, next) => {\n\t\t\t\tlet patched = false;\n\n\t\t\t\t// Handle addMark steps: inject removeMark for the opposite type\n\t\t\t\tconst patchedSteps: Step[] = [];\n\t\t\t\tfor (const step of tr.steps) {\n\t\t\t\t\tif (step.type !== 'addMark') {\n\t\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst markName: string = step.mark.type;\n\t\t\t\t\tconst def: MarkDefinition | undefined = MARK_DEFINITIONS.find((d) => d.type === markName);\n\t\t\t\t\tif (!def) {\n\t\t\t\t\t\tpatchedSteps.push(step);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tpatched = true;\n\t\t\t\t\tconst removeStep: RemoveMarkStep = {\n\t\t\t\t\t\ttype: 'removeMark',\n\t\t\t\t\t\tblockId: step.blockId,\n\t\t\t\t\t\tfrom: step.from,\n\t\t\t\t\t\tto: step.to,\n\t\t\t\t\t\tmark: { type: mkType(def.opposite) },\n\t\t\t\t\t\t...(step.path ? { path: step.path } : {}),\n\t\t\t\t\t};\n\t\t\t\t\tpatchedSteps.push(removeStep, step);\n\t\t\t\t}\n\n\t\t\t\t// Handle stored marks: remove the opposite mark\n\t\t\t\tlet storedMarksAfter: readonly Mark[] | null = tr.storedMarksAfter;\n\t\t\t\tif (storedMarksAfter) {\n\t\t\t\t\tconst hasSup: boolean = storedMarksAfter.some((m) => m.type === 'superscript');\n\t\t\t\t\tconst hasSub: boolean = storedMarksAfter.some((m) => m.type === 'subscript');\n\n\t\t\t\t\tif (hasSup && hasSub) {\n\t\t\t\t\t\t// Keep the one that was most recently added (last in array)\n\t\t\t\t\t\tconst lastSupIdx: number = storedMarksAfter.findLastIndex(\n\t\t\t\t\t\t\t(m) => m.type === 'superscript',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst lastSubIdx: number = storedMarksAfter.findLastIndex(\n\t\t\t\t\t\t\t(m) => m.type === 'subscript',\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst removeType: string = lastSupIdx > lastSubIdx ? 'subscript' : 'superscript';\n\n\t\t\t\t\t\tstoredMarksAfter = storedMarksAfter.filter((m) => m.type !== removeType);\n\t\t\t\t\t\tpatched = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tnext(patched ? { ...tr, steps: patchedSteps, storedMarksAfter } : tr);\n\t\t\t},\n\t\t\t{ name: 'super-sub:exclusivity' },\n\t\t);\n\t}\n\n\t/**\n\t * Registers disabled toolbar buttons for marks whose feature is disabled\n\t * but whose toolbar button is explicitly requested.\n\t */\n\tprivate registerDisabledToolbarItems(context: PluginContext): void {\n\t\tif (!this.config.toolbar) return;\n\n\t\tfor (const def of MARK_DEFINITIONS) {\n\t\t\tconst featureEnabled: boolean = this.config[def.configKey];\n\t\t\tconst toolbarVisible: boolean = this.config.toolbar[def.configKey] ?? true;\n\n\t\t\tif (!featureEnabled && toolbarVisible) {\n\t\t\t\tconst label: string =\n\t\t\t\t\tdef.type === 'superscript' ? this.locale.superscriptLabel : this.locale.subscriptLabel;\n\t\t\t\tcontext.registerToolbarItem({\n\t\t\t\t\tid: def.type,\n\t\t\t\t\tgroup: 'format',\n\t\t\t\t\ticon: def.icon,\n\t\t\t\t\tlabel,\n\t\t\t\t\tcommand: toCommandName(def.type),\n\t\t\t\t\tpriority: def.toolbarPriority,\n\t\t\t\t\tisEnabled: () => false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate isToolbarVisible(\n\t\tconfigKey: keyof Omit<SuperSubConfig, 'toolbar' | 'separatorAfter' | 'locale'>,\n\t): boolean {\n\t\tif (!this.config.toolbar) return true;\n\t\treturn this.config.toolbar[configKey] ?? true;\n\t}\n}\n\n/** Converts a mark type to its toggle command name (e.g. 'superscript' → 'toggleSuperscript'). */\nfunction toCommandName(markType: string): string {\n\treturn `toggle${markType.charAt(0).toUpperCase()}${markType.slice(1)}`;\n}\n"],"names":["SUPER_SUB_LOCALE_EN","superscriptLabel","superscriptTooltip","shortcut","subscriptLabel","subscriptTooltip","SUPER_SUB_LOCALES","en","de","es","fr","zh","ru","ar","hi","DEFAULT_CONFIG","superscript","subscript","MARK_DEFINITIONS","type","opposite","configKey","rank","tag","label","icon","join","keyBinding","toolbarPriority","toHTMLString","content","parseHTML","sanitize","tags","SuperSubPlugin","id","name","priority","config","locale","this","context","resolvePluginLocale","enabledMarks","filter","def","lastVisibleMark","isToolbarVisible","at","isSeparatorTarget","separatorAfter","registerMark","registerKeymaps","registerExclusivityMiddleware","registerDisabledToolbarItems","commandName","toCommandName","toolbarVisible","registerMarkSpec","toDOM","document","createElement","_mark","registerCommand","tr","toggleMark","getState","mkType","dispatch","tooltip","formatShortcut","registerToolbarItem","group","command","isActive","state","isMarkActive","marks","keymap","executeCommand","Object","keys","length","registerKeymap","some","d","registerMiddleware","_state","next","patched","patchedSteps","step","steps","push","markName","mark","find","removeStep","blockId","from","to","path","storedMarksAfter","hasSup","m","hasSub","removeType","findLastIndex","toolbar","featureEnabled","isEnabled","markType","charAt","toUpperCase","slice"],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { A as e, t } from "./Commands-CSpSwGXv.mjs";
2
+ import { r as i } from "./resolvePluginLocale-B4w1OkPy.mjs";
3
+ import { m as a } from "./TypeBrands-C09nE2qO.mjs";
4
+ import { f as r } from "./ToolbarItem-ugDymuXi.mjs";
5
+ const o = { boldLabel: "Bold", italicLabel: "Italic", underlineLabel: "Underline" }, n = { en: o, de: { boldLabel: "Fett", italicLabel: "Kursiv", underlineLabel: "Unterstrichen" }, es: { boldLabel: "Negrita", italicLabel: "Cursiva", underlineLabel: "Subrayado" }, fr: { boldLabel: "Gras", italicLabel: "Italique", underlineLabel: "Souligné" }, zh: { boldLabel: "粗体", italicLabel: "斜体", underlineLabel: "下划线" }, ru: { boldLabel: "Жирный", italicLabel: "Курсив", underlineLabel: "Подчёркнутый" }, ar: { boldLabel: "غامق", italicLabel: "مائل", underlineLabel: "تحته خط" }, hi: { boldLabel: "बोल्ड", italicLabel: "इटैलिक", underlineLabel: "अंडरलाइन" } }, s = { bold: true, italic: true, underline: true }, l = [{ type: "bold", configKey: "bold", rank: 0, tag: "strong", label: "Bold", 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: (e2) => `<strong>${e2}</strong>`, parseHTML: [{ tag: "strong" }, { tag: "b", getAttrs: (e2) => {
6
+ const t2 = e2.style.fontWeight;
7
+ return "normal" !== t2 && "400" !== t2 && {};
8
+ } }, { tag: "span", getAttrs: (e2) => {
9
+ const t2 = e2.style.fontWeight;
10
+ if (!t2) return false;
11
+ if ("bold" === t2) return {};
12
+ const i2 = Number.parseInt(t2, 10);
13
+ return !Number.isNaN(i2) && i2 >= 700 && {};
14
+ } }], sanitize: { tags: ["strong", "b"] } }, { type: "italic", configKey: "italic", rank: 1, tag: "em", label: "Italic", 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: (e2) => `<em>${e2}</em>`, parseHTML: [{ tag: "em" }, { tag: "i" }, { tag: "span", getAttrs: (e2) => "italic" === e2.style.fontStyle && {} }], sanitize: { tags: ["em", "i"] } }, { type: "underline", configKey: "underline", rank: 2, tag: "u", label: "Underline", 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: (e2) => `<u>${e2}</u>`, parseHTML: [{ tag: "u" }, { tag: "span", getAttrs: (e2) => !!e2.style.textDecoration.includes("underline") && {} }], sanitize: { tags: ["u"] } }];
15
+ class g {
16
+ id = "text-formatting";
17
+ name = "Text Formatting";
18
+ priority = 20;
19
+ config;
20
+ locale;
21
+ constructor(e2) {
22
+ this.config = { ...s, ...e2 };
23
+ }
24
+ init(e2) {
25
+ this.locale = i(n, e2, this.config.locale);
26
+ const t2 = l.filter((e3) => this.config[e3.configKey]), a2 = t2.filter((e3) => this.isToolbarVisible(e3.configKey)).at(-1);
27
+ for (const i2 of t2) {
28
+ const t3 = this.config.separatorAfter && i2 === a2;
29
+ this.registerMark(e2, i2, t3);
30
+ }
31
+ this.registerKeymaps(e2, t2), this.registerDisabledToolbarItems(e2);
32
+ }
33
+ registerMark(i2, o2, n2) {
34
+ const s2 = c(o2.type), l2 = this.isToolbarVisible(o2.configKey);
35
+ if (i2.registerMarkSpec({ type: o2.type, rank: o2.rank, toDOM: () => document.createElement(o2.tag), toHTMLString: (e2, t2) => o2.toHTMLString(t2), parseHTML: o2.parseHTML, sanitize: o2.sanitize }), i2.registerCommand(s2, () => {
36
+ const t2 = e(i2.getState(), a(o2.type));
37
+ return !!t2 && (i2.dispatch(t2), true);
38
+ }), l2) {
39
+ const e2 = this.getMarkLabel(o2.type);
40
+ i2.registerToolbarItem({ id: o2.type, group: "format", icon: o2.icon, label: e2, tooltip: `${e2} (${r(o2.keyBinding)})`, command: s2, priority: 10 * o2.rank + 10, separatorAfter: n2, isActive: (e3) => t(e3, a(o2.type)) });
41
+ }
42
+ }
43
+ registerKeymaps(e2, t2) {
44
+ const i2 = {};
45
+ for (const a2 of t2) {
46
+ const t3 = c(a2.type);
47
+ i2[a2.keyBinding] = () => e2.executeCommand(t3);
48
+ }
49
+ Object.keys(i2).length > 0 && e2.registerKeymap(i2);
50
+ }
51
+ registerDisabledToolbarItems(e2) {
52
+ if (this.config.toolbar) for (const t2 of l) {
53
+ const i2 = this.config[t2.configKey], a2 = this.config.toolbar[t2.configKey] ?? true;
54
+ !i2 && a2 && e2.registerToolbarItem({ id: t2.type, group: "format", icon: t2.icon, label: this.getMarkLabel(t2.type), command: c(t2.type), priority: 10 * t2.rank + 10, isEnabled: () => false });
55
+ }
56
+ }
57
+ getMarkLabel(e2) {
58
+ const t2 = `${e2}Label`;
59
+ return this.locale[t2];
60
+ }
61
+ isToolbarVisible(e2) {
62
+ return !this.config.toolbar || (this.config.toolbar[e2] ?? true);
63
+ }
64
+ }
65
+ function c(e2) {
66
+ return `toggle${e2.charAt(0).toUpperCase()}${e2.slice(1)}`;
67
+ }
68
+ export {
69
+ g as T,
70
+ n as a,
71
+ o as b
72
+ };
73
+ //# sourceMappingURL=index-BIL37LSL.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BIL37LSL.mjs","sources":["../../src/plugins/text-formatting/TextFormattingLocale.ts","../../src/plugins/text-formatting/TextFormattingPlugin.ts"],"sourcesContent":["/**\n * Locale interface and default English locale for the TextFormattingPlugin.\n */\n\n// --- Locale Interface ---\n\nexport interface TextFormattingLocale {\n\treadonly boldLabel: string;\n\treadonly italicLabel: string;\n\treadonly underlineLabel: string;\n}\n\n// --- Default English Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_EN: TextFormattingLocale = {\n\tboldLabel: 'Bold',\n\titalicLabel: 'Italic',\n\tunderlineLabel: 'Underline',\n};\n\n// --- German Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_DE: TextFormattingLocale = {\n\tboldLabel: 'Fett',\n\titalicLabel: 'Kursiv',\n\tunderlineLabel: 'Unterstrichen',\n};\n\n// --- Spanish Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_ES: TextFormattingLocale = {\n\tboldLabel: 'Negrita',\n\titalicLabel: 'Cursiva',\n\tunderlineLabel: 'Subrayado',\n};\n\n// --- French Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_FR: TextFormattingLocale = {\n\tboldLabel: 'Gras',\n\titalicLabel: 'Italique',\n\tunderlineLabel: 'Souligné',\n};\n\n// --- Chinese (Simplified) Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_ZH: TextFormattingLocale = {\n\tboldLabel: '粗体',\n\titalicLabel: '斜体',\n\tunderlineLabel: '下划线',\n};\n\n// --- Russian Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_RU: TextFormattingLocale = {\n\tboldLabel: 'Жирный',\n\titalicLabel: 'Курсив',\n\tunderlineLabel: 'Подчёркнутый',\n};\n\n// --- Arabic Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_AR: TextFormattingLocale = {\n\tboldLabel: 'غامق',\n\titalicLabel: 'مائل',\n\tunderlineLabel: 'تحته خط',\n};\n\n// --- Hindi Locale ---\n\nexport const TEXT_FORMATTING_LOCALE_HI: TextFormattingLocale = {\n\tboldLabel: 'बोल्ड',\n\titalicLabel: 'इटैलिक',\n\tunderlineLabel: 'अंडरलाइन',\n};\n\n// --- Locale Map ---\n\nexport const TEXT_FORMATTING_LOCALES: Record<string, TextFormattingLocale> = {\n\ten: TEXT_FORMATTING_LOCALE_EN,\n\tde: TEXT_FORMATTING_LOCALE_DE,\n\tes: TEXT_FORMATTING_LOCALE_ES,\n\tfr: TEXT_FORMATTING_LOCALE_FR,\n\tzh: TEXT_FORMATTING_LOCALE_ZH,\n\tru: TEXT_FORMATTING_LOCALE_RU,\n\tar: TEXT_FORMATTING_LOCALE_AR,\n\thi: TEXT_FORMATTING_LOCALE_HI,\n};\n","/**\n * TextFormattingPlugin: registers inline marks (bold, italic, underline)\n * with their MarkSpecs, toggle commands, keyboard shortcuts, and toolbar items.\n *\n * This plugin is data-driven — each mark type is defined declaratively and\n * all registrations (MarkSpec, command, keymap, toolbar item) are derived\n * from the same definition.\n *\n * Supports two separate config dimensions:\n * - Feature config (bold/italic/underline): controls whether the mark is\n * registered in the schema. When disabled, the keyboard shortcut does nothing.\n * - Toolbar config: controls whether the toolbar button is visible.\n * When a feature is disabled but toolbar is enabled, the button renders as disabled.\n */\n\nimport { isMarkActive, toggleMark } from '../../commands/Commands.js';\nimport { resolvePluginLocale } from '../../i18n/resolvePluginLocale.js';\nimport type { ParseRule } from '../../model/ParseRule.js';\nimport type { SanitizeConfig } from '../../model/SanitizeConfig.js';\nimport { markType as mkType } from '../../model/TypeBrands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\nimport { TEXT_FORMATTING_LOCALES, type TextFormattingLocale } from './TextFormattingLocale.js';\n\n// --- Configuration ---\n\n/** Controls toolbar button visibility per mark. */\nexport interface TextFormattingToolbarConfig {\n\treadonly bold?: boolean;\n\treadonly italic?: boolean;\n\treadonly underline?: boolean;\n}\n\n/** Controls which inline marks are enabled and which toolbar buttons are shown. */\nexport interface TextFormattingConfig {\n\treadonly bold: boolean;\n\treadonly italic: boolean;\n\treadonly underline: boolean;\n\treadonly toolbar?: TextFormattingToolbarConfig;\n\t/** When true, a separator is rendered after the last text-formatting toolbar item. */\n\treadonly separatorAfter?: boolean;\n\treadonly locale?: TextFormattingLocale;\n}\n\nconst DEFAULT_CONFIG: TextFormattingConfig = {\n\tbold: true,\n\titalic: true,\n\tunderline: true,\n};\n\n// --- Mark Definitions ---\n\ninterface MarkDefinition {\n\treadonly type: string;\n\treadonly configKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'separatorAfter' | 'locale'>;\n\treadonly rank: number;\n\treadonly tag: string;\n\treadonly label: string;\n\treadonly icon: string;\n\treadonly keyBinding: string;\n\treadonly toHTMLString: (content: string) => string;\n\treadonly parseHTML: readonly ParseRule[];\n\treadonly sanitize: SanitizeConfig;\n}\n\nconst BOLD_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z\"/></svg>';\nconst ITALIC_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z\"/></svg>';\nconst UNDERLINE_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z\"/></svg>';\n\nconst MARK_DEFINITIONS: readonly MarkDefinition[] = [\n\t{\n\t\ttype: 'bold',\n\t\tconfigKey: 'bold',\n\t\trank: 0,\n\t\ttag: 'strong',\n\t\tlabel: 'Bold',\n\t\ticon: BOLD_ICON,\n\t\tkeyBinding: 'Mod-B',\n\t\ttoHTMLString: (content) => `<strong>${content}</strong>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'strong' },\n\t\t\t{\n\t\t\t\ttag: 'b',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst fw: string = el.style.fontWeight;\n\t\t\t\t\treturn fw === 'normal' || fw === '400' ? false : {};\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\tconst fw: string = el.style.fontWeight;\n\t\t\t\t\tif (!fw) return false;\n\t\t\t\t\tif (fw === 'bold') return {};\n\t\t\t\t\tconst numeric: number = Number.parseInt(fw, 10);\n\t\t\t\t\treturn !Number.isNaN(numeric) && numeric >= 700 ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['strong', 'b'] },\n\t},\n\t{\n\t\ttype: 'italic',\n\t\tconfigKey: 'italic',\n\t\trank: 1,\n\t\ttag: 'em',\n\t\tlabel: 'Italic',\n\t\ticon: ITALIC_ICON,\n\t\tkeyBinding: 'Mod-I',\n\t\ttoHTMLString: (content) => `<em>${content}</em>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'em' },\n\t\t\t{ tag: 'i' },\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\treturn el.style.fontStyle === 'italic' ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['em', 'i'] },\n\t},\n\t{\n\t\ttype: 'underline',\n\t\tconfigKey: 'underline',\n\t\trank: 2,\n\t\ttag: 'u',\n\t\tlabel: 'Underline',\n\t\ticon: UNDERLINE_ICON,\n\t\tkeyBinding: 'Mod-U',\n\t\ttoHTMLString: (content) => `<u>${content}</u>`,\n\t\tparseHTML: [\n\t\t\t{ tag: 'u' },\n\t\t\t{\n\t\t\t\ttag: 'span',\n\t\t\t\tgetAttrs: (el: HTMLElement) => {\n\t\t\t\t\treturn el.style.textDecoration.includes('underline') ? {} : false;\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tsanitize: { tags: ['u'] },\n\t},\n];\n\n// --- Plugin ---\n\nexport class TextFormattingPlugin implements Plugin {\n\treadonly id = 'text-formatting';\n\treadonly name = 'Text Formatting';\n\treadonly priority = 20;\n\n\tprivate readonly config: TextFormattingConfig;\n\tprivate locale!: TextFormattingLocale;\n\n\tconstructor(config?: Partial<TextFormattingConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.locale = resolvePluginLocale(TEXT_FORMATTING_LOCALES, context, this.config.locale);\n\n\t\tconst enabledMarks = MARK_DEFINITIONS.filter((def) => this.config[def.configKey]);\n\n\t\t// Determine which marks will have visible toolbar items\n\t\tconst visibleToolbarMarks = enabledMarks.filter((def) => this.isToolbarVisible(def.configKey));\n\t\tconst lastVisibleMark = visibleToolbarMarks.at(-1);\n\n\t\tfor (const def of enabledMarks) {\n\t\t\tconst isSeparatorTarget = this.config.separatorAfter && def === lastVisibleMark;\n\t\t\tthis.registerMark(context, def, isSeparatorTarget);\n\t\t}\n\n\t\tthis.registerKeymaps(context, enabledMarks);\n\n\t\t// Register disabled placeholder buttons for marks that are disabled\n\t\t// as features but explicitly requested in the toolbar config\n\t\tthis.registerDisabledToolbarItems(context);\n\t}\n\n\tprivate registerMark(\n\t\tcontext: PluginContext,\n\t\tdef: MarkDefinition,\n\t\tseparatorAfter?: boolean,\n\t): void {\n\t\tconst commandName = toCommandName(def.type);\n\t\tconst toolbarVisible = this.isToolbarVisible(def.configKey);\n\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: def.type,\n\t\t\trank: def.rank,\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement(def.tag);\n\t\t\t},\n\t\t\ttoHTMLString: (_mark, content) => def.toHTMLString(content),\n\t\t\tparseHTML: def.parseHTML,\n\t\t\tsanitize: def.sanitize,\n\t\t});\n\n\t\tcontext.registerCommand(commandName, () => {\n\t\t\tconst tr = toggleMark(context.getState(), mkType(def.type));\n\t\t\tif (tr) {\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t});\n\n\t\tif (toolbarVisible) {\n\t\t\tconst label: string = this.getMarkLabel(def.type);\n\t\t\tcontext.registerToolbarItem({\n\t\t\t\tid: def.type,\n\t\t\t\tgroup: 'format',\n\t\t\t\ticon: def.icon,\n\t\t\t\tlabel,\n\t\t\t\ttooltip: `${label} (${formatShortcut(def.keyBinding)})`,\n\t\t\t\tcommand: commandName,\n\t\t\t\tpriority: def.rank * 10 + 10,\n\t\t\t\tseparatorAfter,\n\t\t\t\tisActive: (state) => isMarkActive(state, mkType(def.type)),\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate registerKeymaps(context: PluginContext, marks: readonly MarkDefinition[]): void {\n\t\tconst keymap: Record<string, () => boolean> = {};\n\t\tfor (const def of marks) {\n\t\t\tconst commandName = toCommandName(def.type);\n\t\t\tkeymap[def.keyBinding] = () => context.executeCommand(commandName);\n\t\t}\n\t\tif (Object.keys(keymap).length > 0) {\n\t\t\tcontext.registerKeymap(keymap);\n\t\t}\n\t}\n\n\t/**\n\t * Registers disabled toolbar buttons for marks whose feature is disabled\n\t * but whose toolbar button is explicitly requested.\n\t */\n\tprivate registerDisabledToolbarItems(context: PluginContext): void {\n\t\tif (!this.config.toolbar) return;\n\n\t\tfor (const def of MARK_DEFINITIONS) {\n\t\t\tconst featureEnabled = this.config[def.configKey];\n\t\t\tconst toolbarVisible = this.config.toolbar[def.configKey] ?? true;\n\n\t\t\tif (!featureEnabled && toolbarVisible) {\n\t\t\t\tcontext.registerToolbarItem({\n\t\t\t\t\tid: def.type,\n\t\t\t\t\tgroup: 'format',\n\t\t\t\t\ticon: def.icon,\n\t\t\t\t\tlabel: this.getMarkLabel(def.type),\n\t\t\t\t\tcommand: toCommandName(def.type),\n\t\t\t\t\tpriority: def.rank * 10 + 10,\n\t\t\t\t\tisEnabled: () => false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate getMarkLabel(type: string): string {\n\t\tconst key = `${type}Label` as keyof TextFormattingLocale;\n\t\treturn this.locale[key] as string;\n\t}\n\n\t/** Checks if a toolbar button should be visible for a given mark. */\n\tprivate isToolbarVisible(\n\t\tconfigKey: keyof Omit<TextFormattingConfig, 'toolbar' | 'separatorAfter' | 'locale'>,\n\t): boolean {\n\t\tif (!this.config.toolbar) return true;\n\t\treturn this.config.toolbar[configKey] ?? true;\n\t}\n}\n\n/** Converts a mark type to its toggle command name (e.g. 'bold' → 'toggleBold'). */\nfunction toCommandName(markType: string): string {\n\treturn `toggle${markType.charAt(0).toUpperCase()}${markType.slice(1)}`;\n}\n"],"names":["TEXT_FORMATTING_LOCALE_EN","boldLabel","italicLabel","underlineLabel","TEXT_FORMATTING_LOCALES","en","de","es","fr","zh","ru","ar","hi","DEFAULT_CONFIG","bold","italic","underline","MARK_DEFINITIONS","type","configKey","rank","tag","label","icon","keyBinding","toHTMLString","content","parseHTML","getAttrs","el","fw","style","fontWeight","numeric","Number","parseInt","isNaN","sanitize","tags","fontStyle","textDecoration","includes","TextFormattingPlugin","id","name","priority","config","locale","this","context","resolvePluginLocale","enabledMarks","filter","def","lastVisibleMark","isToolbarVisible","at","isSeparatorTarget","separatorAfter","registerMark","registerKeymaps","registerDisabledToolbarItems","commandName","toCommandName","toolbarVisible","registerMarkSpec","toDOM","document","createElement","_mark","registerCommand","tr","toggleMark","getState","mkType","dispatch","getMarkLabel","registerToolbarItem","group","tooltip","formatShortcut","command","isActive","state","isMarkActive","marks","keymap","executeCommand","Object","keys","length","registerKeymap","toolbar","featureEnabled","isEnabled","key","markType","charAt","toUpperCase","slice"],"mappings":";;;;AAcO,MAAMA,IAAkD,EAC9DC,WAAW,QACXC,aAAa,UACbC,gBAAgB,YAAA,GA6DJC,IAAgE,EAC5EC,IAAIL,GACJM,IA1D8D,EAC9DL,WAAW,QACXC,aAAa,UACbC,gBAAgB,gBAAA,GAwDhBI,IAnD8D,EAC9DN,WAAW,WACXC,aAAa,WACbC,gBAAgB,YAAA,GAiDhBK,IA5C8D,EAC9DP,WAAW,QACXC,aAAa,YACbC,gBAAgB,WAAA,GA0ChBM,IArC8D,EAC9DR,WAAW,MACXC,aAAa,MACbC,gBAAgB,MAAA,GAmChBO,IA9B8D,EAC9DT,WAAW,UACXC,aAAa,UACbC,gBAAgB,eAAA,GA4BhBQ,IAvB8D,EAC9DV,WAAW,QACXC,aAAa,QACbC,gBAAgB,UAAA,GAqBhBS,IAhB8D,EAC9DX,WAAW,SACXC,aAAa,UACbC,gBAAgB,WAAA,EAAA,GC7BXU,IAAuC,EAC5CC,MAAAA,MACAC,QAAAA,MACAC,gBAAW,GAyBNC,IAA8C,CACnD,EACCC,MAAM,QACNC,WAAW,QACXC,MAAM,GACNC,KAAK,UACLC,OAAO,QACPC,MAbD,uTAcCC,YAAY,SACZC,cAAeC,CAAAA,OAAY,WAAWA,EAAAA,aACtCC,WAAW,CACV,EAAEN,KAAK,YACP,EACCA,KAAK,KACLO,UAAWC,CAAAA,OAAAA;AACV,QAAMC,KAAaD,GAAGE,MAAMC;AAC5B,SAAc,aAAPF,MAA0B,UAAPA,MAAuB,CAAA;AAAA,EAAA,GAGnD,EACCT,KAAK,QACLO,UAAWC,CAAAA,OAAAA;AACV,QAAMC,KAAaD,GAAGE,MAAMC;AAC5B,MAAA,CAAKF,GAAI,QAAA;AACT,MAAW,WAAPA,GAAe,QAAO,CAAA;AAC1B,QAAMG,KAAkBC,OAAOC,SAASL,IAAI,EAAA;AAC5C,UAAQI,OAAOE,MAAMH,EAAAA,KAAYA,MAAW,OAAM,CAAA;AAAA,EAAA,CAAA,GAIrDI,UAAU,EAAEC,MAAM,CAAC,UAAU,GAAA,EAAA,EAAA,GAE9B,EACCpB,MAAM,UACNC,WAAW,UACXC,MAAM,GACNC,KAAK,MACLC,OAAO,UACPC,MA1CD,kIA2CCC,YAAY,SACZC,cAAeC,CAAAA,OAAY,OAAOA,EAAAA,SAClCC,WAAW,CACV,EAAEN,KAAK,KAAA,GACP,EAAEA,KAAK,IAAA,GACP,EACCA,KAAK,QACLO,UAAWC,CAAAA,OACoB,aAAvBA,GAAGE,MAAMQ,aAAyB,CAAA,EAAA,CAAA,GAI5CF,UAAU,EAAEC,MAAM,CAAC,MAAM,GAAA,EAAA,EAAA,GAE1B,EACCpB,MAAM,aACNC,WAAW,aACXC,MAAM,GACNC,KAAK,KACLC,OAAO,aACPC,MA7DD,qMA8DCC,YAAY,SACZC,cAAeC,CAAAA,OAAY,MAAMA,EAAAA,QACjCC,WAAW,CACV,EAAEN,KAAK,IAAA,GACP,EACCA,KAAK,QACLO,UAAWC,CAAAA,OAAAA,CAAAA,CACHA,GAAGE,MAAMS,eAAeC,SAAS,WAAA,KAAe,CAAA,EAAA,CAAA,GAI1DJ,UAAU,EAAEC,MAAM,CAAC;AAMd,MAAMI,EAAAA;AAAAA,EACHC,KAAK;AAAA,EACLC,OAAO;AAAA,EACPC,WAAW;AAAA,EAEHC;AAAAA,EACTC;AAAAA,EAER,YAAYD,IAAAA;AACXE,SAAKF,SAAS,EAAA,GAAKjC,GAAAA,GAAmBiC;EACvC;AAAA,EAEA,KAAKG,IAAAA;AACJD,SAAKD,SAASG,EAAoB9C,GAAyB6C,IAASD,KAAKF,OAAOC,MAAAA;AAEhF,UAAMI,KAAelC,EAAiBmC,OAAQC,CAAAA,OAAQL,KAAKF,OAAOO,GAAIlC,SAAAA,CAAAA,GAIhEmC,KADsBH,GAAaC,OAAQC,CAAAA,OAAQL,KAAKO,iBAAiBF,GAAIlC,SAAAA,CAAAA,EACvCqC,GAAAA;AAE5C,eAAWH,MAAOF,IAAc;AAC/B,YAAMM,KAAoBT,KAAKF,OAAOY,kBAAkBL,OAAQC;AAChEN,WAAKW,aAAaV,IAASI,IAAKI,EAAAA;AAAAA,IACjC;AAEAT,SAAKY,gBAAgBX,IAASE,KAI9BH,KAAKa,6BAA6BZ,EAAAA;AAAAA,EACnC;AAAA,EAEQ,aACPA,IACAI,IACAK;AAEA,UAAMI,KAAcC,EAAcV,GAAInC,IAAAA,GAChC8C,KAAiBhB,KAAKO,iBAAiBF,GAAIlC,SAAAA;AAsBjD,QApBA8B,GAAQgB,iBAAiB,EACxB/C,MAAMmC,GAAInC,MACVE,MAAMiC,GAAIjC,MACV8C,OAAA,MACQC,SAASC,cAAcf,GAAIhC,GAAAA,GAEnCI,cAAc,CAAC4C,IAAO3C,OAAY2B,GAAI5B,aAAaC,EAAAA,GACnDC,WAAW0B,GAAI1B,WACfU,UAAUgB,GAAIhB,SAAAA,CAAAA,GAGfY,GAAQqB,gBAAgBR,IAAa,MAAA;AACpC,YAAMS,KAAKC,EAAWvB,GAAQwB,SAAAA,GAAYC,EAAOrB,GAAInC,IAAAA,CAAAA;AACrD,aAAA,CAAA,CAAIqD,OACHtB,GAAQ0B,SAASJ,EAAAA,GAAAA;AAAAA,IACV,CAAA,GAKLP,IAAgB;AACnB,YAAM1C,KAAgB0B,KAAK4B,aAAavB,GAAInC,IAAAA;AAC5C+B,MAAAA,GAAQ4B,oBAAoB,EAC3BlC,IAAIU,GAAInC,MACR4D,OAAO,UACPvD,MAAM8B,GAAI9B,MACVD,OAAAA,IACAyD,SAAS,GAAGzD,OAAU0D,EAAe3B,GAAI7B,UAAAA,CAAAA,KACzCyD,SAASnB,IACTjB,UAAqB,KAAXQ,GAAIjC,OAAY,IAC1BsC,gBAAAA,IACAwB,UAAWC,CAAAA,OAAUC,EAAaD,IAAOT,EAAOrB,GAAInC,IAAAA,CAAAA,EAAAA,CAAAA;AAAAA,IAEtD;AAAA,EACD;AAAA,EAEQ,gBAAgB+B,IAAwBoC,IAAAA;AAC/C,UAAMC,KAAwC,CAAA;AAC9C,eAAWjC,MAAOgC,IAAO;AACxB,YAAMvB,KAAcC,EAAcV,GAAInC,IAAAA;AACtCoE,MAAAA,GAAOjC,GAAI7B,UAAAA,IAAc,MAAMyB,GAAQsC,eAAezB,EAAAA;AAAAA,IACvD;AACI0B,WAAOC,KAAKH,EAAAA,EAAQI,SAAS,KAChCzC,GAAQ0C,eAAeL,EAAAA;AAAAA,EAEzB;AAAA,EAMQ,6BAA6BrC,IAAAA;AACpC,QAAKD,KAAKF,OAAO8C,QAEjB,YAAWvC,MAAOpC,GAAkB;AACnC,YAAM4E,KAAiB7C,KAAKF,OAAOO,GAAIlC,SAAAA,GACjC6C,KAAiBhB,KAAKF,OAAO8C,QAAQvC,GAAIlC,SAAAA,KAAAA;OAE1C0E,MAAkB7B,MACtBf,GAAQ4B,oBAAoB,EAC3BlC,IAAIU,GAAInC,MACR4D,OAAO,UACPvD,MAAM8B,GAAI9B,MACVD,OAAO0B,KAAK4B,aAAavB,GAAInC,IAAAA,GAC7B+D,SAASlB,EAAcV,GAAInC,IAAAA,GAC3B2B,UAAqB,KAAXQ,GAAIjC,OAAY,IAC1B0E,WAAW,MAAA,MAAM,CAAA;AAAA,IAGpB;AAAA,EACD;AAAA,EAEQ,aAAa5E;AACpB,UAAM6E,KAAM,GAAG7E,EAAAA;AACf,WAAO8B,KAAKD,OAAOgD,EAAAA;AAAAA,EACpB;AAAA,EAGQ,iBACP5E,IAAAA;AAEA,WAAA,CAAK6B,KAAKF,OAAO8C,YACV5C,KAAKF,OAAO8C,QAAQzE,EAAAA,KAAAA;AAAAA,EAC5B;AAAA;AAID,SAAS4C,EAAciC,IAAAA;AACtB,SAAO,SAASA,GAASC,OAAO,CAAA,EAAGC,YAAAA,CAAAA,GAAgBF,GAASG,MAAM,CAAA,CAAA;AACnE;"}
@@ -0,0 +1,402 @@
1
+ import { S as e, r as t } from "./resolvePluginLocale-B4w1OkPy.mjs";
2
+ import { e as n } from "./HTMLUtils-0wvCRvJc.mjs";
3
+ import { c as i } from "./NodeSpec-NZVvcCuH.mjs";
4
+ import { i as r, c as o, b as a } from "./Selection-D5ZjXoB7.mjs";
5
+ import { f as s } from "./ToolbarItem-ugDymuXi.mjs";
6
+ import { a as l, c, u as d } from "./Document-CI3iCwEP.mjs";
7
+ import { n as g } from "./TypeBrands-C09nE2qO.mjs";
8
+ function u(e2, t2) {
9
+ const n2 = e2.getState(), i2 = n2.selection, o2 = { src: t2.src, alt: t2.alt ?? "", align: t2.align ?? "center", ...void 0 !== t2.width ? { width: t2.width } : {}, ...void 0 !== t2.height ? { height: t2.height } : {} }, s2 = r(i2) ? i2.nodeId : i2.anchor.blockId, u2 = (function(e3, t3) {
10
+ const n3 = e3.getBlock(t3);
11
+ if ("table_cell" === n3?.type) return t3;
12
+ const i3 = e3.getNodePath(t3);
13
+ if (i3) for (const t4 of i3) {
14
+ const n4 = e3.getBlock(t4);
15
+ if ("table_cell" === n4?.type) return t4;
16
+ }
17
+ })(n2, s2);
18
+ return u2 ? (function(e3, t3, n3, i3) {
19
+ const r2 = e3.getNodePath(n3);
20
+ if (!r2) return false;
21
+ const o3 = c(g("image"), [], void 0, i3), s3 = e3.getBlock(n3);
22
+ if (!s3) return false;
23
+ const u3 = e3.transaction("command"), m2 = d(s3);
24
+ for (let e4 = m2.length - 1; e4 >= 0; e4--) {
25
+ const t4 = s3.children.findIndex((t5) => l(t5) && t5.id === m2[e4]?.id);
26
+ -1 !== t4 && u3.removeNode(r2, t4);
27
+ }
28
+ return u3.insertNode(r2, 0, o3), u3.setSelection(a(o3.id, [...r2, o3.id])), t3.dispatch(u3.build()), true;
29
+ })(n2, e2, u2, o2) : (function(e3, t3, n3, i3) {
30
+ const r2 = e3.doc.children.findIndex((e4) => e4.id === n3);
31
+ if (-1 === r2) return false;
32
+ const o3 = c(g("image"), [], void 0, i3), s3 = c(g("paragraph")), l2 = e3.transaction("command").insertNode([], r2 + 1, o3).insertNode([], r2 + 2, s3).setSelection(a(o3.id, [])).build();
33
+ return t3.dispatch(l2), true;
34
+ })(n2, e2, s2, o2);
35
+ }
36
+ function m(e2, t2, n2) {
37
+ const i2 = e2.getState(), o2 = i2.selection;
38
+ if (!r(o2)) return false;
39
+ const a2 = i2.getBlock(o2.nodeId);
40
+ if (!a2 || "image" !== a2.type) return false;
41
+ const s2 = a2.attrs?.width, l2 = a2.attrs?.height;
42
+ if (void 0 === s2 || void 0 === l2) return false;
43
+ const c2 = l2 > 0 ? s2 / l2 : 1, d2 = Math.max(50, Math.min(n2, s2 + t2)), g2 = Math.round(d2 / c2);
44
+ return (d2 !== s2 || g2 !== l2) && (function(e3, t3) {
45
+ const n3 = e3.getState(), i3 = n3.selection;
46
+ if (!r(i3)) return false;
47
+ const o3 = n3.getBlock(i3.nodeId);
48
+ if (!o3 || "image" !== o3.type) return false;
49
+ const a3 = n3.getNodePath(i3.nodeId);
50
+ if (!a3) return false;
51
+ const s3 = { ...o3.attrs ?? {}, ...t3 }, l3 = n3.transaction("command").setNodeAttr(a3, s3).build();
52
+ return e3.dispatch(l3), true;
53
+ })(e2, { width: d2, height: g2 });
54
+ }
55
+ const p = { insertImage: "Insert Image", insertImageTooltip: "Insert Image", uploadFromComputer: "Upload from computer", uploadAria: "Upload image from computer", separator: "or", urlPlaceholder: "https://...", urlAria: "Image URL", insertButton: "Insert", insertAria: "Insert image", imageAria: (e2, t2, n2) => {
56
+ const i2 = [e2 || "Image"];
57
+ return void 0 !== t2 && void 0 !== n2 && i2.push(`${t2} by ${n2} pixels`), i2.join(", ");
58
+ }, resetToNaturalSize: "Image reset to natural size.", uploadFailed: "Image upload failed." }, h = { en: p, de: { insertImage: "Bild einfügen", insertImageTooltip: "Bild einfügen", uploadFromComputer: "Vom Computer hochladen", uploadAria: "Bild vom Computer hochladen", separator: "oder", urlPlaceholder: "https://...", urlAria: "Bild-URL", insertButton: "Einfügen", insertAria: "Bild einfügen", imageAria: (e2, t2, n2) => {
59
+ const i2 = [e2 || "Bild"];
60
+ return void 0 !== t2 && void 0 !== n2 && i2.push(`${t2} mal ${n2} Pixel`), i2.join(", ");
61
+ }, resetToNaturalSize: "Bild auf Originalgröße zurückgesetzt.", uploadFailed: "Bild-Upload fehlgeschlagen." }, es: { insertImage: "Insertar imagen", insertImageTooltip: "Insertar imagen", uploadFromComputer: "Subir desde el ordenador", uploadAria: "Subir imagen desde el ordenador", separator: "o", urlPlaceholder: "https://...", urlAria: "URL de la imagen", insertButton: "Insertar", insertAria: "Insertar imagen", imageAria: (e2, t2, n2) => {
62
+ const i2 = [e2 || "Imagen"];
63
+ return void 0 !== t2 && void 0 !== n2 && i2.push(`${t2} por ${n2} píxeles`), i2.join(", ");
64
+ }, resetToNaturalSize: "Imagen restablecida a tamaño natural.", uploadFailed: "Error al subir la imagen." }, fr: { insertImage: "Insérer une image", insertImageTooltip: "Insérer une image", uploadFromComputer: "Télécharger depuis l’ordinateur", uploadAria: "Télécharger une image depuis l’ordinateur", separator: "ou", urlPlaceholder: "https://...", urlAria: "URL de l’image", insertButton: "Insérer", insertAria: "Insérer une image", imageAria: (e2, t2, n2) => {
65
+ const i2 = [e2 || "Image"];
66
+ return void 0 !== t2 && void 0 !== n2 && i2.push(`${t2} par ${n2} pixels`), i2.join(", ");
67
+ }, resetToNaturalSize: "Image rétablie à sa taille d’origine.", uploadFailed: "Échec du téléchargement de l’image." }, zh: { insertImage: "插入图片", insertImageTooltip: "插入图片", uploadFromComputer: "从电脑上传", uploadAria: "从电脑上传图片", separator: "或", urlPlaceholder: "https://...", urlAria: "图片链接", insertButton: "插入", insertAria: "插入图片", imageAria: (e2, t2, n2) => {
68
+ const i2 = [e2 || "图片"];
69
+ return void 0 !== t2 && void 0 !== n2 && i2.push(`${t2} x ${n2} 像素`), i2.join(",");
70
+ }, resetToNaturalSize: "图片已恢复原始大小。", uploadFailed: "图片上传失败。" }, ru: { insertImage: "Вставить изображение", insertImageTooltip: "Вставить изображение", uploadFromComputer: "Загрузить с компьютера", uploadAria: "Загрузить изображение с компьютера", separator: "или", urlPlaceholder: "https://...", urlAria: "URL изображения", insertButton: "Вставить", insertAria: "Вставить изображение", imageAria: (e2, t2, n2) => {
71
+ const i2 = [e2 || "Изображение"];
72
+ return void 0 !== t2 && void 0 !== n2 && i2.push(`${t2} на ${n2} пикселей`), i2.join(", ");
73
+ }, resetToNaturalSize: "Изображение сброшено до исходного размера.", uploadFailed: "Ошибка загрузки изображения." }, ar: { insertImage: "إدراج صورة", insertImageTooltip: "إدراج صورة", uploadFromComputer: "رفع من الحاسوب", uploadAria: "رفع صورة من الحاسوب", separator: "أو", urlPlaceholder: "https://...", urlAria: "رابط الصورة", insertButton: "إدراج", insertAria: "إدراج صورة", imageAria: (e2, t2, n2) => {
74
+ const i2 = [e2 || "صورة"];
75
+ return void 0 !== t2 && void 0 !== n2 && i2.push(`${t2} × ${n2} بكسل`), i2.join("، ");
76
+ }, resetToNaturalSize: "تمت إعادة الصورة إلى حجمها الطبيعي.", uploadFailed: "فشل رفع الصورة." }, hi: { insertImage: "चित्र डालें", insertImageTooltip: "चित्र डालें", uploadFromComputer: "कंप्यूटर से अपलोड करें", uploadAria: "कंप्यूटर से चित्र अपलोड करें", separator: "या", urlPlaceholder: "https://...", urlAria: "चित्र URL", insertButton: "डालें", insertAria: "चित्र डालें", imageAria: (e2, t2, n2) => {
77
+ const i2 = [e2 || "चित्र"];
78
+ return void 0 !== t2 && void 0 !== n2 && i2.push(`${t2} x ${n2} पिक्सेल`), i2.join(", ");
79
+ }, resetToNaturalSize: "चित्र मूल आकार में पुनर्स्थापित।", uploadFailed: "चित्र अपलोड विफल।" } }, f = { left: "notectl-image--left", center: "notectl-image--center", right: "notectl-image--right" }, b = { nw: "nwse-resize", ne: "nesw-resize", sw: "nesw-resize", se: "nwse-resize" }, v = { nw: -1, ne: 1, sw: -1, se: 1 }, x = { nw: "Resize top-left", ne: "Resize top-right", sw: "Resize bottom-left", se: "Resize bottom-right" };
80
+ let y = null;
81
+ function I() {
82
+ y && (y.remove(), y = null);
83
+ }
84
+ function z(e2, t2, n2) {
85
+ return (i2, r2, o2) => {
86
+ const a2 = document.createElement("figure");
87
+ a2.className = "notectl-image", a2.setAttribute("data-block-id", i2.id), a2.setAttribute("data-void", "true"), a2.setAttribute("data-selectable", "true");
88
+ const l2 = document.createElement("div");
89
+ l2.className = "notectl-image__container";
90
+ const c2 = document.createElement("img");
91
+ c2.className = "notectl-image__img", c2.draggable = false;
92
+ const d2 = document.createElement("div");
93
+ d2.className = "notectl-image__overlay", l2.appendChild(c2), l2.appendChild(d2), a2.appendChild(l2);
94
+ let g2 = i2.id, u2 = null;
95
+ function m2(e3) {
96
+ const n3 = e3.attrs?.src ?? "", i3 = e3.attrs?.alt ?? "", r3 = e3.attrs?.width, o3 = e3.attrs?.height, s2 = e3.attrs?.align ?? "center";
97
+ c2.src !== n3 && (c2.src = n3), c2.alt = i3, c2.style.width = void 0 !== r3 ? `${r3}px` : "", c2.style.height = void 0 !== o3 ? `${o3}px` : "";
98
+ for (const e4 of Object.values(f)) a2.classList.remove(e4);
99
+ const l3 = f[s2];
100
+ l3 && a2.classList.add(l3);
101
+ const g3 = t2.get(e3.id) ?? "idle", u3 = "uploading" === g3;
102
+ d2.classList.toggle("notectl-image__overlay--uploading", u3), d2.classList.toggle("notectl-image__overlay--error", "error" === g3), d2.textContent = u3 ? "Uploading..." : "error" === g3 ? "Upload failed" : "", u3 ? a2.setAttribute("aria-busy", "true") : a2.removeAttribute("aria-busy"), (function(e4) {
103
+ const t3 = e4.attrs?.alt ?? "", n4 = e4.attrs?.width, i4 = e4.attrs?.height, r4 = [];
104
+ t3 ? r4.push(t3) : r4.push("Image"), void 0 !== n4 && void 0 !== i4 && r4.push(`${n4} by ${i4} pixels`), a2.setAttribute("aria-label", r4.join(", "));
105
+ })(e3);
106
+ }
107
+ m2(i2);
108
+ let p2 = false;
109
+ function h2(t3, n3, i3, s2) {
110
+ let l3 = 0, d3 = 0, g3 = 1;
111
+ const u3 = (t4) => {
112
+ const i4 = t4.clientX - l3, r3 = (o3 = d3 + i4 * v[n3], Math.max(50, Math.min(e2.maxWidth, o3)));
113
+ var o3;
114
+ const a3 = Math.round(r3 / g3);
115
+ c2.style.width = `${r3}px`, c2.style.height = `${a3}px`, s2.textContent = `${Math.round(r3)} × ${a3}`;
116
+ }, m3 = (e3) => {
117
+ document.removeEventListener("pointermove", u3), document.removeEventListener("pointerup", m3), a2.classList.remove("notectl-image--resizing"), s2.classList.remove("notectl-image__size-indicator--visible"), I();
118
+ const t4 = Math.round(c2.getBoundingClientRect().width), n4 = Math.round(t4 / g3);
119
+ !(function(e4, t5, n5) {
120
+ const i4 = r2(), a3 = i4.getBlock(e4);
121
+ if (!a3) return;
122
+ const s3 = a3.attrs?.width, l4 = a3.attrs?.height;
123
+ if (s3 === t5 && l4 === n5) return;
124
+ const c3 = i4.getNodePath(e4);
125
+ if (!c3) return;
126
+ const d4 = { ...a3.attrs ?? {}, width: t5, height: n5 }, g4 = i4.transaction("command").setNodeAttr(c3, d4).build();
127
+ o2(g4);
128
+ })(i3, t4, n4), e3.target?.releasePointerCapture?.(e3.pointerId);
129
+ };
130
+ t3.addEventListener("pointerdown", (e3) => {
131
+ e3.preventDefault(), e3.stopPropagation(), l3 = e3.clientX, d3 = c2.getBoundingClientRect().width;
132
+ const t4 = c2.getBoundingClientRect().height;
133
+ var i4;
134
+ g3 = t4 > 0 ? d3 / t4 : 1, a2.classList.add("notectl-image--resizing"), s2.textContent = `${Math.round(d3)} × ${Math.round(t4)}`, s2.classList.add("notectl-image__size-indicator--visible"), i4 = b[n3], I(), y = document.createElement("style"), y.textContent = `*{cursor:${i4}!important;user-select:none!important}`, document.head.appendChild(y), e3.target.setPointerCapture(e3.pointerId), document.addEventListener("pointermove", u3), document.addEventListener("pointerup", m3);
135
+ });
136
+ }
137
+ function z2() {
138
+ I(), u2 && (u2.remove(), u2 = null);
139
+ }
140
+ return c2.addEventListener("load", () => {
141
+ if (p2) return;
142
+ const t3 = r2(), n3 = t3.getBlock(g2);
143
+ if (!n3 || "image" !== n3.type) return;
144
+ const i3 = void 0 !== n3.attrs?.width, a3 = void 0 !== n3.attrs?.height;
145
+ if (i3 && a3) return void (p2 = true);
146
+ const s2 = c2.naturalWidth, l3 = c2.naturalHeight;
147
+ if (0 === s2 || 0 === l3) return;
148
+ const d3 = Math.min(s2, e2.maxWidth), u3 = s2 > 0 ? l3 / s2 : 1, m3 = Math.round(d3 * u3), h3 = t3.getNodePath(g2);
149
+ if (!h3) return;
150
+ const f2 = { ...n3.attrs ?? {}, width: d3, height: m3 }, b2 = t3.transaction("command").setNodeAttr(h3, f2).build();
151
+ o2(b2), p2 = true;
152
+ }), { dom: a2, contentDOM: null, update: (e3) => "image" === e3.type && (g2 = e3.id, a2.setAttribute("data-block-id", e3.id), m2(e3), true), selectNode() {
153
+ a2.classList.add("notectl-image--selected"), (function(t3) {
154
+ if (!e2.resizable || u2) return;
155
+ u2 = document.createElement("div"), u2.className = "notectl-image__resize-overlay", u2.setAttribute("data-notectl-no-print", "");
156
+ const i3 = document.createElement("div");
157
+ i3.className = "notectl-image__size-indicator", u2.appendChild(i3);
158
+ const r3 = ["nw", "ne", "sw", "se"];
159
+ for (const e3 of r3) {
160
+ const n3 = document.createElement("div");
161
+ n3.className = `notectl-image__resize-handle notectl-image__resize-handle--${e3}`, n3.setAttribute("role", "separator"), n3.setAttribute("aria-label", x[e3]), h2(n3, e3, t3, i3), u2.appendChild(n3);
162
+ }
163
+ if (n2) {
164
+ const e3 = (function(e4) {
165
+ const t4 = e4.shrinkWidth ?? null, n3 = e4.growWidth ?? null;
166
+ return t4 && n3 ? `${s(t4)} / ${s(n3)} to resize` : "";
167
+ })(n2);
168
+ if (e3) {
169
+ const t4 = document.createElement("div");
170
+ t4.className = "notectl-image__keyboard-hint", t4.setAttribute("aria-hidden", "true"), t4.textContent = e3, u2.appendChild(t4);
171
+ }
172
+ }
173
+ l2.appendChild(u2);
174
+ })(g2);
175
+ }, deselectNode() {
176
+ a2.classList.remove("notectl-image--selected"), z2();
177
+ }, destroy() {
178
+ z2();
179
+ } };
180
+ };
181
+ }
182
+ const w = new e("image:upload"), A = { growWidth: "Mod-Shift-ArrowRight", shrinkWidth: "Mod-Shift-ArrowLeft", growWidthLarge: "Mod-Shift-Alt-ArrowRight", shrinkWidthLarge: "Mod-Shift-Alt-ArrowLeft", resetSize: "Mod-Shift-0" }, _ = { maxWidth: 800, maxFileSize: 10485760, acceptedTypes: ["image/png", "image/jpeg", "image/gif", "image/webp", "image/svg+xml"], resizable: true, resizeStep: 10, resizeStepLarge: 50 };
183
+ class S {
184
+ id = "image";
185
+ name = "Image";
186
+ priority = 45;
187
+ config;
188
+ resolvedKeymap;
189
+ uploadStates = /* @__PURE__ */ new Map();
190
+ blobUrls = /* @__PURE__ */ new Set();
191
+ context = null;
192
+ locale;
193
+ constructor(e2) {
194
+ this.config = { ..._, ...e2 }, this.resolvedKeymap = { ...A, ...e2?.keymap };
195
+ }
196
+ init(e2) {
197
+ this.locale = t(h, e2, this.config.locale), e2.registerStyleSheet("\n/* Image */\n.notectl-image {\n margin: 8px 0;\n user-select: none;\n line-height: 0;\n}\n\n.notectl-image--center {\n text-align: center;\n}\n\n.notectl-image--left {\n text-align: left;\n}\n\n.notectl-image--right {\n text-align: right;\n}\n\n.notectl-image__container {\n display: inline-block;\n position: relative;\n line-height: 0;\n}\n\n.notectl-image__img {\n display: block;\n max-width: 100%;\n border-radius: 4px;\n}\n\n.notectl-image--selected .notectl-image__container {\n outline: 2px solid var(--notectl-primary);\n outline-offset: 2px;\n border-radius: 6px;\n}\n\n/* Alignment toolbar (appears on image selection) */\n.notectl-image__align-toolbar {\n display: flex;\n gap: 2px;\n position: absolute;\n top: -36px;\n left: 50%;\n transform: translateX(-50%);\n background: var(--notectl-surface-overlay);\n border: 1px solid var(--notectl-border);\n border-radius: 6px;\n padding: 2px;\n box-shadow: 0 2px 8px var(--notectl-shadow);\n z-index: 10;\n}\n\n.notectl-image__align-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n border: none;\n background: transparent;\n border-radius: 4px;\n cursor: pointer;\n color: var(--notectl-fg);\n}\n\n.notectl-image__align-btn:hover {\n background: var(--notectl-hover-bg);\n}\n\n.notectl-image__align-btn--active {\n background: var(--notectl-active-bg);\n color: var(--notectl-primary-fg);\n}\n\n.notectl-image__align-btn svg {\n width: 16px;\n height: 16px;\n fill: currentColor;\n}\n\n/* Upload overlay */\n.notectl-image__overlay {\n position: absolute;\n inset: 0;\n display: none;\n align-items: center;\n justify-content: center;\n background: rgba(255, 255, 255, 0.8);\n border-radius: 4px;\n font-size: 13px;\n color: var(--notectl-fg-muted);\n}\n\n.notectl-image__overlay--uploading {\n display: flex;\n}\n\n.notectl-image__overlay--error {\n display: flex;\n background: var(--notectl-danger-muted);\n color: var(--notectl-danger);\n}\n\n/* Resize overlay + handles */\n.notectl-image__resize-overlay {\n position: absolute;\n inset: 0;\n pointer-events: none;\n}\n\n.notectl-image__resize-handle {\n position: absolute;\n width: 10px;\n height: 10px;\n background: var(--notectl-bg);\n border: 2px solid var(--notectl-primary);\n border-radius: 50%;\n pointer-events: all;\n z-index: 2;\n transition: transform 0.1s, background 0.1s;\n}\n\n.notectl-image__resize-handle:hover {\n background: var(--notectl-primary);\n transform: scale(1.3);\n}\n\n.notectl-image--resizing .notectl-image__resize-handle {\n background: var(--notectl-primary);\n}\n\n.notectl-image__resize-handle--nw {\n top: -5px;\n left: -5px;\n cursor: nwse-resize;\n}\n\n.notectl-image__resize-handle--ne {\n top: -5px;\n right: -5px;\n cursor: nesw-resize;\n}\n\n.notectl-image__resize-handle--sw {\n bottom: -5px;\n left: -5px;\n cursor: nesw-resize;\n}\n\n.notectl-image__resize-handle--se {\n bottom: -5px;\n right: -5px;\n cursor: nwse-resize;\n}\n\n/* Size indicator tooltip */\n.notectl-image__size-indicator {\n position: absolute;\n bottom: -28px;\n left: 50%;\n transform: translateX(-50%);\n padding: 2px 8px;\n background: var(--notectl-tooltip-bg);\n color: var(--notectl-tooltip-fg);\n font-size: 11px;\n font-weight: 500;\n border-radius: 4px;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity 0.15s;\n z-index: 3;\n}\n\n.notectl-image__size-indicator--visible {\n opacity: 1;\n}\n\n/* Keyboard resize hint (shown on selection, hidden during drag) */\n.notectl-image__keyboard-hint {\n display: none;\n position: absolute;\n bottom: -28px;\n left: 50%;\n transform: translateX(-50%);\n padding: 2px 8px;\n font-size: 11px;\n color: var(--notectl-fg-muted);\n white-space: nowrap;\n pointer-events: none;\n z-index: 3;\n}\n\n.notectl-image--selected .notectl-image__keyboard-hint {\n display: block;\n}\n\n.notectl-image--resizing .notectl-image__keyboard-hint {\n display: none;\n}\n\n/* Resizing feedback */\n.notectl-image--resizing .notectl-image__img {\n opacity: 0.85;\n}\n"), this.context = e2, this.registerNodeSpec(e2), this.registerNodeView(e2), (function(e3) {
198
+ e3.registerCommand("insertImage", () => u(e3, { src: "" })), e3.registerCommand("removeImage", () => (function(e4) {
199
+ const t2 = e4.getState(), n2 = t2.selection;
200
+ if (!r(n2)) return false;
201
+ const i2 = t2.getBlock(n2.nodeId);
202
+ if (!i2 || "image" !== i2.type) return false;
203
+ const a2 = t2.getNodePath(n2.nodeId);
204
+ if (!a2 || 0 === a2.length) return false;
205
+ const s2 = a2.slice(0, -1);
206
+ let c2;
207
+ if (0 === s2.length) c2 = t2.doc;
208
+ else {
209
+ const e5 = s2[s2.length - 1];
210
+ c2 = e5 ? t2.getBlock(e5) : void 0;
211
+ }
212
+ if (!c2) return false;
213
+ const d2 = c2.children.findIndex((e5) => l(e5) && e5.id === n2.nodeId);
214
+ if (-1 === d2) return false;
215
+ const g2 = (function(e5, t3, n3) {
216
+ if (0 === t3.length) {
217
+ const t4 = e5.doc.children, i3 = t4.findIndex((e6) => e6.id === n3), r2 = t4[i3 + 1] ?? t4[i3 - 1];
218
+ return r2?.id;
219
+ }
220
+ return t3[t3.length - 1];
221
+ })(t2, s2, n2.nodeId);
222
+ if (!g2) return false;
223
+ const u2 = t2.transaction("command").removeNode(s2, d2).setSelection(o(g2, 0)).build();
224
+ return e4.dispatch(u2), true;
225
+ })(e3));
226
+ })(e2), this.registerResizeCommands(e2), this.registerResizeKeymaps(e2), this.registerFileHandler(e2), this.registerToolbarItem(e2);
227
+ }
228
+ destroy() {
229
+ for (const e2 of this.blobUrls) URL.revokeObjectURL(e2);
230
+ this.blobUrls.clear(), this.uploadStates.clear(), this.context = null;
231
+ }
232
+ onStateChange(e2, t2, n2) {
233
+ if (!this.context) return;
234
+ for (const e3 of this.uploadStates.keys()) t2.getBlock(e3) || this.uploadStates.delete(e3);
235
+ const i2 = this.isImageSelected(e2), r2 = this.isImageSelected(t2);
236
+ !i2 && r2 && this.announceImageSelection(t2);
237
+ }
238
+ registerNodeSpec(e2) {
239
+ const t2 = this.locale;
240
+ e2.registerNodeSpec({ type: "image", group: "block", isVoid: true, selectable: true, attrs: { src: { default: "" }, alt: { default: "" }, align: { default: "center" } }, toDOM(e3) {
241
+ const n2 = i("figure", e3.id);
242
+ n2.className = "notectl-image", n2.setAttribute("data-void", "true"), n2.setAttribute("data-selectable", "true");
243
+ const r2 = document.createElement("div");
244
+ r2.className = "notectl-image__container";
245
+ const o2 = e3.attrs?.alt ?? "", a2 = e3.attrs?.width, s2 = e3.attrs?.height, l2 = document.createElement("img");
246
+ l2.className = "notectl-image__img", l2.src = e3.attrs?.src ?? "", l2.alt = o2, l2.draggable = false, void 0 !== a2 && (l2.style.width = `${a2}px`), void 0 !== s2 && (l2.style.height = `${s2}px`);
247
+ const c2 = { left: "notectl-image--left", center: "notectl-image--center", right: "notectl-image--right" }[e3.attrs?.align ?? "center"];
248
+ return c2 && n2.classList.add(c2), n2.setAttribute("aria-label", t2.imageAria(o2, a2, s2)), r2.appendChild(l2), n2.appendChild(r2), n2;
249
+ }, toHTML(e3) {
250
+ const t3 = n(e3.attrs?.src ?? ""), i2 = n(e3.attrs?.alt ?? ""), r2 = e3.attrs?.width, o2 = e3.attrs?.height, a2 = e3.attrs?.align ?? "center", s2 = (void 0 !== r2 ? ` width="${r2}"` : "") + (void 0 !== o2 ? ` height="${o2}"` : "");
251
+ return `<figure class="notectl-image notectl-image--${n(a2)}"><img src="${t3}" alt="${i2}"${s2}></figure>`;
252
+ }, parseHTML: [{ tag: "figure", getAttrs(e3) {
253
+ const t3 = e3.querySelector("img");
254
+ if (!t3) return false;
255
+ const n2 = { src: t3.getAttribute("src") ?? "", alt: t3.getAttribute("alt") ?? "", align: "center" }, i2 = t3.getAttribute("width"), r2 = t3.getAttribute("height");
256
+ return i2 && (n2.width = Number.parseInt(i2, 10)), r2 && (n2.height = Number.parseInt(r2, 10)), e3.classList.contains("notectl-image--left") && (n2.align = "left"), e3.classList.contains("notectl-image--right") && (n2.align = "right"), n2;
257
+ } }, { tag: "img", getAttrs(e3) {
258
+ const t3 = { src: e3.getAttribute("src") ?? "", alt: e3.getAttribute("alt") ?? "", align: "center" }, n2 = e3.getAttribute("width"), i2 = e3.getAttribute("height");
259
+ return n2 && (t3.width = Number.parseInt(n2, 10)), i2 && (t3.height = Number.parseInt(i2, 10)), t3;
260
+ } }], sanitize: { tags: ["figure", "img"], attrs: ["src", "alt", "width", "height", "class"] } });
261
+ }
262
+ registerNodeView(e2) {
263
+ e2.registerNodeView("image", z(this.config, this.uploadStates, this.resolvedKeymap));
264
+ }
265
+ registerResizeCommands(e2) {
266
+ const t2 = this.config.resizeStep ?? 10, n2 = this.config.resizeStepLarge ?? 50, i2 = this.config.maxWidth;
267
+ e2.registerCommand("resizeImageGrow", () => {
268
+ const n3 = m(e2, t2, i2);
269
+ return n3 && this.announceCurrentSize(e2), n3;
270
+ }), e2.registerCommand("resizeImageShrink", () => {
271
+ const n3 = m(e2, -t2, i2);
272
+ return n3 && this.announceCurrentSize(e2), n3;
273
+ }), e2.registerCommand("resizeImageGrowLarge", () => {
274
+ const t3 = m(e2, n2, i2);
275
+ return t3 && this.announceCurrentSize(e2), t3;
276
+ }), e2.registerCommand("resizeImageShrinkLarge", () => {
277
+ const t3 = m(e2, -n2, i2);
278
+ return t3 && this.announceCurrentSize(e2), t3;
279
+ }), e2.registerCommand("resetImageSize", () => {
280
+ const t3 = (function(e3) {
281
+ const t4 = e3.getState(), n3 = t4.selection;
282
+ if (!r(n3)) return false;
283
+ const i3 = t4.getBlock(n3.nodeId);
284
+ if (!i3 || "image" !== i3.type) return false;
285
+ const o2 = t4.getNodePath(n3.nodeId);
286
+ if (!o2) return false;
287
+ const a2 = { ...i3.attrs ?? {} }, s2 = Object.fromEntries(Object.entries(a2).filter(([e4]) => "width" !== e4 && "height" !== e4)), l2 = t4.transaction("command").setNodeAttr(o2, s2).build();
288
+ return e3.dispatch(l2), true;
289
+ })(e2);
290
+ return t3 && e2.announce(this.locale.resetToNaturalSize), t3;
291
+ });
292
+ }
293
+ registerResizeKeymaps(e2) {
294
+ const t2 = {}, n2 = { growWidth: "resizeImageGrow", shrinkWidth: "resizeImageShrink", growWidthLarge: "resizeImageGrowLarge", shrinkWidthLarge: "resizeImageShrinkLarge", resetSize: "resetImageSize" };
295
+ for (const [i2, r2] of Object.entries(n2)) {
296
+ const n3 = this.resolvedKeymap[i2] ?? null;
297
+ n3 && (t2[n3] = () => e2.executeCommand(r2));
298
+ }
299
+ Object.keys(t2).length > 0 && e2.registerKeymap(t2);
300
+ }
301
+ registerFileHandler(e2) {
302
+ e2.registerFileHandler("image/*", async (t2, n2) => !!this.isAcceptedType(t2.type) && (this.handleFileInsert(e2, t2), true));
303
+ }
304
+ handleFileInsert(e2, t2) {
305
+ if (t2.size > this.config.maxFileSize) return;
306
+ const n2 = URL.createObjectURL(t2);
307
+ if (this.blobUrls.add(n2), !u(e2, { src: n2 })) return URL.revokeObjectURL(n2), void this.blobUrls.delete(n2);
308
+ const i2 = e2.getState().selection;
309
+ if (!r(i2)) return;
310
+ const o2 = i2.nodeId;
311
+ this.uploadStates.set(o2, "uploading"), e2.getService(w) ? this.uploadFile(e2, t2, o2, n2) : this.uploadStates.set(o2, "complete");
312
+ }
313
+ async uploadFile(e2, t2, n2, i2) {
314
+ const r2 = e2.getService(w);
315
+ if (r2) try {
316
+ const o2 = await r2.upload(t2);
317
+ this.uploadStates.set(n2, "complete");
318
+ const a2 = e2.getState(), s2 = a2.getBlock(n2);
319
+ if (!s2) return;
320
+ const l2 = a2.getNodePath(n2);
321
+ if (!l2) return;
322
+ const c2 = { ...s2.attrs ?? {}, src: o2.url, ...void 0 !== o2.width ? { width: o2.width } : {}, ...void 0 !== o2.height ? { height: o2.height } : {} }, d2 = a2.transaction("command").setNodeAttr(l2, c2).build();
323
+ e2.dispatch(d2), URL.revokeObjectURL(i2), this.blobUrls.delete(i2);
324
+ } catch {
325
+ this.uploadStates.set(n2, "error"), e2.announce(this.locale.uploadFailed);
326
+ }
327
+ }
328
+ registerToolbarItem(e2) {
329
+ e2.registerToolbarItem({ id: "image", group: "insert", icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></svg>', label: this.locale.insertImage, tooltip: this.locale.insertImageTooltip, command: "insertImage", priority: 50, popupType: "custom", separatorAfter: this.config.separatorAfter, renderPopup: (e3, t2, n2) => {
330
+ this.renderImagePopup(e3, t2, n2);
331
+ } });
332
+ }
333
+ renderImagePopup(e2, t2, n2) {
334
+ e2.style.padding = "8px", e2.style.minWidth = "240px";
335
+ const i2 = document.createElement("input");
336
+ i2.type = "file", i2.accept = this.config.acceptedTypes.join(","), i2.style.cssText = "position:absolute;width:0;height:0;overflow:hidden;opacity:0;";
337
+ const r2 = document.createElement("button");
338
+ r2.type = "button", r2.textContent = this.locale.uploadFromComputer, r2.setAttribute("aria-label", this.locale.uploadAria), r2.style.cssText = "display:block;width:100%;padding:8px 12px;cursor:pointer;text-align:center;box-sizing:border-box;border:1px solid var(--notectl-border);border-radius:4px;background:var(--notectl-surface-raised);color:var(--notectl-fg);", r2.addEventListener("mousedown", (e3) => {
339
+ e3.preventDefault(), e3.stopPropagation(), i2.click();
340
+ }), i2.addEventListener("change", () => {
341
+ const e3 = i2.files?.[0];
342
+ e3 && (this.handleFileInsert(t2, e3), n2(), t2.getContainer().focus());
343
+ }), e2.appendChild(i2), e2.appendChild(r2);
344
+ const o2 = document.createElement("div");
345
+ o2.style.cssText = "display:flex;align-items:center;margin:8px 0;color:var(--notectl-fg-muted);font-size:12px;";
346
+ const a2 = document.createElement("span");
347
+ a2.style.cssText = "flex:1;height:1px;background:var(--notectl-border);";
348
+ const s2 = document.createElement("span");
349
+ s2.textContent = this.locale.separator, s2.style.cssText = "padding:0 8px;";
350
+ const l2 = document.createElement("span");
351
+ l2.style.cssText = "flex:1;height:1px;background:var(--notectl-border);", o2.appendChild(a2), o2.appendChild(s2), o2.appendChild(l2), e2.appendChild(o2);
352
+ const c2 = document.createElement("input");
353
+ c2.type = "url", c2.placeholder = this.locale.urlPlaceholder, c2.setAttribute("aria-label", this.locale.urlAria), c2.style.cssText = "width:100%;padding:6px 8px;box-sizing:border-box;border:1px solid var(--notectl-border);border-radius:4px;background:var(--notectl-bg);color:var(--notectl-fg);";
354
+ const d2 = document.createElement("button");
355
+ d2.type = "button", d2.textContent = this.locale.insertButton, d2.setAttribute("aria-label", this.locale.insertAria), d2.style.cssText = "width:100%;padding:8px 12px;margin-top:4px;cursor:pointer;border:1px solid var(--notectl-border);border-radius:4px;background:var(--notectl-surface-raised);color:var(--notectl-fg);";
356
+ const g2 = () => {
357
+ const e3 = c2.value.trim();
358
+ e3 && (u(t2, { src: e3 }), n2(), t2.getContainer().focus());
359
+ };
360
+ d2.addEventListener("mousedown", (e3) => {
361
+ e3.preventDefault(), e3.stopPropagation(), g2();
362
+ }), c2.addEventListener("keydown", (e3) => {
363
+ "Enter" === e3.key && (e3.preventDefault(), g2());
364
+ }), e2.appendChild(c2), e2.appendChild(d2), requestAnimationFrame(() => c2.focus());
365
+ }
366
+ isAcceptedType(e2) {
367
+ return this.config.acceptedTypes.some((t2) => t2 === e2 || t2.endsWith("/*") && e2.startsWith(t2.slice(0, -1)));
368
+ }
369
+ isImageSelected(e2) {
370
+ const t2 = e2.selection;
371
+ if (!r(t2)) return false;
372
+ const n2 = e2.getBlock(t2.nodeId);
373
+ return "image" === n2?.type;
374
+ }
375
+ announceImageSelection(e2) {
376
+ if (!this.context) return;
377
+ const t2 = e2.selection;
378
+ if (!r(t2)) return;
379
+ const n2 = e2.getBlock(t2.nodeId);
380
+ if (!n2 || "image" !== n2.type) return;
381
+ const i2 = n2.attrs?.alt ?? "", o2 = n2.attrs?.width, a2 = n2.attrs?.height, l2 = ["Image selected."];
382
+ i2 && l2.push(`Alt text: ${i2}.`), void 0 !== o2 && void 0 !== a2 && l2.push(`Size: ${o2} by ${a2} pixels.`);
383
+ const c2 = this.resolvedKeymap.shrinkWidth ?? null, d2 = this.resolvedKeymap.growWidth ?? null;
384
+ c2 && d2 && l2.push(`${s(c2)} / ${s(d2)} to resize.`), this.context.announce(l2.join(" "));
385
+ }
386
+ announceCurrentSize(e2) {
387
+ const t2 = e2.getState(), n2 = t2.selection;
388
+ if (!r(n2)) return;
389
+ const i2 = t2.getBlock(n2.nodeId);
390
+ if (!i2 || "image" !== i2.type) return;
391
+ const o2 = i2.attrs?.width, a2 = i2.attrs?.height;
392
+ void 0 !== o2 && void 0 !== a2 && e2.announce(`Image resized to ${o2} by ${a2} pixels.`);
393
+ }
394
+ }
395
+ export {
396
+ A as D,
397
+ h as I,
398
+ p as a,
399
+ w as b,
400
+ S as c
401
+ };
402
+ //# sourceMappingURL=index-BL56fbXt.mjs.map