@notectl/core 1.7.1 → 1.7.3

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 (182) hide show
  1. package/dist/chunks/{AttrRegistry-Ci0qAvtS.mjs → AttrRegistry-D9Jx_RVb.mjs} +2 -2
  2. package/dist/chunks/{AttrRegistry-Ci0qAvtS.mjs.map → AttrRegistry-D9Jx_RVb.mjs.map} +1 -1
  3. package/dist/chunks/AttributedMarkCommands-BtLea72z.mjs +80 -0
  4. package/dist/chunks/AttributedMarkCommands-BtLea72z.mjs.map +1 -0
  5. package/dist/chunks/{CaretNavigation-qLfeL0So.mjs → CaretNavigation-7JYpIKbs.mjs} +3 -3
  6. package/dist/chunks/{CaretNavigation-qLfeL0So.mjs.map → CaretNavigation-7JYpIKbs.mjs.map} +1 -1
  7. package/dist/chunks/{ColorGrid-BBkN0AOb.mjs → ColorGrid--lBQ7jCK.mjs} +56 -55
  8. package/dist/chunks/ColorGrid--lBQ7jCK.mjs.map +1 -0
  9. package/dist/chunks/{ColorPickerPopup-D3ysvOH-.mjs → ColorPickerPopup-TpIRlXc8.mjs} +15 -15
  10. package/dist/chunks/ColorPickerPopup-TpIRlXc8.mjs.map +1 -0
  11. package/dist/chunks/{Document-DfZ1NOjs.mjs → Document-Brtw2jL1.mjs} +6 -6
  12. package/dist/chunks/Document-Brtw2jL1.mjs.map +1 -0
  13. package/dist/chunks/{MarkCommands-uybmkw9l.mjs → MarkCommands-6RUJ4L3r.mjs} +3 -3
  14. package/dist/chunks/MarkCommands-6RUJ4L3r.mjs.map +1 -0
  15. package/dist/chunks/{NodeResolver-CzLmmrph.mjs → NodeResolver-C2XYkeOi.mjs} +2 -2
  16. package/dist/chunks/{NodeResolver-CzLmmrph.mjs.map → NodeResolver-C2XYkeOi.mjs.map} +1 -1
  17. package/dist/chunks/NodeSpec-NZVvcCuH.mjs.map +1 -1
  18. package/dist/chunks/PopupPositioning-CgjgAKjp.mjs +34 -0
  19. package/dist/chunks/PopupPositioning-CgjgAKjp.mjs.map +1 -0
  20. package/dist/chunks/RangeIterator-Bh4Vl_6D.mjs +16 -0
  21. package/dist/chunks/{RangeIterator-Bye0UtbY.mjs.map → RangeIterator-Bh4Vl_6D.mjs.map} +1 -1
  22. package/dist/chunks/StyleRuntime-CP4NCwKT.mjs +235 -0
  23. package/dist/chunks/StyleRuntime-CP4NCwKT.mjs.map +1 -0
  24. package/dist/chunks/ToolbarItem-BpZggUGo.mjs.map +1 -1
  25. package/dist/chunks/{index-Bt_d4IqB.mjs → index--7pBhSF4.mjs} +74 -73
  26. package/dist/chunks/index--7pBhSF4.mjs.map +1 -0
  27. package/dist/chunks/{index-DayTn6Re.mjs → index-BXCkjDax.mjs} +78 -83
  28. package/dist/chunks/index-BXCkjDax.mjs.map +1 -0
  29. package/dist/chunks/{index-DGKQhSAl.mjs → index-BXtw5PNN.mjs} +2 -2
  30. package/dist/chunks/{index-DGKQhSAl.mjs.map → index-BXtw5PNN.mjs.map} +1 -1
  31. package/dist/chunks/{ToolbarPlugin-B7oJRzpl.mjs → index-BcDRT4K2.mjs} +110 -121
  32. package/dist/chunks/index-BcDRT4K2.mjs.map +1 -0
  33. package/dist/chunks/{index-DoCvDkfj.mjs → index-BjFBWBOC.mjs} +23 -25
  34. package/dist/chunks/index-BjFBWBOC.mjs.map +1 -0
  35. package/dist/chunks/{index-CrKz_IEn.mjs → index-C1opJocO.mjs} +2 -2
  36. package/dist/chunks/{index-CrKz_IEn.mjs.map → index-C1opJocO.mjs.map} +1 -1
  37. package/dist/chunks/{index-CfyS_pgH.mjs → index-CCyqQ0Dz.mjs} +32 -31
  38. package/dist/chunks/index-CCyqQ0Dz.mjs.map +1 -0
  39. package/dist/chunks/{index-E7OgN7hM.mjs → index-Cd3uJLP3.mjs} +2 -2
  40. package/dist/chunks/{index-E7OgN7hM.mjs.map → index-Cd3uJLP3.mjs.map} +1 -1
  41. package/dist/chunks/{index-yhz2qeeh.mjs → index-DSAuGP4n.mjs} +131 -127
  42. package/dist/chunks/index-DSAuGP4n.mjs.map +1 -0
  43. package/dist/chunks/{index-CH1r7DL-.mjs → index-DtRfqsq5.mjs} +211 -210
  44. package/dist/chunks/index-DtRfqsq5.mjs.map +1 -0
  45. package/dist/chunks/{index-CFPP456m.mjs → index-DxbQirny.mjs} +8 -8
  46. package/dist/chunks/{index-CFPP456m.mjs.map → index-DxbQirny.mjs.map} +1 -1
  47. package/dist/chunks/{index-DuRNETFv.mjs → index-ErZ5_a1o.mjs} +3 -3
  48. package/dist/chunks/{index-DuRNETFv.mjs.map → index-ErZ5_a1o.mjs.map} +1 -1
  49. package/dist/chunks/{index-Deag_lVi.mjs → index-WpbK_s_H.mjs} +29 -31
  50. package/dist/chunks/index-WpbK_s_H.mjs.map +1 -0
  51. package/dist/chunks/{index-DIvHQtE2.mjs → index-WrqH1wG8.mjs} +15 -14
  52. package/dist/chunks/index-WrqH1wG8.mjs.map +1 -0
  53. package/dist/chunks/{index-Dy6SllXW.mjs → index-fsVJLutn.mjs} +3 -3
  54. package/dist/chunks/{index-Dy6SllXW.mjs.map → index-fsVJLutn.mjs.map} +1 -1
  55. package/dist/chunks/{index-Ckzqtn5D.mjs → index-fx3KIap3.mjs} +15 -14
  56. package/dist/chunks/index-fx3KIap3.mjs.map +1 -0
  57. package/dist/chunks/{index-DmuuFS5D.mjs → index-oOJo-ywB.mjs} +4 -4
  58. package/dist/chunks/{index-DmuuFS5D.mjs.map → index-oOJo-ywB.mjs.map} +1 -1
  59. package/dist/chunks/{index-CFJFD4lF.mjs → index-toj88jtL.mjs} +19 -18
  60. package/dist/chunks/index-toj88jtL.mjs.map +1 -0
  61. package/dist/commands/AttributedMarkCommands.d.ts.map +1 -1
  62. package/dist/commands/MarkCommands.d.ts +3 -3
  63. package/dist/commands/MarkCommands.d.ts.map +1 -1
  64. package/dist/editor/CSSClassCollector.d.ts +36 -0
  65. package/dist/editor/CSSClassCollector.d.ts.map +1 -0
  66. package/dist/editor/ContentHTMLTypes.d.ts +29 -0
  67. package/dist/editor/ContentHTMLTypes.d.ts.map +1 -0
  68. package/dist/editor/ContentStyleInjector.d.ts +69 -0
  69. package/dist/editor/ContentStyleInjector.d.ts.map +1 -0
  70. package/dist/editor/DocumentParser.d.ts +9 -1
  71. package/dist/editor/DocumentParser.d.ts.map +1 -1
  72. package/dist/editor/DocumentSerializer.d.ts +6 -0
  73. package/dist/editor/DocumentSerializer.d.ts.map +1 -1
  74. package/dist/editor/EditorThemeController.d.ts +3 -0
  75. package/dist/editor/EditorThemeController.d.ts.map +1 -1
  76. package/dist/editor/MarkSerializer.d.ts +7 -0
  77. package/dist/editor/MarkSerializer.d.ts.map +1 -1
  78. package/dist/editor/NotectlEditor.d.ts +13 -3
  79. package/dist/editor/NotectlEditor.d.ts.map +1 -1
  80. package/dist/editor/PaperLayoutController.d.ts.map +1 -1
  81. package/dist/editor/styles/font-select.d.ts +1 -1
  82. package/dist/editor/styles/font-select.d.ts.map +1 -1
  83. package/dist/editor/styles/font-size-select.d.ts +1 -1
  84. package/dist/editor/styles/font-size-select.d.ts.map +1 -1
  85. package/dist/editor/styles/heading-select.d.ts +1 -1
  86. package/dist/editor/styles/heading-select.d.ts.map +1 -1
  87. package/dist/editor/styles/toolbar.d.ts +1 -1
  88. package/dist/editor/styles/toolbar.d.ts.map +1 -1
  89. package/dist/index.d.ts +10 -12
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/input/LegacyHTMLNormalizer.d.ts.map +1 -1
  92. package/dist/model/Document.d.ts +0 -4
  93. package/dist/model/Document.d.ts.map +1 -1
  94. package/dist/model/NodeSpec.d.ts +19 -2
  95. package/dist/model/NodeSpec.d.ts.map +1 -1
  96. package/dist/notectl-core.mjs +613 -477
  97. package/dist/notectl-core.mjs.map +1 -1
  98. package/dist/notectl-core.umd.js +1571 -1225
  99. package/dist/notectl-core.umd.js.map +1 -1
  100. package/dist/plugins/alignment/AlignmentPlugin.d.ts.map +1 -1
  101. package/dist/plugins/alignment.mjs +1 -1
  102. package/dist/plugins/caret-navigation.mjs +1 -1
  103. package/dist/plugins/code-block/CodeBlockNodeView.d.ts.map +1 -1
  104. package/dist/plugins/code-block/CodeBlockPlugin.d.ts +0 -1
  105. package/dist/plugins/code-block/CodeBlockPlugin.d.ts.map +1 -1
  106. package/dist/plugins/code-block/index.d.ts +2 -1
  107. package/dist/plugins/code-block/index.d.ts.map +1 -1
  108. package/dist/plugins/code-block.mjs +1 -1
  109. package/dist/plugins/font/FontPlugin.d.ts +0 -1
  110. package/dist/plugins/font/FontPlugin.d.ts.map +1 -1
  111. package/dist/plugins/font-size/FontSizePlugin.d.ts +0 -2
  112. package/dist/plugins/font-size/FontSizePlugin.d.ts.map +1 -1
  113. package/dist/plugins/font-size/FontSizePopup.d.ts +3 -1
  114. package/dist/plugins/font-size/FontSizePopup.d.ts.map +1 -1
  115. package/dist/plugins/font-size.mjs +1 -1
  116. package/dist/plugins/font.mjs +1 -1
  117. package/dist/plugins/gap-cursor.mjs +6 -6
  118. package/dist/plugins/hard-break.mjs +1 -1
  119. package/dist/plugins/heading/HeadingBlockTypePicker.d.ts.map +1 -1
  120. package/dist/plugins/heading.mjs +1 -1
  121. package/dist/plugins/highlight/HighlightPlugin.d.ts.map +1 -1
  122. package/dist/plugins/highlight.mjs +1 -1
  123. package/dist/plugins/horizontal-rule.mjs +1 -1
  124. package/dist/plugins/image/ImageNodeView.d.ts.map +1 -1
  125. package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
  126. package/dist/plugins/image.mjs +1 -1
  127. package/dist/plugins/link.mjs +1 -1
  128. package/dist/plugins/list/ListPlugin.d.ts.map +1 -1
  129. package/dist/plugins/list.mjs +1 -1
  130. package/dist/plugins/print/PrintContentPreparer.d.ts.map +1 -1
  131. package/dist/plugins/shared/ColorGrid.d.ts.map +1 -1
  132. package/dist/plugins/shared/ColorPickerPopup.d.ts +2 -1
  133. package/dist/plugins/shared/ColorPickerPopup.d.ts.map +1 -1
  134. package/dist/plugins/shared/PopupManager.d.ts +12 -2
  135. package/dist/plugins/shared/PopupManager.d.ts.map +1 -1
  136. package/dist/plugins/shared/PopupPositioning.d.ts.map +1 -1
  137. package/dist/plugins/strikethrough.mjs +1 -1
  138. package/dist/plugins/super-sub.mjs +1 -1
  139. package/dist/plugins/table/TableContextMenu.d.ts.map +1 -1
  140. package/dist/plugins/table/TableControls.d.ts.map +1 -1
  141. package/dist/plugins/table/TableControlsDOM.d.ts.map +1 -1
  142. package/dist/plugins/table/TableControlsLayout.d.ts.map +1 -1
  143. package/dist/plugins/table/TableNodeViews.d.ts.map +1 -1
  144. package/dist/plugins/table/TablePlugin.d.ts.map +1 -1
  145. package/dist/plugins/table.mjs +1 -1
  146. package/dist/plugins/text-color/TextColorPlugin.d.ts.map +1 -1
  147. package/dist/plugins/text-color.mjs +1 -1
  148. package/dist/plugins/text-formatting.mjs +1 -1
  149. package/dist/plugins/toolbar/ToolbarItem.d.ts +3 -2
  150. package/dist/plugins/toolbar/ToolbarItem.d.ts.map +1 -1
  151. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts.map +1 -1
  152. package/dist/plugins/toolbar/ToolbarPopupController.d.ts +0 -3
  153. package/dist/plugins/toolbar/ToolbarPopupController.d.ts.map +1 -1
  154. package/dist/plugins/toolbar/ToolbarRenderers.d.ts.map +1 -1
  155. package/dist/plugins/toolbar/ToolbarTooltip.d.ts.map +1 -1
  156. package/dist/plugins/toolbar.mjs +2 -2
  157. package/dist/presets/PresetTypes.d.ts +1 -1
  158. package/dist/presets/PresetTypes.d.ts.map +1 -1
  159. package/dist/style/StyleRuntime.d.ts +34 -0
  160. package/dist/style/StyleRuntime.d.ts.map +1 -0
  161. package/dist/view/Reconciler.d.ts.map +1 -1
  162. package/package.json +1 -1
  163. package/dist/chunks/AttributedMarkCommands-BETuHXj8.mjs +0 -58
  164. package/dist/chunks/AttributedMarkCommands-BETuHXj8.mjs.map +0 -1
  165. package/dist/chunks/ColorGrid-BBkN0AOb.mjs.map +0 -1
  166. package/dist/chunks/ColorPickerPopup-D3ysvOH-.mjs.map +0 -1
  167. package/dist/chunks/Document-DfZ1NOjs.mjs.map +0 -1
  168. package/dist/chunks/MarkCommands-uybmkw9l.mjs.map +0 -1
  169. package/dist/chunks/PopupPositioning-Cn6L_mO2.mjs +0 -30
  170. package/dist/chunks/PopupPositioning-Cn6L_mO2.mjs.map +0 -1
  171. package/dist/chunks/RangeIterator-Bye0UtbY.mjs +0 -16
  172. package/dist/chunks/ToolbarPlugin-B7oJRzpl.mjs.map +0 -1
  173. package/dist/chunks/index-Bt_d4IqB.mjs.map +0 -1
  174. package/dist/chunks/index-CFJFD4lF.mjs.map +0 -1
  175. package/dist/chunks/index-CH1r7DL-.mjs.map +0 -1
  176. package/dist/chunks/index-CfyS_pgH.mjs.map +0 -1
  177. package/dist/chunks/index-Ckzqtn5D.mjs.map +0 -1
  178. package/dist/chunks/index-DIvHQtE2.mjs.map +0 -1
  179. package/dist/chunks/index-DayTn6Re.mjs.map +0 -1
  180. package/dist/chunks/index-Deag_lVi.mjs.map +0 -1
  181. package/dist/chunks/index-DoCvDkfj.mjs.map +0 -1
  182. package/dist/chunks/index-yhz2qeeh.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index-CFPP456m.mjs","sources":["../../src/plugins/horizontal-rule/HorizontalRuleLocale.ts","../../src/plugins/horizontal-rule/HorizontalRulePlugin.ts"],"sourcesContent":["/** Locale interface and default English locale for the HorizontalRulePlugin. */\n\n// --- Locale Interface ---\n\nexport interface HorizontalRuleLocale {\n\treadonly label: string;\n\treadonly tooltip: (shortcut: string) => string;\n}\n\n// --- Default English Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_EN: HorizontalRuleLocale = {\n\tlabel: 'Horizontal Rule',\n\ttooltip: (shortcut: string) => `Horizontal Rule (${shortcut})`,\n};\n\n// --- German Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_DE: HorizontalRuleLocale = {\n\tlabel: 'Trennlinie',\n\ttooltip: (shortcut: string) => `Trennlinie (${shortcut})`,\n};\n\n// --- Spanish Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_ES: HorizontalRuleLocale = {\n\tlabel: 'Línea horizontal',\n\ttooltip: (shortcut: string) => `Línea horizontal (${shortcut})`,\n};\n\n// --- French Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_FR: HorizontalRuleLocale = {\n\tlabel: 'Ligne horizontale',\n\ttooltip: (shortcut: string) => `Ligne horizontale (${shortcut})`,\n};\n\n// --- Chinese (Simplified) Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_ZH: HorizontalRuleLocale = {\n\tlabel: '分隔线',\n\ttooltip: (shortcut: string) => `分隔线 (${shortcut})`,\n};\n\n// --- Russian Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_RU: HorizontalRuleLocale = {\n\tlabel: 'Горизонтальная линия',\n\ttooltip: (shortcut: string) => `Горизонтальная линия (${shortcut})`,\n};\n\n// --- Arabic Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_AR: HorizontalRuleLocale = {\n\tlabel: 'خط أفقي',\n\ttooltip: (shortcut: string) => `خط أفقي (${shortcut})`,\n};\n\n// --- Hindi Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_HI: HorizontalRuleLocale = {\n\tlabel: 'क्षैतिज रेखा',\n\ttooltip: (shortcut: string) => `क्षैतिज रेखा (${shortcut})`,\n};\n\n// --- Locale Map ---\n\nexport const HORIZONTAL_RULE_LOCALES: Record<string, HorizontalRuleLocale> = {\n\ten: HORIZONTAL_RULE_LOCALE_EN,\n\tde: HORIZONTAL_RULE_LOCALE_DE,\n\tes: HORIZONTAL_RULE_LOCALE_ES,\n\tfr: HORIZONTAL_RULE_LOCALE_FR,\n\tzh: HORIZONTAL_RULE_LOCALE_ZH,\n\tru: HORIZONTAL_RULE_LOCALE_RU,\n\tar: HORIZONTAL_RULE_LOCALE_AR,\n\thi: HORIZONTAL_RULE_LOCALE_HI,\n};\n","/**\n * HorizontalRulePlugin: registers a horizontal rule (divider) void block type\n * with NodeSpec, insert command, input rule, keyboard shortcut, and toolbar button.\n */\n\nimport { resolvePluginLocale } from '../../i18n/resolvePluginLocale.js';\nimport { createBlockNode } from '../../model/Document.js';\nimport { createBlockElement } from '../../model/NodeSpec.js';\nimport {\n\tcreateCollapsedSelection,\n\tisCollapsed,\n\tisGapCursor,\n\tisNodeSelection,\n} from '../../model/Selection.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\nimport { HORIZONTAL_RULE_LOCALES, type HorizontalRuleLocale } from './HorizontalRuleLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\thorizontal_rule: Record<string, never>;\n\t}\n}\n\n// --- Configuration ---\n\nexport interface HorizontalRuleConfig {\n\t/** When true, a separator is rendered after the toolbar item. */\n\treadonly separatorAfter?: boolean;\n\t/** Locale override for user-facing strings. */\n\treadonly locale?: HorizontalRuleLocale;\n}\n\nconst DEFAULT_CONFIG: HorizontalRuleConfig = {};\n\n// --- Helpers ---\n\n/** Finds the index of the cursor's block among top-level document children. */\nfunction findBlockIndexForCursor(state: EditorState): number {\n\tconst sel = state.selection;\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return -1;\n\treturn state.doc.children.findIndex((b) => b.id === sel.anchor.blockId);\n}\n\n// --- Plugin ---\n\nexport class HorizontalRulePlugin implements Plugin {\n\treadonly id = 'horizontal-rule';\n\treadonly name = 'Horizontal Rule';\n\treadonly priority = 40;\n\n\tprivate readonly config: HorizontalRuleConfig;\n\tprivate locale!: HorizontalRuleLocale;\n\n\tconstructor(config?: Partial<HorizontalRuleConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.locale = resolvePluginLocale(HORIZONTAL_RULE_LOCALES, context, this.config.locale);\n\t\tthis.registerNodeSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymap(context);\n\t\tthis.registerInputRule(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerNodeSpec(context: PluginContext): void {\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'horizontal_rule',\n\t\t\tgroup: 'block',\n\t\t\tisVoid: true,\n\t\t\ttoDOM(node) {\n\t\t\t\treturn createBlockElement('hr', node.id);\n\t\t\t},\n\t\t\ttoHTML() {\n\t\t\t\treturn '<hr>';\n\t\t\t},\n\t\t\tparseHTML: [{ tag: 'hr' }],\n\t\t\tsanitize: { tags: ['hr'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('insertHorizontalRule', () => {\n\t\t\treturn this.insertHorizontalRule(context);\n\t\t});\n\t}\n\n\tprivate registerKeymap(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-H': () => context.executeCommand('insertHorizontalRule'),\n\t\t});\n\t}\n\n\tprivate registerInputRule(context: PluginContext): void {\n\t\tcontext.registerInputRule({\n\t\t\tpattern: /^-{3,} $/,\n\t\t\thandler(state, _match, _start, end) {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\tif (isNodeSelection(sel) || isGapCursor(sel)) return null;\n\t\t\t\tif (!isCollapsed(sel)) return null;\n\n\t\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\t\tif (!block || block.type !== 'paragraph') return null;\n\n\t\t\t\tconst blockIndex: number = findBlockIndexForCursor(state);\n\t\t\t\tif (blockIndex === -1) return null;\n\n\t\t\t\tconst newParagraph = createBlockNode(nodeType('paragraph'));\n\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.deleteTextAt(sel.anchor.blockId, 0, end)\n\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('horizontal_rule'))\n\t\t\t\t\t.insertNode([], blockIndex + 1, newParagraph)\n\t\t\t\t\t.setSelection(createCollapsedSelection(newParagraph.id, 0))\n\t\t\t\t\t.build();\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon =\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 11h16v2H4z\"/></svg>';\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'horizontal-rule',\n\t\t\tgroup: 'block',\n\t\t\ticon,\n\t\t\tlabel: this.locale.label,\n\t\t\ttooltip: this.locale.tooltip(formatShortcut('Mod-Shift-H')),\n\t\t\tcommand: 'insertHorizontalRule',\n\t\t\tpriority: 60,\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\tisActive: () => false,\n\t\t});\n\t}\n\n\t/**\n\t * Inserts a horizontal rule after the current block,\n\t * followed by a new paragraph for continued editing.\n\t */\n\tprivate insertHorizontalRule(context: PluginContext): boolean {\n\t\tconst state: EditorState = context.getState();\n\t\tif (isNodeSelection(state.selection) || isGapCursor(state.selection)) return false;\n\t\tconst blockIndex: number = findBlockIndexForCursor(state);\n\t\tif (blockIndex === -1) return false;\n\n\t\tconst hrBlock = createBlockNode(nodeType('horizontal_rule'));\n\t\tconst newParagraph = createBlockNode(nodeType('paragraph'));\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.insertNode([], blockIndex + 1, hrBlock)\n\t\t\t.insertNode([], blockIndex + 2, newParagraph)\n\t\t\t.setSelection(createCollapsedSelection(newParagraph.id, 0))\n\t\t\t.build();\n\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n}\n"],"names":["HORIZONTAL_RULE_LOCALE_EN","label","tooltip","shortcut","HORIZONTAL_RULE_LOCALES","en","de","es","fr","zh","ru","ar","hi","DEFAULT_CONFIG","findBlockIndexForCursor","state","sel","selection","isNodeSelection","isGapCursor","doc","children","findIndex","b","id","anchor","blockId","HorizontalRulePlugin","name","priority","config","locale","this","context","resolvePluginLocale","registerNodeSpec","registerCommands","registerKeymap","registerInputRule","registerToolbarItem","type","group","isVoid","toDOM","node","createBlockElement","toHTML","parseHTML","tag","sanitize","tags","registerCommand","insertHorizontalRule","executeCommand","pattern","_match","_start","end","isCollapsed","block","getBlock","blockIndex","newParagraph","createBlockNode","nodeType","transaction","deleteTextAt","setBlockType","insertNode","setSelection","createCollapsedSelection","build","icon","formatShortcut","command","separatorAfter","isActive","getState","hrBlock","tr","dispatch"],"mappings":"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"}
1
+ {"version":3,"file":"index-DxbQirny.mjs","sources":["../../src/plugins/horizontal-rule/HorizontalRuleLocale.ts","../../src/plugins/horizontal-rule/HorizontalRulePlugin.ts"],"sourcesContent":["/** Locale interface and default English locale for the HorizontalRulePlugin. */\n\n// --- Locale Interface ---\n\nexport interface HorizontalRuleLocale {\n\treadonly label: string;\n\treadonly tooltip: (shortcut: string) => string;\n}\n\n// --- Default English Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_EN: HorizontalRuleLocale = {\n\tlabel: 'Horizontal Rule',\n\ttooltip: (shortcut: string) => `Horizontal Rule (${shortcut})`,\n};\n\n// --- German Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_DE: HorizontalRuleLocale = {\n\tlabel: 'Trennlinie',\n\ttooltip: (shortcut: string) => `Trennlinie (${shortcut})`,\n};\n\n// --- Spanish Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_ES: HorizontalRuleLocale = {\n\tlabel: 'Línea horizontal',\n\ttooltip: (shortcut: string) => `Línea horizontal (${shortcut})`,\n};\n\n// --- French Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_FR: HorizontalRuleLocale = {\n\tlabel: 'Ligne horizontale',\n\ttooltip: (shortcut: string) => `Ligne horizontale (${shortcut})`,\n};\n\n// --- Chinese (Simplified) Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_ZH: HorizontalRuleLocale = {\n\tlabel: '分隔线',\n\ttooltip: (shortcut: string) => `分隔线 (${shortcut})`,\n};\n\n// --- Russian Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_RU: HorizontalRuleLocale = {\n\tlabel: 'Горизонтальная линия',\n\ttooltip: (shortcut: string) => `Горизонтальная линия (${shortcut})`,\n};\n\n// --- Arabic Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_AR: HorizontalRuleLocale = {\n\tlabel: 'خط أفقي',\n\ttooltip: (shortcut: string) => `خط أفقي (${shortcut})`,\n};\n\n// --- Hindi Locale ---\n\nexport const HORIZONTAL_RULE_LOCALE_HI: HorizontalRuleLocale = {\n\tlabel: 'क्षैतिज रेखा',\n\ttooltip: (shortcut: string) => `क्षैतिज रेखा (${shortcut})`,\n};\n\n// --- Locale Map ---\n\nexport const HORIZONTAL_RULE_LOCALES: Record<string, HorizontalRuleLocale> = {\n\ten: HORIZONTAL_RULE_LOCALE_EN,\n\tde: HORIZONTAL_RULE_LOCALE_DE,\n\tes: HORIZONTAL_RULE_LOCALE_ES,\n\tfr: HORIZONTAL_RULE_LOCALE_FR,\n\tzh: HORIZONTAL_RULE_LOCALE_ZH,\n\tru: HORIZONTAL_RULE_LOCALE_RU,\n\tar: HORIZONTAL_RULE_LOCALE_AR,\n\thi: HORIZONTAL_RULE_LOCALE_HI,\n};\n","/**\n * HorizontalRulePlugin: registers a horizontal rule (divider) void block type\n * with NodeSpec, insert command, input rule, keyboard shortcut, and toolbar button.\n */\n\nimport { resolvePluginLocale } from '../../i18n/resolvePluginLocale.js';\nimport { createBlockNode } from '../../model/Document.js';\nimport { createBlockElement } from '../../model/NodeSpec.js';\nimport {\n\tcreateCollapsedSelection,\n\tisCollapsed,\n\tisGapCursor,\n\tisNodeSelection,\n} from '../../model/Selection.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { formatShortcut } from '../toolbar/ToolbarItem.js';\nimport { HORIZONTAL_RULE_LOCALES, type HorizontalRuleLocale } from './HorizontalRuleLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\thorizontal_rule: Record<string, never>;\n\t}\n}\n\n// --- Configuration ---\n\nexport interface HorizontalRuleConfig {\n\t/** When true, a separator is rendered after the toolbar item. */\n\treadonly separatorAfter?: boolean;\n\t/** Locale override for user-facing strings. */\n\treadonly locale?: HorizontalRuleLocale;\n}\n\nconst DEFAULT_CONFIG: HorizontalRuleConfig = {};\n\n// --- Helpers ---\n\n/** Finds the index of the cursor's block among top-level document children. */\nfunction findBlockIndexForCursor(state: EditorState): number {\n\tconst sel = state.selection;\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return -1;\n\treturn state.doc.children.findIndex((b) => b.id === sel.anchor.blockId);\n}\n\n// --- Plugin ---\n\nexport class HorizontalRulePlugin implements Plugin {\n\treadonly id = 'horizontal-rule';\n\treadonly name = 'Horizontal Rule';\n\treadonly priority = 40;\n\n\tprivate readonly config: HorizontalRuleConfig;\n\tprivate locale!: HorizontalRuleLocale;\n\n\tconstructor(config?: Partial<HorizontalRuleConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.locale = resolvePluginLocale(HORIZONTAL_RULE_LOCALES, context, this.config.locale);\n\t\tthis.registerNodeSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymap(context);\n\t\tthis.registerInputRule(context);\n\t\tthis.registerToolbarItem(context);\n\t}\n\n\tprivate registerNodeSpec(context: PluginContext): void {\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'horizontal_rule',\n\t\t\tgroup: 'block',\n\t\t\tisVoid: true,\n\t\t\ttoDOM(node) {\n\t\t\t\treturn createBlockElement('hr', node.id);\n\t\t\t},\n\t\t\ttoHTML() {\n\t\t\t\treturn '<hr>';\n\t\t\t},\n\t\t\tparseHTML: [{ tag: 'hr' }],\n\t\t\tsanitize: { tags: ['hr'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('insertHorizontalRule', () => {\n\t\t\treturn this.insertHorizontalRule(context);\n\t\t});\n\t}\n\n\tprivate registerKeymap(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Mod-Shift-H': () => context.executeCommand('insertHorizontalRule'),\n\t\t});\n\t}\n\n\tprivate registerInputRule(context: PluginContext): void {\n\t\tcontext.registerInputRule({\n\t\t\tpattern: /^-{3,} $/,\n\t\t\thandler(state, _match, _start, end) {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\tif (isNodeSelection(sel) || isGapCursor(sel)) return null;\n\t\t\t\tif (!isCollapsed(sel)) return null;\n\n\t\t\t\tconst block = state.getBlock(sel.anchor.blockId);\n\t\t\t\tif (!block || block.type !== 'paragraph') return null;\n\n\t\t\t\tconst blockIndex: number = findBlockIndexForCursor(state);\n\t\t\t\tif (blockIndex === -1) return null;\n\n\t\t\t\tconst newParagraph = createBlockNode(nodeType('paragraph'));\n\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.deleteTextAt(sel.anchor.blockId, 0, end)\n\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('horizontal_rule'))\n\t\t\t\t\t.insertNode([], blockIndex + 1, newParagraph)\n\t\t\t\t\t.setSelection(createCollapsedSelection(newParagraph.id, 0))\n\t\t\t\t\t.build();\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tconst icon =\n\t\t\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 11h16v2H4z\"/></svg>';\n\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'horizontal-rule',\n\t\t\tgroup: 'block',\n\t\t\ticon,\n\t\t\tlabel: this.locale.label,\n\t\t\ttooltip: this.locale.tooltip(formatShortcut('Mod-Shift-H')),\n\t\t\tcommand: 'insertHorizontalRule',\n\t\t\tpriority: 60,\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\tisActive: () => false,\n\t\t});\n\t}\n\n\t/**\n\t * Inserts a horizontal rule after the current block,\n\t * followed by a new paragraph for continued editing.\n\t */\n\tprivate insertHorizontalRule(context: PluginContext): boolean {\n\t\tconst state: EditorState = context.getState();\n\t\tif (isNodeSelection(state.selection) || isGapCursor(state.selection)) return false;\n\t\tconst blockIndex: number = findBlockIndexForCursor(state);\n\t\tif (blockIndex === -1) return false;\n\n\t\tconst hrBlock = createBlockNode(nodeType('horizontal_rule'));\n\t\tconst newParagraph = createBlockNode(nodeType('paragraph'));\n\n\t\tconst tr = state\n\t\t\t.transaction('command')\n\t\t\t.insertNode([], blockIndex + 1, hrBlock)\n\t\t\t.insertNode([], blockIndex + 2, newParagraph)\n\t\t\t.setSelection(createCollapsedSelection(newParagraph.id, 0))\n\t\t\t.build();\n\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n}\n"],"names":["HORIZONTAL_RULE_LOCALE_EN","label","tooltip","shortcut","HORIZONTAL_RULE_LOCALES","en","de","es","fr","zh","ru","ar","hi","DEFAULT_CONFIG","findBlockIndexForCursor","state","sel","selection","isNodeSelection","isGapCursor","doc","children","findIndex","b","id","anchor","blockId","HorizontalRulePlugin","name","priority","config","locale","this","context","resolvePluginLocale","registerNodeSpec","registerCommands","registerKeymap","registerInputRule","registerToolbarItem","type","group","isVoid","toDOM","node","createBlockElement","toHTML","parseHTML","tag","sanitize","tags","registerCommand","insertHorizontalRule","executeCommand","pattern","_match","_start","end","isCollapsed","block","getBlock","blockIndex","newParagraph","createBlockNode","nodeType","transaction","deleteTextAt","setBlockType","insertNode","setSelection","createCollapsedSelection","build","icon","formatShortcut","command","separatorAfter","isActive","getState","hrBlock","tr","dispatch"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
- import { k as t, f as n, u as e, b as o, a as r, t as i, g as c } from "./Document-DfZ1NOjs.mjs";
1
+ import { k as t, f as n, u as e, d as o, c as r, t as i, g as c } from "./Document-Brtw2jL1.mjs";
2
2
  import { i as s, b as l, s as d, a as u } from "./NavigationUtils-Cspt2ZrK.mjs";
3
- import { f } from "./NodeResolver-CzLmmrph.mjs";
3
+ import { f } from "./NodeResolver-C2XYkeOi.mjs";
4
4
  import { b as a, s as b, d as k, i as g, a as I, j as h, e as m, c as p } from "./Selection-BRTab5hO.mjs";
5
5
  import { n as S, i as B } from "./TypeBrands-C09nE2qO.mjs";
6
6
  function x(t2, n2) {
@@ -293,4 +293,4 @@ export {
293
293
  N as r,
294
294
  L as s
295
295
  };
296
- //# sourceMappingURL=index-DuRNETFv.mjs.map
296
+ //# sourceMappingURL=index-ErZ5_a1o.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-DuRNETFv.mjs","sources":["../../src/commands/CommandHelpers.ts","../../src/commands/NodeSelectionCommands.ts","../../src/commands/GapCursorCommands.ts","../../src/commands/Commands.ts","../../src/plugins/hard-break/HardBreakPlugin.ts"],"sourcesContent":["/**\n * Shared helpers used across multiple command modules.\n *\n * - {@link getSiblings} — resolves a parent path to its child list\n * - {@link createEmptyParagraph} — builds an empty paragraph BlockNode\n * - {@link resolveInsertPoint} — normalizes a text selection to a single insert position\n */\n\nimport type { BlockNode, ChildNode } from '../model/Document.js';\nimport { createBlockNode, createTextNode } from '../model/Document.js';\nimport { isCollapsed, selectionRange } from '../model/Selection.js';\nimport type { Selection } from '../model/Selection.js';\nimport type { BlockId } from '../model/TypeBrands.js';\nimport { nodeType } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\n\n/** The resolved insert position within a single block. */\nexport interface InsertPoint {\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n}\n\n/** Resolves the children of a parent path: doc root or a nested block. */\nexport function getSiblings(\n\tstate: EditorState,\n\tparentPath: readonly BlockId[],\n): readonly ChildNode[] {\n\tif (parentPath.length === 0) return state.doc.children;\n\tconst parent: BlockNode | undefined = state.getBlock(\n\t\tparentPath[parentPath.length - 1] as BlockId,\n\t);\n\treturn parent ? parent.children : [];\n}\n\n/** Creates an empty paragraph block node with the given ID. */\nexport function createEmptyParagraph(id: BlockId): BlockNode {\n\treturn createBlockNode(nodeType('paragraph'), [createTextNode('')], id);\n}\n\n/**\n * Normalizes a text selection to a single insert point.\n *\n * - Collapsed selection → anchor position.\n * - Range selection → normalized `from` position (document-order start).\n */\nexport function resolveInsertPoint(sel: Selection, blockOrder: readonly BlockId[]): InsertPoint {\n\tif (isCollapsed(sel)) {\n\t\treturn { blockId: sel.anchor.blockId, offset: sel.anchor.offset };\n\t}\n\tconst range = selectionRange(sel, blockOrder);\n\treturn { blockId: range.from.blockId, offset: range.from.offset };\n}\n","/**\n * Commands for NodeSelection: deleting void blocks, inserting paragraphs\n * after void blocks, and navigating arrow keys into/out of void blocks.\n */\n\nimport { type BlockNode, generateBlockId, getBlockLength, isBlockNode } from '../model/Document.js';\nimport { isVoidBlock } from '../model/NavigationUtils.js';\nimport { findNodePath } from '../model/NodeResolver.js';\nimport type { NodeSelection } from '../model/Selection.js';\nimport {\n\tcreateCollapsedSelection,\n\tcreateGapCursor,\n\tcreateNodeSelection,\n\tisCollapsed,\n\tisGapCursor,\n\tisNodeSelection,\n} from '../model/Selection.js';\nimport type { BlockId } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport { createEmptyParagraph, getSiblings } from './CommandHelpers.js';\n\n/**\n * Deletes the void block targeted by a NodeSelection and places cursor\n * on the adjacent block. If it's the only block, replaces with empty paragraph.\n */\nexport function deleteNodeSelection(state: EditorState, sel: NodeSelection): Transaction | null {\n\tconst path = findNodePath(state.doc, sel.nodeId);\n\tif (!path) return null;\n\n\tconst parentPath: BlockId[] = path.length > 1 ? (path.slice(0, -1) as BlockId[]) : [];\n\tconst siblings = getSiblings(state, parentPath);\n\n\tconst index: number = siblings.findIndex((c) => 'id' in c && c.id === sel.nodeId);\n\tif (index < 0) return null;\n\n\tconst builder = state.transaction('input');\n\n\t// If this is the only block in the document, insert empty paragraph first\n\tif (siblings.length === 1 && parentPath.length === 0) {\n\t\tconst newId = generateBlockId();\n\t\tbuilder.insertNode(parentPath, 0, createEmptyParagraph(newId));\n\t\tbuilder.removeNode(parentPath, 1);\n\t\tbuilder.setSelection(createCollapsedSelection(newId, 0));\n\t\treturn builder.build();\n\t}\n\n\tbuilder.removeNode(parentPath, index);\n\n\t// Find where to place cursor: prefer previous sibling leaf, else next sibling leaf.\n\tconst prevSibling = siblings[index - 1];\n\tif (prevSibling && isBlockNode(prevSibling)) {\n\t\tconst prevLeafId = findLastLeafBlockId(prevSibling);\n\t\tif (prevLeafId) {\n\t\t\tconst prevLeaf = state.getBlock(prevLeafId);\n\t\t\tconst prevLen = prevLeaf ? getBlockLength(prevLeaf) : 0;\n\t\t\tbuilder.setSelection(createCollapsedSelection(prevLeafId, prevLen));\n\t\t}\n\t} else {\n\t\tconst nextSibling = siblings[index + 1];\n\t\tif (nextSibling && isBlockNode(nextSibling)) {\n\t\t\tconst nextLeafId = findFirstLeafBlockId(nextSibling);\n\t\t\tif (nextLeafId) {\n\t\t\t\tbuilder.setSelection(createCollapsedSelection(nextLeafId, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn builder.build();\n}\n\n/** Inserts a new paragraph after a NodeSelection-targeted void block. */\nexport function insertParagraphAfterNodeSelection(\n\tstate: EditorState,\n\tsel: NodeSelection,\n): Transaction | null {\n\tconst path = findNodePath(state.doc, sel.nodeId);\n\tif (!path) return null;\n\n\tconst parentPath: BlockId[] = path.length > 1 ? (path.slice(0, -1) as BlockId[]) : [];\n\tconst siblings = getSiblings(state, parentPath);\n\n\tconst index: number = siblings.findIndex((c) => 'id' in c && c.id === sel.nodeId);\n\tif (index < 0) return null;\n\n\tconst newId = generateBlockId();\n\tconst builder = state.transaction('input');\n\tbuilder.insertNode(parentPath, index + 1, createEmptyParagraph(newId));\n\tbuilder.setSelection(createCollapsedSelection(newId, 0));\n\treturn builder.build();\n}\n\n/** Inserts text in a new paragraph after a NodeSelection-targeted void block. */\nexport function insertTextAfterNodeSelection(\n\tstate: EditorState,\n\tsel: NodeSelection,\n\ttext: string,\n\torigin: 'input' | 'paste',\n): Transaction {\n\tconst path = findNodePath(state.doc, sel.nodeId);\n\tconst parentPath: BlockId[] = path && path.length > 1 ? (path.slice(0, -1) as BlockId[]) : [];\n\tconst siblings = getSiblings(state, parentPath);\n\n\tconst index: number = siblings.findIndex((c) => 'id' in c && c.id === sel.nodeId);\n\n\tconst newId = generateBlockId();\n\tconst builder = state.transaction(origin);\n\n\tconst insertIdx = index >= 0 ? index + 1 : siblings.length;\n\tbuilder.insertNode(parentPath, insertIdx, createEmptyParagraph(newId));\n\tbuilder.insertText(newId, 0, text, []);\n\tbuilder.setSelection(createCollapsedSelection(newId, text.length));\n\treturn builder.build();\n}\n\n/**\n * Navigates arrow keys into/out of void blocks.\n * Returns a transaction if navigation should create a NodeSelection, or null.\n */\nexport function navigateArrowIntoVoid(\n\tstate: EditorState,\n\tdirection: 'left' | 'right' | 'up' | 'down',\n): Transaction | null {\n\tconst sel = state.selection;\n\tconst blockOrder = state.getBlockOrder();\n\n\t// If currently on a NodeSelection, navigate away from it\n\tif (isNodeSelection(sel)) {\n\t\treturn navigateAwayFromNodeSelection(state, sel, direction, blockOrder);\n\t}\n\n\t// GapCursor is handled by navigateFromGapCursor in CaretNavigation\n\tif (isGapCursor(sel)) return null;\n\n\t// Text selection: check if navigating into a void block\n\tif (!isCollapsed(sel)) return null;\n\n\treturn navigateIntoVoid(state, sel, direction, blockOrder);\n}\n\n/** Finds the first leaf (deepest-first-child) block ID in a subtree. */\nexport function findFirstLeafBlockId(node: BlockNode): BlockId {\n\tlet current: BlockNode = node;\n\twhile (true) {\n\t\tconst firstBlockChild = current.children.find((child): child is BlockNode =>\n\t\t\tisBlockNode(child),\n\t\t);\n\t\tif (!firstBlockChild) return current.id;\n\t\tcurrent = firstBlockChild;\n\t}\n}\n\n/** Finds the last leaf (deepest-last-child) block ID in a subtree. */\nexport function findLastLeafBlockId(node: BlockNode): BlockId {\n\tlet current: BlockNode = node;\n\twhile (true) {\n\t\tlet lastBlockChild: BlockNode | undefined;\n\t\tfor (let i = current.children.length - 1; i >= 0; i--) {\n\t\t\tconst child = current.children[i];\n\t\t\tif (child && isBlockNode(child)) {\n\t\t\t\tlastBlockChild = child;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!lastBlockChild) return current.id;\n\t\tcurrent = lastBlockChild;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Handles navigation away from a NodeSelection (arrow keys while void is selected). */\nfunction navigateAwayFromNodeSelection(\n\tstate: EditorState,\n\tsel: NodeSelection,\n\tdirection: 'left' | 'right' | 'up' | 'down',\n\tblockOrder: readonly BlockId[],\n): Transaction | null {\n\tconst nodeIdx = blockOrder.indexOf(sel.nodeId);\n\tconst nodePath = (findNodePath(state.doc, sel.nodeId) ?? []) as BlockId[];\n\n\tif (direction === 'left' || direction === 'up') {\n\t\tif (nodeIdx > 0) {\n\t\t\tconst prevId = blockOrder[nodeIdx - 1];\n\t\t\tif (!prevId) return null;\n\t\t\tif (isVoidBlock(state, prevId)) {\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.setSelection(createGapCursor(sel.nodeId, 'before', nodePath))\n\t\t\t\t\t.build();\n\t\t\t}\n\t\t\tconst prevBlock = state.getBlock(prevId);\n\t\t\tconst prevLen = prevBlock ? getBlockLength(prevBlock) : 0;\n\t\t\treturn state\n\t\t\t\t.transaction('input')\n\t\t\t\t.setSelection(createCollapsedSelection(prevId, prevLen))\n\t\t\t\t.build();\n\t\t}\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(createGapCursor(sel.nodeId, 'before', nodePath))\n\t\t\t.build();\n\t}\n\n\t// right or down\n\tif (nodeIdx < blockOrder.length - 1) {\n\t\tconst nextId = blockOrder[nodeIdx + 1];\n\t\tif (!nextId) return null;\n\t\tif (isVoidBlock(state, nextId)) {\n\t\t\treturn state\n\t\t\t\t.transaction('input')\n\t\t\t\t.setSelection(createGapCursor(sel.nodeId, 'after', nodePath))\n\t\t\t\t.build();\n\t\t}\n\t\treturn state.transaction('input').setSelection(createCollapsedSelection(nextId, 0)).build();\n\t}\n\treturn state\n\t\t.transaction('input')\n\t\t.setSelection(createGapCursor(sel.nodeId, 'after', nodePath))\n\t\t.build();\n}\n\n/** Handles text selection navigating into an adjacent void block. */\nfunction navigateIntoVoid(\n\tstate: EditorState,\n\tsel: { readonly anchor: { readonly blockId: BlockId; readonly offset: number } },\n\tdirection: 'left' | 'right' | 'up' | 'down',\n\tblockOrder: readonly BlockId[],\n): Transaction | null {\n\tconst blockIdx = blockOrder.indexOf(sel.anchor.blockId);\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return null;\n\tconst blockLen = getBlockLength(block);\n\n\tif (direction === 'right' || direction === 'down') {\n\t\tif (sel.anchor.offset === blockLen && blockIdx < blockOrder.length - 1) {\n\t\t\tconst nextId = blockOrder[blockIdx + 1];\n\t\t\tif (nextId && isVoidBlock(state, nextId)) {\n\t\t\t\tconst path = findNodePath(state.doc, nextId) ?? [];\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.setSelection(createNodeSelection(nextId, path as BlockId[]))\n\t\t\t\t\t.build();\n\t\t\t}\n\t\t}\n\t}\n\n\tif (direction === 'left' || direction === 'up') {\n\t\tif (sel.anchor.offset === 0 && blockIdx > 0) {\n\t\t\tconst prevId = blockOrder[blockIdx - 1];\n\t\t\tif (prevId && isVoidBlock(state, prevId)) {\n\t\t\t\tconst path = findNodePath(state.doc, prevId) ?? [];\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.setSelection(createNodeSelection(prevId, path as BlockId[]))\n\t\t\t\t\t.build();\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n","/**\n * Commands for GapCursor: deleting void blocks adjacent to gap cursors\n * and inserting paragraphs at gap positions.\n */\n\nimport { generateBlockId, getBlockLength } from '../model/Document.js';\nimport { isVoidBlock } from '../model/NavigationUtils.js';\nimport { findNodePath } from '../model/NodeResolver.js';\nimport type { GapCursorSelection, NodeSelection } from '../model/Selection.js';\nimport { createCollapsedSelection, createNodeSelection } from '../model/Selection.js';\nimport type { BlockId } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport { createEmptyParagraph, getSiblings } from './CommandHelpers.js';\nimport { deleteNodeSelection } from './NodeSelectionCommands.js';\n\n/**\n * Deletes the void block adjacent to a GapCursor when pressing Backspace.\n *\n * - `side === 'after'` → void block is behind the cursor → delete it.\n * - `side === 'before'` → void block is ahead → navigate backward (to previous block).\n * - At document start with `side === 'before'` → `null` (no-op).\n */\nexport function deleteBackwardAtGap(\n\tstate: EditorState,\n\tsel: GapCursorSelection,\n): Transaction | null {\n\tif (sel.side === 'after') {\n\t\treturn deleteVoidAtGap(state, sel);\n\t}\n\n\t// side === 'before': navigate to previous block\n\tconst blockOrder: readonly BlockId[] = state.getBlockOrder();\n\tconst blockIdx: number = blockOrder.indexOf(sel.blockId);\n\n\tif (blockIdx <= 0) return null;\n\n\tconst prevId: BlockId | undefined = blockOrder[blockIdx - 1];\n\tif (!prevId) return null;\n\n\tif (isVoidBlock(state, prevId)) {\n\t\tconst path = findNodePath(state.doc, prevId) ?? [];\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(createNodeSelection(prevId, path as BlockId[]))\n\t\t\t.build();\n\t}\n\n\tconst prevBlock = state.getBlock(prevId);\n\tif (!prevBlock) return null;\n\tconst prevLen: number = getBlockLength(prevBlock);\n\treturn state.transaction('input').setSelection(createCollapsedSelection(prevId, prevLen)).build();\n}\n\n/**\n * Deletes the void block adjacent to a GapCursor when pressing Delete.\n *\n * - `side === 'before'` → void block is ahead of the cursor → delete it.\n * - `side === 'after'` → void block is behind → navigate forward (to next block).\n * - At document end with `side === 'after'` → `null` (no-op).\n */\nexport function deleteForwardAtGap(\n\tstate: EditorState,\n\tsel: GapCursorSelection,\n): Transaction | null {\n\tif (sel.side === 'before') {\n\t\treturn deleteVoidAtGap(state, sel);\n\t}\n\n\t// side === 'after': navigate to next block\n\tconst blockOrder: readonly BlockId[] = state.getBlockOrder();\n\tconst blockIdx: number = blockOrder.indexOf(sel.blockId);\n\n\tif (blockIdx >= blockOrder.length - 1) return null;\n\n\tconst nextId: BlockId | undefined = blockOrder[blockIdx + 1];\n\tif (!nextId) return null;\n\n\tif (isVoidBlock(state, nextId)) {\n\t\tconst path = findNodePath(state.doc, nextId) ?? [];\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(createNodeSelection(nextId, path as BlockId[]))\n\t\t\t.build();\n\t}\n\n\treturn state.transaction('input').setSelection(createCollapsedSelection(nextId, 0)).build();\n}\n\n/** Deletes the void block that the GapCursor is adjacent to, delegating to deleteNodeSelection. */\nfunction deleteVoidAtGap(state: EditorState, sel: GapCursorSelection): Transaction | null {\n\tconst path = (findNodePath(state.doc, sel.blockId) ?? []) as BlockId[];\n\tconst nodeSel: NodeSelection = createNodeSelection(sel.blockId, path);\n\treturn deleteNodeSelection(state, nodeSel);\n}\n\n/** Inserts a new paragraph at a GapCursor position (before or after the void block). */\nexport function insertParagraphAtGap(\n\tstate: EditorState,\n\tsel: GapCursorSelection,\n): Transaction | null {\n\tconst path = findNodePath(state.doc, sel.blockId);\n\tif (!path) return null;\n\n\tconst parentPath: BlockId[] = path.length > 1 ? (path.slice(0, -1) as BlockId[]) : [];\n\tconst siblings = getSiblings(state, parentPath);\n\n\tconst index: number = siblings.findIndex((c) => 'id' in c && c.id === sel.blockId);\n\tif (index < 0) return null;\n\n\tconst insertIdx: number = sel.side === 'before' ? index : index + 1;\n\tconst newId = generateBlockId();\n\tconst builder = state.transaction('input');\n\tbuilder.insertNode(parentPath, insertIdx, createEmptyParagraph(newId));\n\tbuilder.setSelection(createCollapsedSelection(newId, 0));\n\treturn builder.build();\n}\n\n/** Inserts text in a new paragraph at a GapCursor position. */\nexport function insertTextAtGap(\n\tstate: EditorState,\n\tsel: GapCursorSelection,\n\ttext: string,\n\torigin: 'input' | 'paste',\n): Transaction {\n\tconst path = findNodePath(state.doc, sel.blockId);\n\tconst parentPath: BlockId[] = path && path.length > 1 ? (path.slice(0, -1) as BlockId[]) : [];\n\tconst siblings = getSiblings(state, parentPath);\n\n\tconst index: number = siblings.findIndex((c) => 'id' in c && c.id === sel.blockId);\n\tconst insertIdx: number =\n\t\tsel.side === 'before' ? Math.max(index, 0) : index >= 0 ? index + 1 : siblings.length;\n\n\tconst newId = generateBlockId();\n\tconst builder = state.transaction(origin);\n\tbuilder.insertNode(parentPath, insertIdx, createEmptyParagraph(newId));\n\tbuilder.insertText(newId, 0, text, []);\n\tbuilder.setSelection(createCollapsedSelection(newId, text.length));\n\treturn builder.build();\n}\n","/**\n * Core editor commands and barrel re-exports from submodules.\n *\n * This module contains text insertion, block splitting, block merging,\n * selection deletion, and select-all. Mark, delete, gap-cursor, node-selection,\n * and word-boundary commands are re-exported from their respective modules.\n */\n\nimport {\n\ttype Mark,\n\tcreateInlineNode,\n\tgenerateBlockId,\n\tgetBlockLength,\n\tgetBlockMarksAtOffset,\n} from '../model/Document.js';\nimport {\n\tisInsideIsolating,\n\tisIsolatingBlock,\n\tisVoidBlock,\n\tsharesParent,\n} from '../model/NavigationUtils.js';\nimport { findNodePath } from '../model/NodeResolver.js';\nimport {\n\tcreateCollapsedSelection,\n\tcreateNodeSelection,\n\tcreateSelection,\n\tisCollapsed,\n\tisGapCursor,\n\tisNodeSelection,\n\tselectionRange,\n} from '../model/Selection.js';\nimport { type BlockId, inlineType } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport type { TransactionBuilder } from '../state/Transaction.js';\nimport { resolveInsertPoint } from './CommandHelpers.js';\nimport { insertParagraphAtGap, insertTextAtGap } from './GapCursorCommands.js';\nimport {\n\tdeleteNodeSelection,\n\tinsertParagraphAfterNodeSelection,\n\tinsertTextAfterNodeSelection,\n} from './NodeSelectionCommands.js';\n\n// --- Re-exports from submodules ---\n\nexport {\n\tcanCrossBlockBoundary,\n\tisInsideIsolating,\n\tisIsolatingBlock,\n\tisVoidBlock,\n\tsharesParent,\n} from '../model/NavigationUtils.js';\n\nexport type { FeatureConfig } from './MarkCommands.js';\nexport {\n\tisMarkActive,\n\ttoggleBold,\n\ttoggleItalic,\n\ttoggleMark,\n\ttoggleUnderline,\n} from './MarkCommands.js';\n\nexport {\n\tdeleteBackward,\n\tdeleteForward,\n\tdeleteSoftLineBackward,\n\tdeleteSoftLineForward,\n\tdeleteWordBackward,\n\tdeleteWordForward,\n} from './DeleteCommands.js';\n\nexport {\n\tdeleteNodeSelection,\n\tfindFirstLeafBlockId,\n\tfindLastLeafBlockId,\n\tinsertParagraphAfterNodeSelection,\n\tinsertTextAfterNodeSelection,\n\tnavigateArrowIntoVoid,\n} from './NodeSelectionCommands.js';\n\nexport {\n\tdeleteBackwardAtGap,\n\tdeleteForwardAtGap,\n\tinsertParagraphAtGap,\n\tinsertTextAtGap,\n} from './GapCursorCommands.js';\n\nexport {\n\tfindWordBoundaryBackward,\n\tfindWordBoundaryForward,\n} from './WordBoundary.js';\n\nexport {\n\tapplyAttributedMark,\n\tgetMarkAttrAtSelection,\n\tisAttributedMarkActive,\n\tremoveAttributedMark,\n} from './AttributedMarkCommands.js';\n\nexport { forEachBlockInRange } from './RangeIterator.js';\n\n// --- Text Commands ---\n\n/** Inserts text at the current selection, replacing any selected range. */\nexport function insertTextCommand(\n\tstate: EditorState,\n\ttext: string,\n\torigin: 'input' | 'paste' = 'input',\n): Transaction {\n\tconst sel = state.selection;\n\n\t// NodeSelection: insert paragraph after void block with the text\n\tif (isNodeSelection(sel)) {\n\t\treturn insertTextAfterNodeSelection(state, sel, text, origin);\n\t}\n\n\t// GapCursor: insert paragraph at the gap position with the text\n\tif (isGapCursor(sel)) {\n\t\treturn insertTextAtGap(state, sel, text, origin);\n\t}\n\n\tconst builder = state.transaction(origin);\n\tconst marks = resolveActiveMarks(state);\n\n\tif (!isCollapsed(sel)) {\n\t\taddDeleteSelectionSteps(state, builder);\n\t}\n\n\tconst { blockId: insertBlockId, offset: insertOffset } = resolveInsertPoint(\n\t\tsel,\n\t\tstate.getBlockOrder(),\n\t);\n\n\tbuilder.insertText(insertBlockId, insertOffset, text, marks);\n\tbuilder.setSelection(createCollapsedSelection(insertBlockId, insertOffset + text.length));\n\n\treturn builder.build();\n}\n\n/** Deletes the current selection. */\nexport function deleteSelectionCommand(state: EditorState): Transaction | null {\n\tif (isNodeSelection(state.selection)) {\n\t\treturn deleteNodeSelection(state, state.selection);\n\t}\n\tif (isGapCursor(state.selection)) return null;\n\tif (isCollapsed(state.selection)) return null;\n\n\tconst builder = state.transaction('input');\n\taddDeleteSelectionSteps(state, builder);\n\n\tconst range = selectionRange(state.selection, state.getBlockOrder());\n\tbuilder.setSelection(createCollapsedSelection(range.from.blockId, range.from.offset));\n\n\treturn builder.build();\n}\n\n/** Splits the current block at the cursor position (Enter key). */\nexport function splitBlockCommand(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\n\t// NodeSelection: insert empty paragraph after the void block\n\tif (isNodeSelection(sel)) {\n\t\treturn insertParagraphAfterNodeSelection(state, sel);\n\t}\n\n\t// GapCursor: insert empty paragraph at the gap position\n\tif (isGapCursor(sel)) {\n\t\treturn insertParagraphAtGap(state, sel);\n\t}\n\n\tconst builder = state.transaction('input');\n\n\tif (!isCollapsed(sel)) {\n\t\taddDeleteSelectionSteps(state, builder);\n\t}\n\n\tconst { blockId, offset } = resolveInsertPoint(sel, state.getBlockOrder());\n\tconst newBlockId = generateBlockId();\n\n\t// splitBlock operates at the same level in the tree — the StepApplication\n\t// handles this correctly because it looks up the block by ID recursively.\n\tbuilder.splitBlock(blockId, offset, newBlockId);\n\tbuilder.setSelection(createCollapsedSelection(newBlockId, 0));\n\n\treturn builder.build();\n}\n\n/** Inserts a hard line break (InlineNode) at the current cursor position. */\nexport function insertHardBreakCommand(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return null;\n\n\tconst builder = state.transaction('input');\n\n\tif (!isCollapsed(sel)) {\n\t\taddDeleteSelectionSteps(state, builder);\n\t}\n\n\tconst { blockId: insertBlockId, offset: insertOffset } = resolveInsertPoint(\n\t\tsel,\n\t\tstate.getBlockOrder(),\n\t);\n\n\tconst hardBreak = createInlineNode(inlineType('hard_break'));\n\tbuilder.insertInlineNode(insertBlockId, insertOffset, hardBreak);\n\tbuilder.setSelection(createCollapsedSelection(insertBlockId, insertOffset + 1));\n\n\treturn builder.build();\n}\n\n/**\n * Merges the current block with the previous block, respecting\n * isolating boundaries and void blocks.\n */\nexport function mergeBlockBackward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return null;\n\tconst blockOrder = state.getBlockOrder();\n\tconst blockIdx = blockOrder.indexOf(sel.anchor.blockId);\n\n\tif (blockIdx <= 0) return null;\n\n\tconst prevBlockId = blockOrder[blockIdx - 1];\n\tif (!prevBlockId) return null;\n\n\t// Never merge isolating blocks directly (e.g. table cells).\n\tif (isIsolatingBlock(state, sel.anchor.blockId) || isIsolatingBlock(state, prevBlockId)) {\n\t\treturn null;\n\t}\n\n\t// Prevent merge across isolating boundaries\n\tif (!sharesParent(state, sel.anchor.blockId, prevBlockId)) {\n\t\tif (isInsideIsolating(state, sel.anchor.blockId)) return null;\n\t}\n\n\t// If previous block is void, select it instead of merging\n\tif (isVoidBlock(state, prevBlockId)) {\n\t\tconst path = findNodePath(state.doc, prevBlockId) ?? [];\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(createNodeSelection(prevBlockId, path as BlockId[]))\n\t\t\t.build();\n\t}\n\n\tconst prevBlock = state.getBlock(prevBlockId);\n\tif (!prevBlock) return null;\n\tconst prevLen = getBlockLength(prevBlock);\n\n\treturn state\n\t\t.transaction('input')\n\t\t.mergeBlocksAt(prevBlockId, sel.anchor.blockId)\n\t\t.setSelection(createCollapsedSelection(prevBlockId, prevLen))\n\t\t.build();\n}\n\n/**\n * Merges the next block into the current block, respecting\n * isolating boundaries and void blocks.\n */\nexport function mergeBlockForward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return null;\n\tconst blockOrder = state.getBlockOrder();\n\tconst blockIdx = blockOrder.indexOf(sel.anchor.blockId);\n\n\tif (blockIdx >= blockOrder.length - 1) return null;\n\n\tconst nextBlockId = blockOrder[blockIdx + 1];\n\tif (!nextBlockId) return null;\n\n\t// Never merge isolating blocks directly (e.g. table cells).\n\tif (isIsolatingBlock(state, sel.anchor.blockId) || isIsolatingBlock(state, nextBlockId)) {\n\t\treturn null;\n\t}\n\n\t// Prevent merge across isolating boundaries\n\tif (!sharesParent(state, sel.anchor.blockId, nextBlockId)) {\n\t\tif (isInsideIsolating(state, sel.anchor.blockId)) return null;\n\t}\n\n\t// If next block is void, select it instead of merging\n\tif (isVoidBlock(state, nextBlockId)) {\n\t\tconst path = findNodePath(state.doc, nextBlockId) ?? [];\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(createNodeSelection(nextBlockId, path as BlockId[]))\n\t\t\t.build();\n\t}\n\n\treturn state\n\t\t.transaction('input')\n\t\t.mergeBlocksAt(sel.anchor.blockId, nextBlockId)\n\t\t.setSelection(createCollapsedSelection(sel.anchor.blockId, sel.anchor.offset))\n\t\t.build();\n}\n\n/** Selects all content in the editor. */\nexport function selectAll(state: EditorState): Transaction {\n\tconst blocks = state.doc.children;\n\tconst firstBlock = blocks[0];\n\tconst lastBlock = blocks[blocks.length - 1];\n\tif (!firstBlock || !lastBlock)\n\t\treturn state.transaction('command').setSelection(state.selection).build();\n\tconst lastBlockLen = getBlockLength(lastBlock);\n\n\treturn state\n\t\t.transaction('command')\n\t\t.setSelection(\n\t\t\tcreateSelection(\n\t\t\t\t{ blockId: firstBlock.id, offset: 0 },\n\t\t\t\t{ blockId: lastBlock.id, offset: lastBlockLen },\n\t\t\t),\n\t\t)\n\t\t.build();\n}\n\n// --- Internal Helpers ---\n\nfunction resolveActiveMarks(state: EditorState): readonly Mark[] {\n\tif (state.storedMarks) return state.storedMarks;\n\tif (isNodeSelection(state.selection) || isGapCursor(state.selection)) return [];\n\n\tconst block = state.getBlock(state.selection.anchor.blockId);\n\tif (!block) return [];\n\n\treturn getBlockMarksAtOffset(block, state.selection.anchor.offset);\n}\n\nexport function addDeleteSelectionSteps(state: EditorState, builder: TransactionBuilder): void {\n\tif (isNodeSelection(state.selection) || isGapCursor(state.selection)) return;\n\tconst blockOrder = state.getBlockOrder();\n\tconst range = selectionRange(state.selection, blockOrder);\n\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\tif (fromIdx === toIdx) {\n\t\tbuilder.deleteTextAt(range.from.blockId, range.from.offset, range.to.offset);\n\t} else {\n\t\tconst firstBlock = state.getBlock(range.from.blockId);\n\t\tif (!firstBlock) return;\n\t\tconst firstLen = getBlockLength(firstBlock);\n\n\t\t// Delete from the end of first block\n\t\tif (range.from.offset < firstLen) {\n\t\t\tbuilder.deleteTextAt(range.from.blockId, range.from.offset, firstLen);\n\t\t}\n\n\t\t// Delete from start of last block\n\t\tif (range.to.offset > 0) {\n\t\t\tbuilder.deleteTextAt(range.to.blockId, 0, range.to.offset);\n\t\t}\n\n\t\t// Delete middle blocks entirely and merge last into first\n\t\tfor (let i = fromIdx + 1; i < toIdx; i++) {\n\t\t\tconst midBlockId = blockOrder[i];\n\t\t\tif (!midBlockId) continue;\n\t\t\tconst midBlock = state.getBlock(midBlockId);\n\t\t\tif (!midBlock) continue;\n\t\t\tconst midLen = getBlockLength(midBlock);\n\t\t\tif (midLen > 0) {\n\t\t\t\tbuilder.deleteTextAt(midBlockId, 0, midLen);\n\t\t\t}\n\t\t\tbuilder.mergeBlocksAt(range.from.blockId, midBlockId);\n\t\t}\n\n\t\t// Merge last block into first\n\t\tbuilder.mergeBlocksAt(range.from.blockId, range.to.blockId);\n\t}\n}\n","/**\n * HardBreakPlugin: registers a hard line break (Shift+Enter → `<br>`)\n * as an InlineNode, with command and keymap bindings.\n */\n\nimport { insertHardBreakCommand } from '../../commands/Commands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface InlineNodeAttrRegistry {\n\t\thard_break: Record<string, never>;\n\t}\n}\n\n// --- Plugin ---\n\nexport class HardBreakPlugin implements Plugin {\n\treadonly id = 'hard-break';\n\treadonly name = 'Hard Break';\n\treadonly priority = 10;\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerInlineNodeSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymap(context);\n\t}\n\n\tprivate registerInlineNodeSpec(context: PluginContext): void {\n\t\tcontext.registerInlineNodeSpec({\n\t\t\ttype: 'hard_break',\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement('br');\n\t\t\t},\n\t\t\ttoHTMLString() {\n\t\t\t\treturn '<br>';\n\t\t\t},\n\t\t\tparseHTML: [{ tag: 'br' }],\n\t\t\tsanitize: { tags: ['br'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('insertHardBreak', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst tr = insertHardBreakCommand(state);\n\t\t\tif (!tr) return false;\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t});\n\t}\n\n\tprivate registerKeymap(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Shift-Enter': () => {\n\t\t\t\tconst state = context.getState();\n\t\t\t\tconst tr = insertHardBreakCommand(state);\n\t\t\t\tif (!tr) return false;\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t});\n\t}\n}\n"],"names":["getSiblings","state","parentPath","length","doc","children","parent","getBlock","createEmptyParagraph","id","createBlockNode","nodeType","createTextNode","resolveInsertPoint","sel","blockOrder","isCollapsed","blockId","anchor","offset","range","selectionRange","from","deleteNodeSelection","path","findNodePath","nodeId","slice","siblings","index","findIndex","c","builder","transaction","newId","generateBlockId","insertNode","removeNode","setSelection","createCollapsedSelection","build","prevSibling","isBlockNode","prevLeafId","node","current","lastBlockChild","i","child","prevLeaf","prevLen","getBlockLength","nextSibling","nextLeafId","firstBlockChild","find","navigateArrowIntoVoid","direction","selection","getBlockOrder","isNodeSelection","nodeIdx","indexOf","nodePath","prevId","isVoidBlock","createGapCursor","prevBlock","nextId","isGapCursor","blockIdx","block","blockLen","createNodeSelection","deleteBackwardAtGap","side","deleteVoidAtGap","deleteForwardAtGap","insertTextCommand","text","origin","insertIdx","insertText","Math","max","marks","storedMarks","getBlockMarksAtOffset","addDeleteSelectionSteps","insertBlockId","insertOffset","deleteSelectionCommand","splitBlockCommand","newBlockId","splitBlock","insertHardBreakCommand","hardBreak","createInlineNode","inlineType","insertInlineNode","mergeBlockBackward","prevBlockId","isIsolatingBlock","sharesParent","isInsideIsolating","mergeBlocksAt","mergeBlockForward","nextBlockId","selectAll","blocks","firstBlock","lastBlock","lastBlockLen","createSelection","fromIdx","toIdx","to","deleteTextAt","firstLen","midBlockId","midBlock","midLen","HardBreakPlugin","name","priority","context","this","registerInlineNodeSpec","registerCommands","registerKeymap","type","toDOM","document","createElement","toHTMLString","parseHTML","tag","sanitize","tags","registerCommand","tr","getState","dispatch"],"mappings":";;;;;AAuBO,SAASA,EACfC,IACAC,IAAAA;AAEA,MAA0B,MAAtBA,GAAWC,OAAc,QAAOF,GAAMG,IAAIC;AAC9C,QAAMC,KAAgCL,GAAMM,SAC3CL,GAAWA,GAAWC,SAAS,CAAA,CAAA;AAEhC,SAAOG,KAASA,GAAOD,WAAW,CAAA;AACnC;AAGO,SAASG,EAAqBC;AACpC,SAAOC,EAAgBC,EAAS,WAAA,GAAc,CAACC,EAAe,MAAMH,EAAAA;AACrE;AAQO,SAASI,EAAmBC,IAAgBC,IAAAA;AAClD,MAAIC,EAAYF,EAAAA,EACf,QAAO,EAAEG,SAASH,GAAII,OAAOD,SAASE,QAAQL,GAAII,OAAOC,OAAAA;AAE1D,QAAMC,KAAQC,EAAeP,IAAKC,EAAAA;AAClC,SAAO,EAAEE,SAASG,GAAME,KAAKL,SAASE,QAAQC,GAAME,KAAKH,OAAAA;AAC1D;ACzBO,SAASI,EAAoBtB,IAAoBa,IAAAA;AACvD,QAAMU,KAAOC,EAAaxB,GAAMG,KAAKU,GAAIY,MAAAA;AACzC,MAAA,CAAKF,GAAM,QAAO;AAElB,QAAMtB,KAAwBsB,GAAKrB,SAAS,IAAKqB,GAAKG,MAAM,GAAA,EAAG,IAAoB,CAAA,GAC7EC,KAAW5B,EAAYC,IAAOC,KAE9B2B,KAAgBD,GAASE,UAAWC,CAAAA,OAAM,QAAQA,MAAKA,GAAEtB,OAAOK,GAAIY,MAAAA;AAC1E,MAAIG,KAAQ,EAAG,QAAO;AAEtB,QAAMG,KAAU/B,GAAMgC,YAAY,OAAA;AAGlC,MAAwB,MAApBL,GAASzB,UAAsC,MAAtBD,GAAWC,QAAc;AACrD,UAAM+B,KAAQC,EAAAA;AAId,WAHAH,GAAQI,WAAWlC,IAAY,GAAGM,EAAqB0B,EAAAA,CAAAA,GACvDF,GAAQK,WAAWnC,IAAY,IAC/B8B,GAAQM,aAAaC,EAAyBL,IAAO,CAAA,CAAA,GAC9CF,GAAQQ;EAChB;AAEAR,EAAAA,GAAQK,WAAWnC,IAAY2B,EAAAA;AAG/B,QAAMY,KAAcb,GAASC,KAAQ,CAAA;AACrC,MAAIY,MAAeC,EAAYD,KAAc;AAC5C,UAAME,MAqGD,SAA6BC,IAAAA;AACnC,UAAIC,KAAqBD;AACzB,iBAAa;AACZ,YAAIE;AACJ,iBAASC,KAAIF,GAAQxC,SAASF,SAAS,GAAG4C,MAAK,GAAGA,MAAK;AACtD,gBAAMC,KAAQH,GAAQxC,SAAS0C,EAAAA;AAC/B,cAAIC,MAASN,EAAYM,EAAAA,GAAQ;AAChCF,YAAAA,KAAiBE;AACjB;AAAA,UACD;AAAA,QACD;AACA,YAAA,CAAKF,GAAgB,QAAOD,GAAQpC;AACpCoC,QAAAA,KAAUC;AAAAA,MACX;AAAA,IACD,GAnHyCL,EAAAA;AACvC,QAAIE,IAAY;AACf,YAAMM,KAAWhD,GAAMM,SAASoC,KAC1BO,KAAUD,KAAWE,EAAeF,EAAAA,IAAY;AACtDjB,MAAAA,GAAQM,aAAaC,EAAyBI,IAAYO,EAAAA,CAAAA;AAAAA,IAC3D;AAAA,EACD,OAAO;AACN,UAAME,KAAcxB,GAASC,KAAQ,CAAA;AACrC,QAAIuB,MAAeV,EAAYU,EAAAA,GAAc;AAC5C,YAAMC,MAgFF,SAA8BT,IAAAA;AACpC,YAAIC,KAAqBD;AACzB,mBAAa;AACZ,gBAAMU,KAAkBT,GAAQxC,SAASkD,KAAMP,CAAAA,OAC9CN,EAAYM,EAAAA,CAAAA;AAEb,cAAA,CAAKM,GAAiB,QAAOT,GAAQpC;AACrCoC,UAAAA,KAAUS;AAAAA,QACX;AAAA,MACD,GAzF2CF,EAAAA;AACpCC,MAAAA,MACHrB,GAAQM,aAAaC,EAAyBc,IAAY,CAAA,CAAA;AAAA,IAE5D;AAAA,EACD;AAEA,SAAOrB,GAAQQ,MAAAA;AAChB;AAkDO,SAASgB,EACfvD,IACAwD,IAAAA;AAEA,QAAM3C,KAAMb,GAAMyD,WACZ3C,KAAad,GAAM0D,cAAAA;AAGzB,SAAIC,EAAgB9C,OA+CrB,SACCb,IACAa,IACA2C,IACA1C,IAAAA;AAEA,UAAM8C,KAAU9C,GAAW+C,QAAQhD,GAAIY,MAAAA,GACjCqC,KAAYtC,EAAaxB,GAAMG,KAAKU,GAAIY,MAAAA,KAAW,CAAA;AAEzD,QAAkB,WAAd+B,MAAsC,SAAdA,IAAoB;AAC/C,UAAII,KAAU,GAAG;AAChB,cAAMG,KAASjD,GAAW8C,KAAU,CAAA;AACpC,YAAA,CAAKG,GAAQ,QAAO;AACpB,YAAIC,EAAYhE,IAAO+D,EAAAA,EACtB,QAAO/D,GACLgC,YAAY,OAAA,EACZK,aAAa4B,EAAgBpD,GAAIY,QAAQ,UAAUqC,EAAAA,CAAAA,EACnDvB,MAAAA;AAEH,cAAM2B,KAAYlE,GAAMM,SAASyD,KAC3Bd,KAAUiB,KAAYhB,EAAegB,EAAAA,IAAa;AACxD,eAAOlE,GACLgC,YAAY,OAAA,EACZK,aAAaC,EAAyByB,IAAQd,EAAAA,CAAAA,EAC9CV,MAAAA;AAAAA,MACH;AACA,aAAOvC,GACLgC,YAAY,OAAA,EACZK,aAAa4B,EAAgBpD,GAAIY,QAAQ,UAAUqC,EAAAA,CAAAA,EACnDvB,MAAAA;AAAAA,IACH;AAGA,QAAIqB,KAAU9C,GAAWZ,SAAS,GAAG;AACpC,YAAMiE,KAASrD,GAAW8C,KAAU,CAAA;AACpC,aAAKO,KACDH,EAAYhE,IAAOmE,MACfnE,GACLgC,YAAY,OAAA,EACZK,aAAa4B,EAAgBpD,GAAIY,QAAQ,SAASqC,EAAAA,CAAAA,EAClDvB,MAAAA,IAEIvC,GAAMgC,YAAY,OAAA,EAASK,aAAaC,EAAyB6B,IAAQ,CAAA,CAAA,EAAI5B,MAAAA,IAPhE;AAAA,IAQrB;AACA,WAAOvC,GACLgC,YAAY,OAAA,EACZK,aAAa4B,EAAgBpD,GAAIY,QAAQ,SAASqC,EAAAA,CAAAA,EAClDvB,MAAAA;AAAAA,EACH,GA9FuCvC,IAAOa,IAAK2C,IAAW1C,EAAAA,IAIzDsD,EAAYvD,EAAAA,IAAa,OAGxBE,EAAYF,EAAAA,KA0FlB,SACCb,IACAa,IACA2C,IACA1C,IAAAA;AAEA,UAAMuD,KAAWvD,GAAW+C,QAAQhD,GAAII,OAAOD,OAAAA,GACzCsD,KAAQtE,GAAMM,SAASO,GAAII,OAAOD,OAAAA;AACxC,QAAA,CAAKsD,GAAO,QAAO;AACnB,UAAMC,KAAWrB,EAAeoB,EAAAA;AAEhC,SAAkB,YAAdd,MAAuC,WAAdA,OACxB3C,GAAII,OAAOC,WAAWqD,MAAYF,KAAWvD,GAAWZ,SAAS,GAAG;AACvE,YAAMiE,KAASrD,GAAWuD,KAAW,CAAA;AACrC,UAAIF,MAAUH,EAAYhE,IAAOmE,KAAS;AACzC,cAAM5C,KAAOC,EAAaxB,GAAMG,KAAKgE,OAAW,CAAA;AAChD,eAAOnE,GACLgC,YAAY,OAAA,EACZK,aAAamC,EAAoBL,IAAQ5C,EAAAA,CAAAA,EACzCgB,MAAAA;AAAAA,MACH;AAAA,IACD;AAGD,SAAkB,WAAdiB,MAAsC,SAAdA,OACD,MAAtB3C,GAAII,OAAOC,UAAgBmD,KAAW,GAAG;AAC5C,YAAMN,KAASjD,GAAWuD,KAAW,CAAA;AACrC,UAAIN,MAAUC,EAAYhE,IAAO+D,EAAAA,GAAS;AACzC,cAAMxC,KAAOC,EAAaxB,GAAMG,KAAK4D,EAAAA,KAAW,CAAA;AAChD,eAAO/D,GACLgC,YAAY,OAAA,EACZK,aAAamC,EAAoBT,IAAQxC,KACzCgB,MAAAA;AAAAA,MACH;AAAA,IACD;AAGD,WAAO;AAAA,EACR,GA9HyBvC,IAAOa,IAAK2C,IAAW1C,EAAAA,IAFjB;AAG/B;ACnHO,SAAS2D,EACfzE,IACAa,IAAAA;AAEA,MAAiB,YAAbA,GAAI6D,KACP,QAAOC,EAAgB3E,IAAOa,EAAAA;AAI/B,QAAMC,KAAiCd,GAAM0D,cAAAA,GACvCW,KAAmBvD,GAAW+C,QAAQhD,GAAIG,OAAAA;AAEhD,MAAIqD,MAAY,EAAG,QAAO;AAE1B,QAAMN,KAA8BjD,GAAWuD,KAAW,CAAA;AAC1D,MAAA,CAAKN,GAAQ,QAAO;AAEpB,MAAIC,EAAYhE,IAAO+D,EAAAA,GAAS;AAC/B,UAAMxC,KAAOC,EAAaxB,GAAMG,KAAK4D,EAAAA,KAAW,CAAA;AAChD,WAAO/D,GACLgC,YAAY,OAAA,EACZK,aAAamC,EAAoBT,IAAQxC,EAAAA,CAAAA,EACzCgB,MAAAA;AAAAA,EACH;AAEA,QAAM2B,KAAYlE,GAAMM,SAASyD,EAAAA;AACjC,MAAA,CAAKG,GAAW,QAAO;AACvB,QAAMjB,KAAkBC,EAAegB,EAAAA;AACvC,SAAOlE,GAAMgC,YAAY,OAAA,EAASK,aAAaC,EAAyByB,IAAQd,KAAUV,MAAAA;AAC3F;AASO,SAASqC,EACf5E,IACAa,IAAAA;AAEA,MAAiB,aAAbA,GAAI6D,KACP,QAAOC,EAAgB3E,IAAOa,EAAAA;AAI/B,QAAMC,KAAiCd,GAAM0D,cAAAA,GACvCW,KAAmBvD,GAAW+C,QAAQhD,GAAIG,OAAAA;AAEhD,MAAIqD,MAAYvD,GAAWZ,SAAS,EAAG,QAAO;AAE9C,QAAMiE,KAA8BrD,GAAWuD,KAAW,CAAA;AAC1D,OAAKF,GAAQ,QAAO;AAEpB,MAAIH,EAAYhE,IAAOmE,KAAS;AAC/B,UAAM5C,KAAOC,EAAaxB,GAAMG,KAAKgE,OAAW,CAAA;AAChD,WAAOnE,GACLgC,YAAY,OAAA,EACZK,aAAamC,EAAoBL,IAAQ5C,EAAAA,CAAAA,EACzCgB,MAAAA;AAAAA,EACH;AAEA,SAAOvC,GAAMgC,YAAY,OAAA,EAASK,aAAaC,EAAyB6B,IAAQ,CAAA,CAAA,EAAI5B,MAAAA;AACrF;AAGA,SAASoC,EAAgB3E,IAAoBa,IAAAA;AAC5C,QAAMU,KAAQC,EAAaxB,GAAMG,KAAKU,GAAIG,OAAAA,KAAY,CAAA;AAEtD,SAAOM,EAAoBtB,IADIwE,EAAoB3D,GAAIG,SAASO,EAAAA,CAAAA;AAEjE;ACUO,SAASsD,EACf7E,IACA8E,IACAC,KAA4B,SAAA;AAE5B,QAAMlE,KAAMb,GAAMyD;AAGlB,MAAIE,EAAgB9C,EAAAA,EACnB,SFpBK,SACNb,IACAa,IACAiE,IACAC,IAAAA;AAEA,UAAMxD,KAAOC,EAAaxB,GAAMG,KAAKU,GAAIY,MAAAA,GACnCxB,KAAwBsB,MAAQA,GAAKrB,SAAS,IAAKqB,GAAKG,MAAM,GAAA,EAAG,IAAoB,CAAA,GACrFC,KAAW5B,EAAYC,IAAOC,EAAAA,GAE9B2B,KAAgBD,GAASE,UAAWC,CAAAA,OAAM,QAAQA,MAAKA,GAAEtB,OAAOK,GAAIY,MAAAA,GAEpEQ,KAAQC,EAAAA,GACRH,KAAU/B,GAAMgC,YAAY+C,EAAAA,GAE5BC,KAAYpD,MAAS,IAAIA,KAAQ,IAAID,GAASzB;AAIpD,WAHA6B,GAAQI,WAAWlC,IAAY+E,IAAWzE,EAAqB0B,EAAAA,CAAAA,GAC/DF,GAAQkD,WAAWhD,IAAO,GAAG6C,IAAM,CAAA,CAAA,GACnC/C,GAAQM,aAAaC,EAAyBL,IAAO6C,GAAK5E,MAAAA,CAAAA,GACnD6B,GAAQQ,MAAAA;AAAAA,EAChB,GEAsCvC,IAAOa,IAAKiE,IAAMC,EAAAA;AAIvD,MAAIX,EAAYvD,EAAAA,EACf,SDCK,SACNb,IACAa,IACAiE,IACAC,IAAAA;AAEA,UAAMxD,KAAOC,EAAaxB,GAAMG,KAAKU,GAAIG,OAAAA,GACnCf,KAAwBsB,MAAQA,GAAKrB,SAAS,IAAKqB,GAAKG,MAAM,GAAA,MAAuB,CAAA,GACrFC,KAAW5B,EAAYC,IAAOC,EAAAA,GAE9B2B,KAAgBD,GAASE,UAAWC,CAAAA,OAAM,QAAQA,MAAKA,GAAEtB,OAAOK,GAAIG,OAAAA,GACpEgE,KACQ,aAAbnE,GAAI6D,OAAoBQ,KAAKC,IAAIvD,IAAO,CAAA,IAAKA,MAAS,IAAIA,KAAQ,IAAID,GAASzB,QAE1E+B,KAAQC,EAAAA,GACRH,KAAU/B,GAAMgC,YAAY+C,EAAAA;AAIlC,WAHAhD,GAAQI,WAAWlC,IAAY+E,IAAWzE,EAAqB0B,EAAAA,CAAAA,GAC/DF,GAAQkD,WAAWhD,IAAO,GAAG6C,IAAM,CAAA,CAAA,GACnC/C,GAAQM,aAAaC,EAAyBL,IAAO6C,GAAK5E,MAAAA,CAAAA,GACnD6B,GAAQQ,MAAAA;AAAAA,EAChB,GCrByBvC,IAAOa,IAAKiE,IAAMC,EAAAA;AAG1C,QAAMhD,KAAU/B,GAAMgC,YAAY+C,EAAAA,GAC5BK,MAqMP,SAA4BpF,IAAAA;AAC3B,QAAIA,GAAMqF,YAAa,QAAOrF,GAAMqF;AACpC,QAAI1B,EAAgB3D,GAAMyD,SAAAA,KAAcW,EAAYpE,GAAMyD,SAAAA,EAAY,QAAO;AAE7E,UAAMa,KAAQtE,GAAMM,SAASN,GAAMyD,UAAUxC,OAAOD,OAAAA;AACpD,WAAKsD,KAEEgB,EAAsBhB,IAAOtE,GAAMyD,UAAUxC,OAAOC,MAAAA,IAFxC,CAAA;AAAA,EAGpB,GA7MkClB,EAAAA;AAE5Be,IAAYF,EAAAA,KAChB0E,EAAwBvF,IAAO+B,EAAAA;AAGhC,QAAA,EAAQf,SAASwE,IAAetE,QAAQuE,GAAAA,IAAiB7E,EACxDC,IACAb,GAAM0D,cAAAA,CAAAA;AAMP,SAHA3B,GAAQkD,WAAWO,IAAeC,IAAcX,IAAMM,EAAAA,GACtDrD,GAAQM,aAAaC,EAAyBkD,IAAeC,KAAeX,GAAK5E,MAAAA,CAAAA,GAE1E6B,GAAQQ,MAAAA;AAChB;AAGO,SAASmD,EAAuB1F,IAAAA;AACtC,MAAI2D,EAAgB3D,GAAMyD,SAAAA,EACzB,QAAOnC,EAAoBtB,IAAOA,GAAMyD,SAAAA;AAEzC,MAAIW,EAAYpE,GAAMyD,SAAAA,EAAY,QAAO;AACzC,MAAI1C,EAAYf,GAAMyD,SAAAA,EAAY,QAAO;AAEzC,QAAM1B,KAAU/B,GAAMgC,YAAY,OAAA;AAClCuD,IAAwBvF,IAAO+B,EAAAA;AAE/B,QAAMZ,KAAQC,EAAepB,GAAMyD,WAAWzD,GAAM0D,cAAAA,CAAAA;AAGpD,SAFA3B,GAAQM,aAAaC,EAAyBnB,GAAME,KAAKL,SAASG,GAAME,KAAKH,MAAAA,CAAAA,GAEtEa,GAAQQ,MAAAA;AAChB;AAGO,SAASoD,EAAkB3F;AACjC,QAAMa,KAAMb,GAAMyD;AAGlB,MAAIE,EAAgB9C,IACnB,SF1FK,SACNb,IACAa,IAAAA;AAEA,UAAMU,KAAOC,EAAaxB,GAAMG,KAAKU,GAAIY,MAAAA;AACzC,QAAA,CAAKF,GAAM,QAAO;AAElB,UAAMtB,KAAwBsB,GAAKrB,SAAS,IAAKqB,GAAKG,MAAM,GAAA,EAAG,IAAoB,CAAA,GAG7EE,KAFW7B,EAAYC,IAAOC,EAAAA,EAEL4B,UAAWC,CAAAA,OAAM,QAAQA,MAAKA,GAAEtB,OAAOK,GAAIY,MAAAA;AAC1E,QAAIG,KAAQ,EAAG,QAAO;AAEtB,UAAMK,KAAQC,EAAAA,GACRH,KAAU/B,GAAMgC,YAAY;AAGlC,WAFAD,GAAQI,WAAWlC,IAAY2B,KAAQ,GAAGrB,EAAqB0B,EAAAA,CAAAA,GAC/DF,GAAQM,aAAaC,EAAyBL,IAAO,CAAA,CAAA,GAC9CF,GAAQQ;EAChB,GEwE2CvC,IAAOa,EAAAA;AAIjD,MAAIuD,EAAYvD,IACf,SDtEK,SACNb,IACAa,IAAAA;AAEA,UAAMU,KAAOC,EAAaxB,GAAMG,KAAKU,GAAIG,OAAAA;AACzC,QAAA,CAAKO,GAAM,QAAO;AAElB,UAAMtB,KAAwBsB,GAAKrB,SAAS,IAAKqB,GAAKG,MAAM,GAAA,EAAG,IAAoB,CAAA,GAG7EE,KAFW7B,EAAYC,IAAOC,EAAAA,EAEL4B,UAAWC,CAAAA,OAAM,QAAQA,MAAKA,GAAEtB,OAAOK,GAAIG,OAAAA;AAC1E,QAAIY,KAAQ,EAAG,QAAO;AAEtB,UAAMoD,KAAiC,aAAbnE,GAAI6D,OAAoB9C,KAAQA,KAAQ,GAC5DK,KAAQC,EAAAA,GACRH,KAAU/B,GAAMgC,YAAY;AAGlC,WAFAD,GAAQI,WAAWlC,IAAY+E,IAAWzE,EAAqB0B,MAC/DF,GAAQM,aAAaC,EAAyBL,IAAO,CAAA,CAAA,GAC9CF,GAAQQ;EAChB,GCmD8BvC,IAAOa,EAAAA;AAGpC,QAAMkB,KAAU/B,GAAMgC,YAAY,OAAA;AAE7BjB,IAAYF,EAAAA,KAChB0E,EAAwBvF,IAAO+B;AAGhC,QAAA,EAAMf,SAAEA,YAASE,GAAAA,IAAWN,EAAmBC,IAAKb,GAAM0D,cAAAA,CAAAA,GACpDkC,KAAa1D,EAAAA;AAOnB,SAHAH,GAAQ8D,WAAW7E,IAASE,IAAQ0E,EAAAA,GACpC7D,GAAQM,aAAaC,EAAyBsD,IAAY,KAEnD7D,GAAQQ,MAAAA;AAChB;AAGO,SAASuD,EAAuB9F,IAAAA;AACtC,QAAMa,KAAMb,GAAMyD;AAElB,MAAIE,EAAgB9C,EAAAA,KAAQuD,EAAYvD,EAAAA,EAAM,QAAO;AAErD,QAAMkB,KAAU/B,GAAMgC,YAAY,OAAA;AAE7BjB,IAAYF,EAAAA,KAChB0E,EAAwBvF,IAAO+B,EAAAA;AAGhC,UAAQf,SAASwE,IAAetE,QAAQuE,GAAAA,IAAiB7E,EACxDC,IACAb,GAAM0D,cAAAA,CAAAA,GAGDqC,KAAYC,EAAiBC,EAAW,YAAA,CAAA;AAI9C,SAHAlE,GAAQmE,iBAAiBV,IAAeC,IAAcM,EAAAA,GACtDhE,GAAQM,aAAaC,EAAyBkD,IAAeC,KAAe,CAAA,CAAA,GAErE1D,GAAQQ,MAAAA;AAChB;AAMO,SAAS4D,EAAmBnG,IAAAA;AAClC,QAAMa,KAAMb,GAAMyD;AAClB,MAAIE,EAAgB9C,EAAAA,KAAQuD,EAAYvD,EAAAA,EAAM,QAAO;AACrD,QAAMC,KAAad,GAAM0D,cAAAA,GACnBW,KAAWvD,GAAW+C,QAAQhD,GAAII,OAAOD,OAAAA;AAE/C,MAAIqD,MAAY,EAAG,QAAO;AAE1B,QAAM+B,KAActF,GAAWuD,KAAW,CAAA;AAC1C,MAAA,CAAK+B,GAAa,QAAO;AAGzB,MAAIC,EAAiBrG,IAAOa,GAAII,OAAOD,YAAYqF,EAAiBrG,IAAOoG,EAAAA,EAC1E,QAAO;AAIR,MAAA,CAAKE,EAAatG,IAAOa,GAAII,OAAOD,SAASoF,EAAAA,KACxCG,EAAkBvG,IAAOa,GAAII,OAAOD,OAAAA,EAAU,QAAO;AAI1D,MAAIgD,EAAYhE,IAAOoG,EAAAA,GAAc;AACpC,UAAM7E,KAAOC,EAAaxB,GAAMG,KAAKiG,EAAAA,KAAgB,CAAA;AACrD,WAAOpG,GACLgC,YAAY,OAAA,EACZK,aAAamC,EAAoB4B,IAAa7E,EAAAA,CAAAA,EAC9CgB,MAAAA;AAAAA,EACH;AAEA,QAAM2B,KAAYlE,GAAMM,SAAS8F,EAAAA;AACjC,MAAA,CAAKlC,GAAW,QAAO;AACvB,QAAMjB,KAAUC,EAAegB,EAAAA;AAE/B,SAAOlE,GACLgC,YAAY,OAAA,EACZwE,cAAcJ,IAAavF,GAAII,OAAOD,OAAAA,EACtCqB,aAAaC,EAAyB8D,IAAanD,EAAAA,CAAAA,EACnDV,MAAAA;AACH;AAMO,SAASkE,EAAkBzG,IAAAA;AACjC,QAAMa,KAAMb,GAAMyD;AAClB,MAAIE,EAAgB9C,EAAAA,KAAQuD,EAAYvD,EAAAA,EAAM,QAAO;AACrD,QAAMC,KAAad,GAAM0D,cAAAA,GACnBW,KAAWvD,GAAW+C,QAAQhD,GAAII,OAAOD,OAAAA;AAE/C,MAAIqD,MAAYvD,GAAWZ,SAAS,EAAG,QAAO;AAE9C,QAAMwG,KAAc5F,GAAWuD,KAAW,CAAA;AAC1C,OAAKqC,GAAa,QAAO;AAGzB,MAAIL,EAAiBrG,IAAOa,GAAII,OAAOD,OAAAA,KAAYqF,EAAiBrG,IAAO0G,EAAAA,EAC1E,QAAO;AAIR,MAAA,CAAKJ,EAAatG,IAAOa,GAAII,OAAOD,SAAS0F,EAAAA,KACxCH,EAAkBvG,IAAOa,GAAII,OAAOD,OAAAA,EAAU,QAAO;AAI1D,MAAIgD,EAAYhE,IAAO0G,EAAAA,GAAc;AACpC,UAAMnF,KAAOC,EAAaxB,GAAMG,KAAKuG,EAAAA,KAAgB,CAAA;AACrD,WAAO1G,GACLgC,YAAY,OAAA,EACZK,aAAamC,EAAoBkC,IAAanF,EAAAA,CAAAA,EAC9CgB,MAAAA;AAAAA,EACH;AAEA,SAAOvC,GACLgC,YAAY,OAAA,EACZwE,cAAc3F,GAAII,OAAOD,SAAS0F,EAAAA,EAClCrE,aAAaC,EAAyBzB,GAAII,OAAOD,SAASH,GAAII,OAAOC,MAAAA,CAAAA,EACrEqB,MAAAA;AACH;AAGO,SAASoE,EAAU3G,IAAAA;AACzB,QAAM4G,KAAS5G,GAAMG,IAAIC,UACnByG,KAAaD,GAAO,CAAA,GACpBE,KAAYF,GAAOA,GAAO1G,SAAS;AACzC,MAAA,CAAK2G,MAAAA,CAAeC,GACnB,QAAO9G,GAAMgC,YAAY,WAAWK,aAAarC,GAAMyD,SAAAA,EAAWlB,MAAAA;AACnE,QAAMwE,KAAe7D,EAAe4D,EAAAA;AAEpC,SAAO9G,GACLgC,YAAY,SAAA,EACZK,aACA2E,EACC,EAAEhG,SAAS6F,GAAWrG,IAAIU,QAAQ,EAAA,GAClC,EAAEF,SAAS8F,GAAUtG,IAAIU,QAAQ6F,GAAAA,CAAAA,CAAAA,EAGlCxE,MAAAA;AACH;AAcO,SAASgD,EAAwBvF,IAAoB+B,IAAAA;AAC3D,MAAI4B,EAAgB3D,GAAMyD,SAAAA,KAAcW,EAAYpE,GAAMyD,SAAAA,EAAY;AACtE,QAAM3C,KAAad,GAAM0D,cAAAA,GACnBvC,KAAQC,EAAepB,GAAMyD,WAAW3C,EAAAA,GACxCmG,KAAUnG,GAAW+C,QAAQ1C,GAAME,KAAKL,OAAAA,GACxCkG,KAAQpG,GAAW+C,QAAQ1C,GAAMgG,GAAGnG,OAAAA;AAE1C,MAAIiG,OAAYC,GACfnF,CAAAA,GAAQqF,aAAajG,GAAME,KAAKL,SAASG,GAAME,KAAKH,QAAQC,GAAMgG,GAAGjG,MAAAA;AAAAA,OAC/D;AACN,UAAM2F,KAAa7G,GAAMM,SAASa,GAAME,KAAKL,OAAAA;AAC7C,QAAA,CAAK6F,GAAY;AACjB,UAAMQ,KAAWnE,EAAe2D,EAAAA;AAG5B1F,IAAAA,GAAME,KAAKH,SAASmG,MACvBtF,GAAQqF,aAAajG,GAAME,KAAKL,SAASG,GAAME,KAAKH,QAAQmG,EAAAA,GAIzDlG,GAAMgG,GAAGjG,SAAS,KACrBa,GAAQqF,aAAajG,GAAMgG,GAAGnG,SAAS,GAAGG,GAAMgG,GAAGjG,MAAAA;AAIpD,aAAS4B,KAAImE,KAAU,GAAGnE,KAAIoE,IAAOpE,MAAK;AACzC,YAAMwE,KAAaxG,GAAWgC,EAAAA;AAC9B,UAAA,CAAKwE,GAAY;AACjB,YAAMC,KAAWvH,GAAMM,SAASgH,EAAAA;AAChC,UAAA,CAAKC,GAAU;AACf,YAAMC,KAAStE,EAAeqE,EAAAA;AAC1BC,MAAAA,KAAS,KACZzF,GAAQqF,aAAaE,IAAY,GAAGE,EAAAA,GAErCzF,GAAQyE,cAAcrF,GAAME,KAAKL,SAASsG,EAAAA;AAAAA,IAC3C;AAGAvF,IAAAA,GAAQyE,cAAcrF,GAAME,KAAKL,SAASG,GAAMgG,GAAGnG,OAAAA;AAAAA,EACpD;AACD;AC/VO,MAAMyG;EACHjH,KAAK;AAAA,EACLkH,OAAO;AAAA,EACPC,WAAW;AAAA,EAEpB,KAAKC,IAAAA;AACJC,SAAKC,uBAAuBF,EAAAA,GAC5BC,KAAKE,iBAAiBH,EAAAA,GACtBC,KAAKG,eAAeJ,EAAAA;AAAAA,EACrB;AAAA,EAEQ,uBAAuBA,IAAAA;AAC9BA,IAAAA,GAAQE,uBAAuB,EAC9BG,MAAM,cACNC,OAAA,MACQC,SAASC,cAAc,IAAA,GAE/BC,cAAA,MACQ,QAERC,WAAW,CAAC,EAAEC,KAAK,KAAA,CAAA,GACnBC,UAAU,EAAEC,MAAM,CAAC,IAAA,EAAA,EAAA,CAAA;AAAA,EAErB;AAAA,EAEQ,iBAAiBb,IAAAA;AACxBA,IAAAA,GAAQc,gBAAgB,mBAAmB,MAAA;AAC1C,YACMC,KAAK7C,EADG8B,GAAQgB,SAAAA,CAAAA;AAEtB,aAAA,CAAA,CAAKD,OACLf,GAAQiB,SAASF,EAAAA,GAAAA;AAAAA;EAGnB;AAAA,EAEQ,eAAef,IAAAA;AACtBA,IAAAA,GAAQI,eAAe,EACtB,eAAe,MAAA;AACd,YACMW,KAAK7C,EADG8B,GAAQgB;AAEtB,aAAA,CAAA,CAAKD,OACLf,GAAQiB,SAASF,EAAAA,GAAAA;AAAAA,IACV,EAAA,CAAA;AAAA,EAGV;;"}
1
+ {"version":3,"file":"index-ErZ5_a1o.mjs","sources":["../../src/commands/CommandHelpers.ts","../../src/commands/NodeSelectionCommands.ts","../../src/commands/GapCursorCommands.ts","../../src/commands/Commands.ts","../../src/plugins/hard-break/HardBreakPlugin.ts"],"sourcesContent":["/**\n * Shared helpers used across multiple command modules.\n *\n * - {@link getSiblings} — resolves a parent path to its child list\n * - {@link createEmptyParagraph} — builds an empty paragraph BlockNode\n * - {@link resolveInsertPoint} — normalizes a text selection to a single insert position\n */\n\nimport type { BlockNode, ChildNode } from '../model/Document.js';\nimport { createBlockNode, createTextNode } from '../model/Document.js';\nimport { isCollapsed, selectionRange } from '../model/Selection.js';\nimport type { Selection } from '../model/Selection.js';\nimport type { BlockId } from '../model/TypeBrands.js';\nimport { nodeType } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\n\n/** The resolved insert position within a single block. */\nexport interface InsertPoint {\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n}\n\n/** Resolves the children of a parent path: doc root or a nested block. */\nexport function getSiblings(\n\tstate: EditorState,\n\tparentPath: readonly BlockId[],\n): readonly ChildNode[] {\n\tif (parentPath.length === 0) return state.doc.children;\n\tconst parent: BlockNode | undefined = state.getBlock(\n\t\tparentPath[parentPath.length - 1] as BlockId,\n\t);\n\treturn parent ? parent.children : [];\n}\n\n/** Creates an empty paragraph block node with the given ID. */\nexport function createEmptyParagraph(id: BlockId): BlockNode {\n\treturn createBlockNode(nodeType('paragraph'), [createTextNode('')], id);\n}\n\n/**\n * Normalizes a text selection to a single insert point.\n *\n * - Collapsed selection → anchor position.\n * - Range selection → normalized `from` position (document-order start).\n */\nexport function resolveInsertPoint(sel: Selection, blockOrder: readonly BlockId[]): InsertPoint {\n\tif (isCollapsed(sel)) {\n\t\treturn { blockId: sel.anchor.blockId, offset: sel.anchor.offset };\n\t}\n\tconst range = selectionRange(sel, blockOrder);\n\treturn { blockId: range.from.blockId, offset: range.from.offset };\n}\n","/**\n * Commands for NodeSelection: deleting void blocks, inserting paragraphs\n * after void blocks, and navigating arrow keys into/out of void blocks.\n */\n\nimport { type BlockNode, generateBlockId, getBlockLength, isBlockNode } from '../model/Document.js';\nimport { isVoidBlock } from '../model/NavigationUtils.js';\nimport { findNodePath } from '../model/NodeResolver.js';\nimport type { NodeSelection } from '../model/Selection.js';\nimport {\n\tcreateCollapsedSelection,\n\tcreateGapCursor,\n\tcreateNodeSelection,\n\tisCollapsed,\n\tisGapCursor,\n\tisNodeSelection,\n} from '../model/Selection.js';\nimport type { BlockId } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport { createEmptyParagraph, getSiblings } from './CommandHelpers.js';\n\n/**\n * Deletes the void block targeted by a NodeSelection and places cursor\n * on the adjacent block. If it's the only block, replaces with empty paragraph.\n */\nexport function deleteNodeSelection(state: EditorState, sel: NodeSelection): Transaction | null {\n\tconst path = findNodePath(state.doc, sel.nodeId);\n\tif (!path) return null;\n\n\tconst parentPath: BlockId[] = path.length > 1 ? (path.slice(0, -1) as BlockId[]) : [];\n\tconst siblings = getSiblings(state, parentPath);\n\n\tconst index: number = siblings.findIndex((c) => 'id' in c && c.id === sel.nodeId);\n\tif (index < 0) return null;\n\n\tconst builder = state.transaction('input');\n\n\t// If this is the only block in the document, insert empty paragraph first\n\tif (siblings.length === 1 && parentPath.length === 0) {\n\t\tconst newId = generateBlockId();\n\t\tbuilder.insertNode(parentPath, 0, createEmptyParagraph(newId));\n\t\tbuilder.removeNode(parentPath, 1);\n\t\tbuilder.setSelection(createCollapsedSelection(newId, 0));\n\t\treturn builder.build();\n\t}\n\n\tbuilder.removeNode(parentPath, index);\n\n\t// Find where to place cursor: prefer previous sibling leaf, else next sibling leaf.\n\tconst prevSibling = siblings[index - 1];\n\tif (prevSibling && isBlockNode(prevSibling)) {\n\t\tconst prevLeafId = findLastLeafBlockId(prevSibling);\n\t\tif (prevLeafId) {\n\t\t\tconst prevLeaf = state.getBlock(prevLeafId);\n\t\t\tconst prevLen = prevLeaf ? getBlockLength(prevLeaf) : 0;\n\t\t\tbuilder.setSelection(createCollapsedSelection(prevLeafId, prevLen));\n\t\t}\n\t} else {\n\t\tconst nextSibling = siblings[index + 1];\n\t\tif (nextSibling && isBlockNode(nextSibling)) {\n\t\t\tconst nextLeafId = findFirstLeafBlockId(nextSibling);\n\t\t\tif (nextLeafId) {\n\t\t\t\tbuilder.setSelection(createCollapsedSelection(nextLeafId, 0));\n\t\t\t}\n\t\t}\n\t}\n\n\treturn builder.build();\n}\n\n/** Inserts a new paragraph after a NodeSelection-targeted void block. */\nexport function insertParagraphAfterNodeSelection(\n\tstate: EditorState,\n\tsel: NodeSelection,\n): Transaction | null {\n\tconst path = findNodePath(state.doc, sel.nodeId);\n\tif (!path) return null;\n\n\tconst parentPath: BlockId[] = path.length > 1 ? (path.slice(0, -1) as BlockId[]) : [];\n\tconst siblings = getSiblings(state, parentPath);\n\n\tconst index: number = siblings.findIndex((c) => 'id' in c && c.id === sel.nodeId);\n\tif (index < 0) return null;\n\n\tconst newId = generateBlockId();\n\tconst builder = state.transaction('input');\n\tbuilder.insertNode(parentPath, index + 1, createEmptyParagraph(newId));\n\tbuilder.setSelection(createCollapsedSelection(newId, 0));\n\treturn builder.build();\n}\n\n/** Inserts text in a new paragraph after a NodeSelection-targeted void block. */\nexport function insertTextAfterNodeSelection(\n\tstate: EditorState,\n\tsel: NodeSelection,\n\ttext: string,\n\torigin: 'input' | 'paste',\n): Transaction {\n\tconst path = findNodePath(state.doc, sel.nodeId);\n\tconst parentPath: BlockId[] = path && path.length > 1 ? (path.slice(0, -1) as BlockId[]) : [];\n\tconst siblings = getSiblings(state, parentPath);\n\n\tconst index: number = siblings.findIndex((c) => 'id' in c && c.id === sel.nodeId);\n\n\tconst newId = generateBlockId();\n\tconst builder = state.transaction(origin);\n\n\tconst insertIdx = index >= 0 ? index + 1 : siblings.length;\n\tbuilder.insertNode(parentPath, insertIdx, createEmptyParagraph(newId));\n\tbuilder.insertText(newId, 0, text, []);\n\tbuilder.setSelection(createCollapsedSelection(newId, text.length));\n\treturn builder.build();\n}\n\n/**\n * Navigates arrow keys into/out of void blocks.\n * Returns a transaction if navigation should create a NodeSelection, or null.\n */\nexport function navigateArrowIntoVoid(\n\tstate: EditorState,\n\tdirection: 'left' | 'right' | 'up' | 'down',\n): Transaction | null {\n\tconst sel = state.selection;\n\tconst blockOrder = state.getBlockOrder();\n\n\t// If currently on a NodeSelection, navigate away from it\n\tif (isNodeSelection(sel)) {\n\t\treturn navigateAwayFromNodeSelection(state, sel, direction, blockOrder);\n\t}\n\n\t// GapCursor is handled by navigateFromGapCursor in CaretNavigation\n\tif (isGapCursor(sel)) return null;\n\n\t// Text selection: check if navigating into a void block\n\tif (!isCollapsed(sel)) return null;\n\n\treturn navigateIntoVoid(state, sel, direction, blockOrder);\n}\n\n/** Finds the first leaf (deepest-first-child) block ID in a subtree. */\nexport function findFirstLeafBlockId(node: BlockNode): BlockId {\n\tlet current: BlockNode = node;\n\twhile (true) {\n\t\tconst firstBlockChild = current.children.find((child): child is BlockNode =>\n\t\t\tisBlockNode(child),\n\t\t);\n\t\tif (!firstBlockChild) return current.id;\n\t\tcurrent = firstBlockChild;\n\t}\n}\n\n/** Finds the last leaf (deepest-last-child) block ID in a subtree. */\nexport function findLastLeafBlockId(node: BlockNode): BlockId {\n\tlet current: BlockNode = node;\n\twhile (true) {\n\t\tlet lastBlockChild: BlockNode | undefined;\n\t\tfor (let i = current.children.length - 1; i >= 0; i--) {\n\t\t\tconst child = current.children[i];\n\t\t\tif (child && isBlockNode(child)) {\n\t\t\t\tlastBlockChild = child;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif (!lastBlockChild) return current.id;\n\t\tcurrent = lastBlockChild;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Handles navigation away from a NodeSelection (arrow keys while void is selected). */\nfunction navigateAwayFromNodeSelection(\n\tstate: EditorState,\n\tsel: NodeSelection,\n\tdirection: 'left' | 'right' | 'up' | 'down',\n\tblockOrder: readonly BlockId[],\n): Transaction | null {\n\tconst nodeIdx = blockOrder.indexOf(sel.nodeId);\n\tconst nodePath = (findNodePath(state.doc, sel.nodeId) ?? []) as BlockId[];\n\n\tif (direction === 'left' || direction === 'up') {\n\t\tif (nodeIdx > 0) {\n\t\t\tconst prevId = blockOrder[nodeIdx - 1];\n\t\t\tif (!prevId) return null;\n\t\t\tif (isVoidBlock(state, prevId)) {\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.setSelection(createGapCursor(sel.nodeId, 'before', nodePath))\n\t\t\t\t\t.build();\n\t\t\t}\n\t\t\tconst prevBlock = state.getBlock(prevId);\n\t\t\tconst prevLen = prevBlock ? getBlockLength(prevBlock) : 0;\n\t\t\treturn state\n\t\t\t\t.transaction('input')\n\t\t\t\t.setSelection(createCollapsedSelection(prevId, prevLen))\n\t\t\t\t.build();\n\t\t}\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(createGapCursor(sel.nodeId, 'before', nodePath))\n\t\t\t.build();\n\t}\n\n\t// right or down\n\tif (nodeIdx < blockOrder.length - 1) {\n\t\tconst nextId = blockOrder[nodeIdx + 1];\n\t\tif (!nextId) return null;\n\t\tif (isVoidBlock(state, nextId)) {\n\t\t\treturn state\n\t\t\t\t.transaction('input')\n\t\t\t\t.setSelection(createGapCursor(sel.nodeId, 'after', nodePath))\n\t\t\t\t.build();\n\t\t}\n\t\treturn state.transaction('input').setSelection(createCollapsedSelection(nextId, 0)).build();\n\t}\n\treturn state\n\t\t.transaction('input')\n\t\t.setSelection(createGapCursor(sel.nodeId, 'after', nodePath))\n\t\t.build();\n}\n\n/** Handles text selection navigating into an adjacent void block. */\nfunction navigateIntoVoid(\n\tstate: EditorState,\n\tsel: { readonly anchor: { readonly blockId: BlockId; readonly offset: number } },\n\tdirection: 'left' | 'right' | 'up' | 'down',\n\tblockOrder: readonly BlockId[],\n): Transaction | null {\n\tconst blockIdx = blockOrder.indexOf(sel.anchor.blockId);\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return null;\n\tconst blockLen = getBlockLength(block);\n\n\tif (direction === 'right' || direction === 'down') {\n\t\tif (sel.anchor.offset === blockLen && blockIdx < blockOrder.length - 1) {\n\t\t\tconst nextId = blockOrder[blockIdx + 1];\n\t\t\tif (nextId && isVoidBlock(state, nextId)) {\n\t\t\t\tconst path = findNodePath(state.doc, nextId) ?? [];\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.setSelection(createNodeSelection(nextId, path as BlockId[]))\n\t\t\t\t\t.build();\n\t\t\t}\n\t\t}\n\t}\n\n\tif (direction === 'left' || direction === 'up') {\n\t\tif (sel.anchor.offset === 0 && blockIdx > 0) {\n\t\t\tconst prevId = blockOrder[blockIdx - 1];\n\t\t\tif (prevId && isVoidBlock(state, prevId)) {\n\t\t\t\tconst path = findNodePath(state.doc, prevId) ?? [];\n\t\t\t\treturn state\n\t\t\t\t\t.transaction('input')\n\t\t\t\t\t.setSelection(createNodeSelection(prevId, path as BlockId[]))\n\t\t\t\t\t.build();\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n","/**\n * Commands for GapCursor: deleting void blocks adjacent to gap cursors\n * and inserting paragraphs at gap positions.\n */\n\nimport { generateBlockId, getBlockLength } from '../model/Document.js';\nimport { isVoidBlock } from '../model/NavigationUtils.js';\nimport { findNodePath } from '../model/NodeResolver.js';\nimport type { GapCursorSelection, NodeSelection } from '../model/Selection.js';\nimport { createCollapsedSelection, createNodeSelection } from '../model/Selection.js';\nimport type { BlockId } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport { createEmptyParagraph, getSiblings } from './CommandHelpers.js';\nimport { deleteNodeSelection } from './NodeSelectionCommands.js';\n\n/**\n * Deletes the void block adjacent to a GapCursor when pressing Backspace.\n *\n * - `side === 'after'` → void block is behind the cursor → delete it.\n * - `side === 'before'` → void block is ahead → navigate backward (to previous block).\n * - At document start with `side === 'before'` → `null` (no-op).\n */\nexport function deleteBackwardAtGap(\n\tstate: EditorState,\n\tsel: GapCursorSelection,\n): Transaction | null {\n\tif (sel.side === 'after') {\n\t\treturn deleteVoidAtGap(state, sel);\n\t}\n\n\t// side === 'before': navigate to previous block\n\tconst blockOrder: readonly BlockId[] = state.getBlockOrder();\n\tconst blockIdx: number = blockOrder.indexOf(sel.blockId);\n\n\tif (blockIdx <= 0) return null;\n\n\tconst prevId: BlockId | undefined = blockOrder[blockIdx - 1];\n\tif (!prevId) return null;\n\n\tif (isVoidBlock(state, prevId)) {\n\t\tconst path = findNodePath(state.doc, prevId) ?? [];\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(createNodeSelection(prevId, path as BlockId[]))\n\t\t\t.build();\n\t}\n\n\tconst prevBlock = state.getBlock(prevId);\n\tif (!prevBlock) return null;\n\tconst prevLen: number = getBlockLength(prevBlock);\n\treturn state.transaction('input').setSelection(createCollapsedSelection(prevId, prevLen)).build();\n}\n\n/**\n * Deletes the void block adjacent to a GapCursor when pressing Delete.\n *\n * - `side === 'before'` → void block is ahead of the cursor → delete it.\n * - `side === 'after'` → void block is behind → navigate forward (to next block).\n * - At document end with `side === 'after'` → `null` (no-op).\n */\nexport function deleteForwardAtGap(\n\tstate: EditorState,\n\tsel: GapCursorSelection,\n): Transaction | null {\n\tif (sel.side === 'before') {\n\t\treturn deleteVoidAtGap(state, sel);\n\t}\n\n\t// side === 'after': navigate to next block\n\tconst blockOrder: readonly BlockId[] = state.getBlockOrder();\n\tconst blockIdx: number = blockOrder.indexOf(sel.blockId);\n\n\tif (blockIdx >= blockOrder.length - 1) return null;\n\n\tconst nextId: BlockId | undefined = blockOrder[blockIdx + 1];\n\tif (!nextId) return null;\n\n\tif (isVoidBlock(state, nextId)) {\n\t\tconst path = findNodePath(state.doc, nextId) ?? [];\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(createNodeSelection(nextId, path as BlockId[]))\n\t\t\t.build();\n\t}\n\n\treturn state.transaction('input').setSelection(createCollapsedSelection(nextId, 0)).build();\n}\n\n/** Deletes the void block that the GapCursor is adjacent to, delegating to deleteNodeSelection. */\nfunction deleteVoidAtGap(state: EditorState, sel: GapCursorSelection): Transaction | null {\n\tconst path = (findNodePath(state.doc, sel.blockId) ?? []) as BlockId[];\n\tconst nodeSel: NodeSelection = createNodeSelection(sel.blockId, path);\n\treturn deleteNodeSelection(state, nodeSel);\n}\n\n/** Inserts a new paragraph at a GapCursor position (before or after the void block). */\nexport function insertParagraphAtGap(\n\tstate: EditorState,\n\tsel: GapCursorSelection,\n): Transaction | null {\n\tconst path = findNodePath(state.doc, sel.blockId);\n\tif (!path) return null;\n\n\tconst parentPath: BlockId[] = path.length > 1 ? (path.slice(0, -1) as BlockId[]) : [];\n\tconst siblings = getSiblings(state, parentPath);\n\n\tconst index: number = siblings.findIndex((c) => 'id' in c && c.id === sel.blockId);\n\tif (index < 0) return null;\n\n\tconst insertIdx: number = sel.side === 'before' ? index : index + 1;\n\tconst newId = generateBlockId();\n\tconst builder = state.transaction('input');\n\tbuilder.insertNode(parentPath, insertIdx, createEmptyParagraph(newId));\n\tbuilder.setSelection(createCollapsedSelection(newId, 0));\n\treturn builder.build();\n}\n\n/** Inserts text in a new paragraph at a GapCursor position. */\nexport function insertTextAtGap(\n\tstate: EditorState,\n\tsel: GapCursorSelection,\n\ttext: string,\n\torigin: 'input' | 'paste',\n): Transaction {\n\tconst path = findNodePath(state.doc, sel.blockId);\n\tconst parentPath: BlockId[] = path && path.length > 1 ? (path.slice(0, -1) as BlockId[]) : [];\n\tconst siblings = getSiblings(state, parentPath);\n\n\tconst index: number = siblings.findIndex((c) => 'id' in c && c.id === sel.blockId);\n\tconst insertIdx: number =\n\t\tsel.side === 'before' ? Math.max(index, 0) : index >= 0 ? index + 1 : siblings.length;\n\n\tconst newId = generateBlockId();\n\tconst builder = state.transaction(origin);\n\tbuilder.insertNode(parentPath, insertIdx, createEmptyParagraph(newId));\n\tbuilder.insertText(newId, 0, text, []);\n\tbuilder.setSelection(createCollapsedSelection(newId, text.length));\n\treturn builder.build();\n}\n","/**\n * Core editor commands and barrel re-exports from submodules.\n *\n * This module contains text insertion, block splitting, block merging,\n * selection deletion, and select-all. Mark, delete, gap-cursor, node-selection,\n * and word-boundary commands are re-exported from their respective modules.\n */\n\nimport {\n\ttype Mark,\n\tcreateInlineNode,\n\tgenerateBlockId,\n\tgetBlockLength,\n\tgetBlockMarksAtOffset,\n} from '../model/Document.js';\nimport {\n\tisInsideIsolating,\n\tisIsolatingBlock,\n\tisVoidBlock,\n\tsharesParent,\n} from '../model/NavigationUtils.js';\nimport { findNodePath } from '../model/NodeResolver.js';\nimport {\n\tcreateCollapsedSelection,\n\tcreateNodeSelection,\n\tcreateSelection,\n\tisCollapsed,\n\tisGapCursor,\n\tisNodeSelection,\n\tselectionRange,\n} from '../model/Selection.js';\nimport { type BlockId, inlineType } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\nimport type { Transaction } from '../state/Transaction.js';\nimport type { TransactionBuilder } from '../state/Transaction.js';\nimport { resolveInsertPoint } from './CommandHelpers.js';\nimport { insertParagraphAtGap, insertTextAtGap } from './GapCursorCommands.js';\nimport {\n\tdeleteNodeSelection,\n\tinsertParagraphAfterNodeSelection,\n\tinsertTextAfterNodeSelection,\n} from './NodeSelectionCommands.js';\n\n// --- Re-exports from submodules ---\n\nexport {\n\tcanCrossBlockBoundary,\n\tisInsideIsolating,\n\tisIsolatingBlock,\n\tisVoidBlock,\n\tsharesParent,\n} from '../model/NavigationUtils.js';\n\nexport type { FeatureConfig } from './MarkCommands.js';\nexport {\n\tisMarkActive,\n\ttoggleBold,\n\ttoggleItalic,\n\ttoggleMark,\n\ttoggleUnderline,\n} from './MarkCommands.js';\n\nexport {\n\tdeleteBackward,\n\tdeleteForward,\n\tdeleteSoftLineBackward,\n\tdeleteSoftLineForward,\n\tdeleteWordBackward,\n\tdeleteWordForward,\n} from './DeleteCommands.js';\n\nexport {\n\tdeleteNodeSelection,\n\tfindFirstLeafBlockId,\n\tfindLastLeafBlockId,\n\tinsertParagraphAfterNodeSelection,\n\tinsertTextAfterNodeSelection,\n\tnavigateArrowIntoVoid,\n} from './NodeSelectionCommands.js';\n\nexport {\n\tdeleteBackwardAtGap,\n\tdeleteForwardAtGap,\n\tinsertParagraphAtGap,\n\tinsertTextAtGap,\n} from './GapCursorCommands.js';\n\nexport {\n\tfindWordBoundaryBackward,\n\tfindWordBoundaryForward,\n} from './WordBoundary.js';\n\nexport {\n\tapplyAttributedMark,\n\tgetMarkAttrAtSelection,\n\tisAttributedMarkActive,\n\tremoveAttributedMark,\n} from './AttributedMarkCommands.js';\n\nexport { forEachBlockInRange } from './RangeIterator.js';\n\n// --- Text Commands ---\n\n/** Inserts text at the current selection, replacing any selected range. */\nexport function insertTextCommand(\n\tstate: EditorState,\n\ttext: string,\n\torigin: 'input' | 'paste' = 'input',\n): Transaction {\n\tconst sel = state.selection;\n\n\t// NodeSelection: insert paragraph after void block with the text\n\tif (isNodeSelection(sel)) {\n\t\treturn insertTextAfterNodeSelection(state, sel, text, origin);\n\t}\n\n\t// GapCursor: insert paragraph at the gap position with the text\n\tif (isGapCursor(sel)) {\n\t\treturn insertTextAtGap(state, sel, text, origin);\n\t}\n\n\tconst builder = state.transaction(origin);\n\tconst marks = resolveActiveMarks(state);\n\n\tif (!isCollapsed(sel)) {\n\t\taddDeleteSelectionSteps(state, builder);\n\t}\n\n\tconst { blockId: insertBlockId, offset: insertOffset } = resolveInsertPoint(\n\t\tsel,\n\t\tstate.getBlockOrder(),\n\t);\n\n\tbuilder.insertText(insertBlockId, insertOffset, text, marks);\n\tbuilder.setSelection(createCollapsedSelection(insertBlockId, insertOffset + text.length));\n\n\treturn builder.build();\n}\n\n/** Deletes the current selection. */\nexport function deleteSelectionCommand(state: EditorState): Transaction | null {\n\tif (isNodeSelection(state.selection)) {\n\t\treturn deleteNodeSelection(state, state.selection);\n\t}\n\tif (isGapCursor(state.selection)) return null;\n\tif (isCollapsed(state.selection)) return null;\n\n\tconst builder = state.transaction('input');\n\taddDeleteSelectionSteps(state, builder);\n\n\tconst range = selectionRange(state.selection, state.getBlockOrder());\n\tbuilder.setSelection(createCollapsedSelection(range.from.blockId, range.from.offset));\n\n\treturn builder.build();\n}\n\n/** Splits the current block at the cursor position (Enter key). */\nexport function splitBlockCommand(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\n\t// NodeSelection: insert empty paragraph after the void block\n\tif (isNodeSelection(sel)) {\n\t\treturn insertParagraphAfterNodeSelection(state, sel);\n\t}\n\n\t// GapCursor: insert empty paragraph at the gap position\n\tif (isGapCursor(sel)) {\n\t\treturn insertParagraphAtGap(state, sel);\n\t}\n\n\tconst builder = state.transaction('input');\n\n\tif (!isCollapsed(sel)) {\n\t\taddDeleteSelectionSteps(state, builder);\n\t}\n\n\tconst { blockId, offset } = resolveInsertPoint(sel, state.getBlockOrder());\n\tconst newBlockId = generateBlockId();\n\n\t// splitBlock operates at the same level in the tree — the StepApplication\n\t// handles this correctly because it looks up the block by ID recursively.\n\tbuilder.splitBlock(blockId, offset, newBlockId);\n\tbuilder.setSelection(createCollapsedSelection(newBlockId, 0));\n\n\treturn builder.build();\n}\n\n/** Inserts a hard line break (InlineNode) at the current cursor position. */\nexport function insertHardBreakCommand(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return null;\n\n\tconst builder = state.transaction('input');\n\n\tif (!isCollapsed(sel)) {\n\t\taddDeleteSelectionSteps(state, builder);\n\t}\n\n\tconst { blockId: insertBlockId, offset: insertOffset } = resolveInsertPoint(\n\t\tsel,\n\t\tstate.getBlockOrder(),\n\t);\n\n\tconst hardBreak = createInlineNode(inlineType('hard_break'));\n\tbuilder.insertInlineNode(insertBlockId, insertOffset, hardBreak);\n\tbuilder.setSelection(createCollapsedSelection(insertBlockId, insertOffset + 1));\n\n\treturn builder.build();\n}\n\n/**\n * Merges the current block with the previous block, respecting\n * isolating boundaries and void blocks.\n */\nexport function mergeBlockBackward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return null;\n\tconst blockOrder = state.getBlockOrder();\n\tconst blockIdx = blockOrder.indexOf(sel.anchor.blockId);\n\n\tif (blockIdx <= 0) return null;\n\n\tconst prevBlockId = blockOrder[blockIdx - 1];\n\tif (!prevBlockId) return null;\n\n\t// Never merge isolating blocks directly (e.g. table cells).\n\tif (isIsolatingBlock(state, sel.anchor.blockId) || isIsolatingBlock(state, prevBlockId)) {\n\t\treturn null;\n\t}\n\n\t// Prevent merge across isolating boundaries\n\tif (!sharesParent(state, sel.anchor.blockId, prevBlockId)) {\n\t\tif (isInsideIsolating(state, sel.anchor.blockId)) return null;\n\t}\n\n\t// If previous block is void, select it instead of merging\n\tif (isVoidBlock(state, prevBlockId)) {\n\t\tconst path = findNodePath(state.doc, prevBlockId) ?? [];\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(createNodeSelection(prevBlockId, path as BlockId[]))\n\t\t\t.build();\n\t}\n\n\tconst prevBlock = state.getBlock(prevBlockId);\n\tif (!prevBlock) return null;\n\tconst prevLen = getBlockLength(prevBlock);\n\n\treturn state\n\t\t.transaction('input')\n\t\t.mergeBlocksAt(prevBlockId, sel.anchor.blockId)\n\t\t.setSelection(createCollapsedSelection(prevBlockId, prevLen))\n\t\t.build();\n}\n\n/**\n * Merges the next block into the current block, respecting\n * isolating boundaries and void blocks.\n */\nexport function mergeBlockForward(state: EditorState): Transaction | null {\n\tconst sel = state.selection;\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return null;\n\tconst blockOrder = state.getBlockOrder();\n\tconst blockIdx = blockOrder.indexOf(sel.anchor.blockId);\n\n\tif (blockIdx >= blockOrder.length - 1) return null;\n\n\tconst nextBlockId = blockOrder[blockIdx + 1];\n\tif (!nextBlockId) return null;\n\n\t// Never merge isolating blocks directly (e.g. table cells).\n\tif (isIsolatingBlock(state, sel.anchor.blockId) || isIsolatingBlock(state, nextBlockId)) {\n\t\treturn null;\n\t}\n\n\t// Prevent merge across isolating boundaries\n\tif (!sharesParent(state, sel.anchor.blockId, nextBlockId)) {\n\t\tif (isInsideIsolating(state, sel.anchor.blockId)) return null;\n\t}\n\n\t// If next block is void, select it instead of merging\n\tif (isVoidBlock(state, nextBlockId)) {\n\t\tconst path = findNodePath(state.doc, nextBlockId) ?? [];\n\t\treturn state\n\t\t\t.transaction('input')\n\t\t\t.setSelection(createNodeSelection(nextBlockId, path as BlockId[]))\n\t\t\t.build();\n\t}\n\n\treturn state\n\t\t.transaction('input')\n\t\t.mergeBlocksAt(sel.anchor.blockId, nextBlockId)\n\t\t.setSelection(createCollapsedSelection(sel.anchor.blockId, sel.anchor.offset))\n\t\t.build();\n}\n\n/** Selects all content in the editor. */\nexport function selectAll(state: EditorState): Transaction {\n\tconst blocks = state.doc.children;\n\tconst firstBlock = blocks[0];\n\tconst lastBlock = blocks[blocks.length - 1];\n\tif (!firstBlock || !lastBlock)\n\t\treturn state.transaction('command').setSelection(state.selection).build();\n\tconst lastBlockLen = getBlockLength(lastBlock);\n\n\treturn state\n\t\t.transaction('command')\n\t\t.setSelection(\n\t\t\tcreateSelection(\n\t\t\t\t{ blockId: firstBlock.id, offset: 0 },\n\t\t\t\t{ blockId: lastBlock.id, offset: lastBlockLen },\n\t\t\t),\n\t\t)\n\t\t.build();\n}\n\n// --- Internal Helpers ---\n\nfunction resolveActiveMarks(state: EditorState): readonly Mark[] {\n\tif (state.storedMarks) return state.storedMarks;\n\tif (isNodeSelection(state.selection) || isGapCursor(state.selection)) return [];\n\n\tconst block = state.getBlock(state.selection.anchor.blockId);\n\tif (!block) return [];\n\n\treturn getBlockMarksAtOffset(block, state.selection.anchor.offset);\n}\n\nexport function addDeleteSelectionSteps(state: EditorState, builder: TransactionBuilder): void {\n\tif (isNodeSelection(state.selection) || isGapCursor(state.selection)) return;\n\tconst blockOrder = state.getBlockOrder();\n\tconst range = selectionRange(state.selection, blockOrder);\n\tconst fromIdx = blockOrder.indexOf(range.from.blockId);\n\tconst toIdx = blockOrder.indexOf(range.to.blockId);\n\n\tif (fromIdx === toIdx) {\n\t\tbuilder.deleteTextAt(range.from.blockId, range.from.offset, range.to.offset);\n\t} else {\n\t\tconst firstBlock = state.getBlock(range.from.blockId);\n\t\tif (!firstBlock) return;\n\t\tconst firstLen = getBlockLength(firstBlock);\n\n\t\t// Delete from the end of first block\n\t\tif (range.from.offset < firstLen) {\n\t\t\tbuilder.deleteTextAt(range.from.blockId, range.from.offset, firstLen);\n\t\t}\n\n\t\t// Delete from start of last block\n\t\tif (range.to.offset > 0) {\n\t\t\tbuilder.deleteTextAt(range.to.blockId, 0, range.to.offset);\n\t\t}\n\n\t\t// Delete middle blocks entirely and merge last into first\n\t\tfor (let i = fromIdx + 1; i < toIdx; i++) {\n\t\t\tconst midBlockId = blockOrder[i];\n\t\t\tif (!midBlockId) continue;\n\t\t\tconst midBlock = state.getBlock(midBlockId);\n\t\t\tif (!midBlock) continue;\n\t\t\tconst midLen = getBlockLength(midBlock);\n\t\t\tif (midLen > 0) {\n\t\t\t\tbuilder.deleteTextAt(midBlockId, 0, midLen);\n\t\t\t}\n\t\t\tbuilder.mergeBlocksAt(range.from.blockId, midBlockId);\n\t\t}\n\n\t\t// Merge last block into first\n\t\tbuilder.mergeBlocksAt(range.from.blockId, range.to.blockId);\n\t}\n}\n","/**\n * HardBreakPlugin: registers a hard line break (Shift+Enter → `<br>`)\n * as an InlineNode, with command and keymap bindings.\n */\n\nimport { insertHardBreakCommand } from '../../commands/Commands.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface InlineNodeAttrRegistry {\n\t\thard_break: Record<string, never>;\n\t}\n}\n\n// --- Plugin ---\n\nexport class HardBreakPlugin implements Plugin {\n\treadonly id = 'hard-break';\n\treadonly name = 'Hard Break';\n\treadonly priority = 10;\n\n\tinit(context: PluginContext): void {\n\t\tthis.registerInlineNodeSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerKeymap(context);\n\t}\n\n\tprivate registerInlineNodeSpec(context: PluginContext): void {\n\t\tcontext.registerInlineNodeSpec({\n\t\t\ttype: 'hard_break',\n\t\t\ttoDOM() {\n\t\t\t\treturn document.createElement('br');\n\t\t\t},\n\t\t\ttoHTMLString() {\n\t\t\t\treturn '<br>';\n\t\t\t},\n\t\t\tparseHTML: [{ tag: 'br' }],\n\t\t\tsanitize: { tags: ['br'] },\n\t\t});\n\t}\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('insertHardBreak', () => {\n\t\t\tconst state = context.getState();\n\t\t\tconst tr = insertHardBreakCommand(state);\n\t\t\tif (!tr) return false;\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t});\n\t}\n\n\tprivate registerKeymap(context: PluginContext): void {\n\t\tcontext.registerKeymap({\n\t\t\t'Shift-Enter': () => {\n\t\t\t\tconst state = context.getState();\n\t\t\t\tconst tr = insertHardBreakCommand(state);\n\t\t\t\tif (!tr) return false;\n\t\t\t\tcontext.dispatch(tr);\n\t\t\t\treturn true;\n\t\t\t},\n\t\t});\n\t}\n}\n"],"names":["getSiblings","state","parentPath","length","doc","children","parent","getBlock","createEmptyParagraph","id","createBlockNode","nodeType","createTextNode","resolveInsertPoint","sel","blockOrder","isCollapsed","blockId","anchor","offset","range","selectionRange","from","deleteNodeSelection","path","findNodePath","nodeId","slice","siblings","index","findIndex","c","builder","transaction","newId","generateBlockId","insertNode","removeNode","setSelection","createCollapsedSelection","build","prevSibling","isBlockNode","prevLeafId","node","current","lastBlockChild","i","child","prevLeaf","prevLen","getBlockLength","nextSibling","nextLeafId","firstBlockChild","find","navigateArrowIntoVoid","direction","selection","getBlockOrder","isNodeSelection","nodeIdx","indexOf","nodePath","prevId","isVoidBlock","createGapCursor","prevBlock","nextId","isGapCursor","blockIdx","block","blockLen","createNodeSelection","deleteBackwardAtGap","side","deleteVoidAtGap","deleteForwardAtGap","insertTextCommand","text","origin","insertIdx","insertText","Math","max","marks","storedMarks","getBlockMarksAtOffset","addDeleteSelectionSteps","insertBlockId","insertOffset","deleteSelectionCommand","splitBlockCommand","newBlockId","splitBlock","insertHardBreakCommand","hardBreak","createInlineNode","inlineType","insertInlineNode","mergeBlockBackward","prevBlockId","isIsolatingBlock","sharesParent","isInsideIsolating","mergeBlocksAt","mergeBlockForward","nextBlockId","selectAll","blocks","firstBlock","lastBlock","lastBlockLen","createSelection","fromIdx","toIdx","to","deleteTextAt","firstLen","midBlockId","midBlock","midLen","HardBreakPlugin","name","priority","context","this","registerInlineNodeSpec","registerCommands","registerKeymap","type","toDOM","document","createElement","toHTMLString","parseHTML","tag","sanitize","tags","registerCommand","tr","getState","dispatch"],"mappings":"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"}
@@ -1,11 +1,11 @@
1
- import { i as t, g as e, a as n, r as o } from "./AttributedMarkCommands-BETuHXj8.mjs";
1
+ import { i as t, g as e, a as n, r as o } from "./AttributedMarkCommands-BtLea72z.mjs";
2
2
  import { r as i } from "./resolvePluginLocale-B4w1OkPy.mjs";
3
3
  import { e as r } from "./HTMLUtils-DTqQzcKR.mjs";
4
4
  import { m as a } from "./TypeBrands-C09nE2qO.mjs";
5
- import { b as l } from "./ColorValidation-CV4f1wu6.mjs";
6
- import { a as s } from "./ToolbarPlugin-B7oJRzpl.mjs";
7
- const c = { label: "Font", tooltip: "Font Family" }, p = { en: c, de: { label: "Schriftart", tooltip: "Schriftfamilie" }, es: { label: "Fuente", tooltip: "Familia de fuente" }, fr: { label: "Police", tooltip: "Famille de police" }, zh: { label: "字体", tooltip: "字体系列" }, ru: { label: "Шрифт", tooltip: "Семейство шрифтов" }, ar: { label: "الخط", tooltip: "عائلة الخط" }, hi: { label: "फ़ॉन्ट", tooltip: "फ़ॉन्ट परिवार" } };
8
- class f {
5
+ import { a as l, g as s } from "./StyleRuntime-CP4NCwKT.mjs";
6
+ import { b as c } from "./ColorValidation-CV4f1wu6.mjs";
7
+ const f = { label: "Font", tooltip: "Font Family" }, m = { en: f, de: { label: "Schriftart", tooltip: "Schriftfamilie" }, es: { label: "Fuente", tooltip: "Familia de fuente" }, fr: { label: "Police", tooltip: "Famille de police" }, zh: { label: "字体", tooltip: "字体系列" }, ru: { label: "Шрифт", tooltip: "Семейство шрифтов" }, ar: { label: "الخط", tooltip: "عائلة الخط" }, hi: { label: "फ़ॉन्ट", tooltip: "फ़ॉन्ट परिवार" } };
8
+ class p {
9
9
  id = "font";
10
10
  name = "Font";
11
11
  priority = 22;
@@ -17,7 +17,7 @@ class f {
17
17
  this.config = t2;
18
18
  }
19
19
  init(t2) {
20
- this.locale = i(p, t2, this.config.locale), t2.registerStyleSheet("\n/* Font Select — Width overrides for combobox button */\n.notectl-toolbar-btn--font {\n min-width: 100px;\n max-width: 160px;\n}\n\n/* Font Picker Popup */\n.notectl-font-picker {\n min-width: 200px;\n max-height: 320px;\n overflow-y: auto;\n}\n\n.notectl-font-picker__list {\n padding: 4px 0;\n}\n\n.notectl-font-picker__item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 12px;\n border: none;\n background: none;\n cursor: pointer;\n font-size: 14px;\n color: var(--notectl-fg);\n line-height: 1.4;\n text-align: left;\n white-space: nowrap;\n font-family: inherit;\n transition: background 0.1s;\n}\n\n.notectl-font-picker__item:hover {\n background: var(--notectl-hover-bg);\n}\n\n.notectl-font-picker__item--active {\n background: var(--notectl-active-bg);\n color: var(--notectl-primary-fg);\n}\n\n.notectl-font-picker__item--active:hover {\n background: var(--notectl-active-bg);\n}\n\n.notectl-font-picker__check {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n flex-shrink: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--notectl-primary-fg);\n}\n\n.notectl-font-picker__label {\n flex: 1;\n}\n\n.notectl-font-picker__separator {\n height: 1px;\n background: var(--notectl-border);\n margin: 4px 8px;\n}\n"), this.context = t2, this.registerMarkSpec(t2), this.registerCommands(t2), this.registerToolbarItem(t2), this.injectFontFaces();
20
+ this.locale = i(m, t2, this.config.locale), t2.registerStyleSheet("\n/* Font Select — Width overrides for combobox button */\n.notectl-toolbar-btn--font {\n min-width: 100px;\n max-width: 160px;\n}\n\n/* Font Picker Popup */\n.notectl-font-picker {\n min-width: 200px;\n max-height: 320px;\n overflow-y: auto;\n}\n\n.notectl-font-picker__list {\n padding: 4px 0;\n}\n\n.notectl-font-picker__item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n padding: 7px 12px;\n border: none;\n background: none;\n cursor: pointer;\n font-size: 14px;\n color: var(--notectl-fg);\n line-height: 1.4;\n text-align: left;\n white-space: nowrap;\n font-family: inherit;\n transition: background 0.1s;\n}\n\n@media (hover: hover) {\n .notectl-font-picker__item:hover {\n background: var(--notectl-hover-bg);\n }\n}\n\n.notectl-font-picker__item--active {\n background: var(--notectl-active-bg);\n color: var(--notectl-primary-fg);\n}\n\n@media (hover: hover) {\n .notectl-font-picker__item--active:hover {\n background: var(--notectl-active-bg);\n }\n}\n\n.notectl-font-picker__check {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n flex-shrink: 0;\n font-size: 13px;\n font-weight: 600;\n color: var(--notectl-primary-fg);\n}\n\n.notectl-font-picker__label {\n flex: 1;\n}\n\n.notectl-font-picker__separator {\n height: 1px;\n background: var(--notectl-border);\n margin: 4px 8px;\n}\n"), this.context = t2, this.registerMarkSpec(t2), this.registerCommands(t2), this.registerToolbarItem(t2), this.injectFontFaces();
21
21
  }
22
22
  destroy() {
23
23
  this.injectedStyleElement?.remove(), this.injectedStyleElement = null, this.context = null;
@@ -25,13 +25,13 @@ class f {
25
25
  registerMarkSpec(t2) {
26
26
  t2.registerMarkSpec({ type: "font", rank: 6, attrs: { family: { default: "" } }, toDOM(t3) {
27
27
  const e2 = document.createElement("span"), n2 = t3.attrs?.family ?? "";
28
- return n2 && (e2.style.fontFamily = n2), e2;
28
+ return n2 && l(e2, "fontFamily", n2), e2;
29
29
  }, toHTMLString: (t3, e2) => {
30
30
  const n2 = String(t3.attrs?.family ?? "");
31
- return n2 && l(n2) ? `<span style="font-family: ${r(n2)}">${e2}</span>` : e2;
31
+ return n2 && c(n2) ? `<span style="font-family: ${r(n2)}">${e2}</span>` : e2;
32
32
  }, toHTMLStyle: (t3) => {
33
33
  const e2 = String(t3.attrs?.family ?? "");
34
- return e2 && l(e2) ? `font-family: ${r(e2)}` : null;
34
+ return e2 && c(e2) ? `font-family: ${r(e2)}` : null;
35
35
  }, parseHTML: [{ tag: "span", getAttrs: (t3) => {
36
36
  const e2 = t3.style.fontFamily;
37
37
  return !!e2 && { family: e2 };
@@ -53,8 +53,8 @@ class f {
53
53
  return t2;
54
54
  }
55
55
  registerToolbarItem(t2) {
56
- t2.registerToolbarItem({ id: "font", group: "format", label: this.locale.label, tooltip: this.locale.tooltip, command: "removeFont", priority: 5, popupType: "combobox", separatorAfter: this.config.separatorAfter, getLabel: (t3) => this.resolveFontName(this.getActiveFont(t3)), renderPopup: (t3, e2) => {
57
- this.renderFontPopup(t3, e2);
56
+ t2.registerToolbarItem({ id: "font", group: "format", label: this.locale.label, tooltip: this.locale.tooltip, command: "removeFont", priority: 5, popupType: "combobox", separatorAfter: this.config.separatorAfter, getLabel: (t3) => this.resolveFontName(this.getActiveFont(t3)), renderPopup: (t3, e2, n2) => {
57
+ this.renderFontPopup(t3, e2, n2);
58
58
  }, isActive: (t3) => this.isFontActive(t3) });
59
59
  }
60
60
  resolveFontName(t2) {
@@ -78,31 +78,29 @@ class f {
78
78
  }
79
79
  injectFontFaces() {
80
80
  const t2 = [];
81
- for (const e3 of this.config.fonts) if (e3.fontFaces?.length) for (const n2 of e3.fontFaces) {
82
- const o2 = [`font-family: '${(e3.family.split(",")[0] ?? "").trim().replace(/'/g, "")}'`, `src: ${n2.src}`];
83
- n2.weight && o2.push(`font-weight: ${n2.weight}`), n2.style && o2.push(`font-style: ${n2.style}`), o2.push(`font-display: ${n2.display ?? "swap"}`), t2.push(`@font-face {
81
+ for (const e3 of this.config.fonts) if (e3.fontFaces?.length) for (const n3 of e3.fontFaces) {
82
+ const o2 = [`font-family: '${(e3.family.split(",")[0] ?? "").trim().replace(/'/g, "")}'`, `src: ${n3.src}`];
83
+ n3.weight && o2.push(`font-weight: ${n3.weight}`), n3.style && o2.push(`font-style: ${n3.style}`), o2.push(`font-display: ${n3.display ?? "swap"}`), t2.push(`@font-face {
84
84
  ${o2.join(";\n ")};
85
85
  }`);
86
86
  }
87
87
  if (0 === t2.length) return;
88
88
  const e2 = document.createElement("style");
89
- e2.setAttribute("data-notectl-fonts", ""), e2.textContent = t2.join("\n\n"), document.head.appendChild(e2), this.injectedStyleElement = e2;
89
+ e2.setAttribute("data-notectl-fonts", "");
90
+ const n2 = this.context ? s(this.context.getContainer()) : void 0;
91
+ n2 && e2.setAttribute("nonce", n2), e2.textContent = t2.join("\n\n"), document.head.appendChild(e2), this.injectedStyleElement = e2;
90
92
  }
91
- dismissPopup() {
92
- const t2 = this.context?.getService(s);
93
- t2?.closePopup();
94
- }
95
- renderFontPopup(t2, e2) {
93
+ renderFontPopup(t2, e2, n2) {
96
94
  t2.classList.add("notectl-font-picker");
97
- const n2 = e2.getState(), o2 = this.getActiveFont(n2), i2 = this.defaultFont.family, r2 = document.createElement("div");
98
- r2.className = "notectl-font-picker__list", r2.setAttribute("role", "listbox"), r2.setAttribute("aria-label", this.locale.label);
95
+ const o2 = e2.getState(), i2 = this.getActiveFont(o2), r2 = this.defaultFont.family, a2 = e2.getContainer(), l2 = document.createElement("div");
96
+ l2.className = "notectl-font-picker__list", l2.setAttribute("role", "listbox"), l2.setAttribute("aria-label", this.locale.label);
99
97
  for (const t3 of this.config.fonts) {
100
- const n3 = t3.family === i2, a2 = n3 && !o2 || o2 === t3.family, l2 = this.createFontItem(t3.name, t3.family, a2, (o3) => {
101
- o3.preventDefault(), o3.stopPropagation(), n3 ? e2.executeCommand("removeFont") : this.applyFont(e2, e2.getState(), t3.family), this.dismissPopup();
98
+ const o3 = t3.family === r2, s2 = o3 && !i2 || i2 === t3.family, c2 = this.createFontItem(t3.name, t3.family, s2, (i3) => {
99
+ i3.preventDefault(), i3.stopPropagation(), o3 ? e2.executeCommand("removeFont") : this.applyFont(e2, e2.getState(), t3.family), n2({ restoreFocusTo: a2 });
102
100
  });
103
- t3.category && l2.setAttribute("data-category", t3.category), r2.appendChild(l2);
101
+ t3.category && c2.setAttribute("data-category", t3.category), l2.appendChild(c2);
104
102
  }
105
- t2.appendChild(r2);
103
+ t2.appendChild(l2);
106
104
  }
107
105
  createFontItem(t2, e2, n2, o2) {
108
106
  const i2 = document.createElement("button");
@@ -110,12 +108,12 @@ class f {
110
108
  const r2 = document.createElement("span");
111
109
  r2.className = "notectl-font-picker__check", r2.textContent = n2 ? "✓" : "", i2.appendChild(r2);
112
110
  const a2 = document.createElement("span");
113
- return a2.className = "notectl-font-picker__label", a2.textContent = t2, e2 && (a2.style.fontFamily = e2), i2.appendChild(a2), i2.addEventListener("mousedown", o2), i2;
111
+ return a2.className = "notectl-font-picker__label", a2.textContent = t2, e2 && l(a2, "fontFamily", e2), i2.appendChild(a2), i2.addEventListener("mousedown", o2), i2;
114
112
  }
115
113
  }
116
114
  export {
117
- f as F,
118
- p as a,
119
- c as b
115
+ p as F,
116
+ m as a,
117
+ f as b
120
118
  };
121
- //# sourceMappingURL=index-Deag_lVi.mjs.map
119
+ //# sourceMappingURL=index-WpbK_s_H.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-WpbK_s_H.mjs","sources":["../../src/editor/styles/font-select.ts","../../src/plugins/font/FontLocale.ts","../../src/plugins/font/FontPlugin.ts"],"sourcesContent":["/** Font picker toolbar combobox + popup styles. */\nexport const FONT_SELECT_CSS = `\n/* Font Select — Width overrides for combobox button */\n.notectl-toolbar-btn--font {\n\tmin-width: 100px;\n\tmax-width: 160px;\n}\n\n/* Font Picker Popup */\n.notectl-font-picker {\n\tmin-width: 200px;\n\tmax-height: 320px;\n\toverflow-y: auto;\n}\n\n.notectl-font-picker__list {\n\tpadding: 4px 0;\n}\n\n.notectl-font-picker__item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\twidth: 100%;\n\tpadding: 7px 12px;\n\tborder: none;\n\tbackground: none;\n\tcursor: pointer;\n\tfont-size: 14px;\n\tcolor: var(--notectl-fg);\n\tline-height: 1.4;\n\ttext-align: left;\n\twhite-space: nowrap;\n\tfont-family: inherit;\n\ttransition: background 0.1s;\n}\n\n@media (hover: hover) {\n\t.notectl-font-picker__item:hover {\n\t\tbackground: var(--notectl-hover-bg);\n\t}\n}\n\n.notectl-font-picker__item--active {\n\tbackground: var(--notectl-active-bg);\n\tcolor: var(--notectl-primary-fg);\n}\n\n@media (hover: hover) {\n\t.notectl-font-picker__item--active:hover {\n\t\tbackground: var(--notectl-active-bg);\n\t}\n}\n\n.notectl-font-picker__check {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 16px;\n\tflex-shrink: 0;\n\tfont-size: 13px;\n\tfont-weight: 600;\n\tcolor: var(--notectl-primary-fg);\n}\n\n.notectl-font-picker__label {\n\tflex: 1;\n}\n\n.notectl-font-picker__separator {\n\theight: 1px;\n\tbackground: var(--notectl-border);\n\tmargin: 4px 8px;\n}\n`;\n","/** Locale interface and default English locale for the FontPlugin. */\n\n// --- Locale Interface ---\n\nexport interface FontLocale {\n\treadonly label: string;\n\treadonly tooltip: string;\n}\n\n// --- Default English Locale ---\n\nexport const FONT_LOCALE_EN: FontLocale = {\n\tlabel: 'Font',\n\ttooltip: 'Font Family',\n};\n\n// --- German Locale ---\n\nexport const FONT_LOCALE_DE: FontLocale = {\n\tlabel: 'Schriftart',\n\ttooltip: 'Schriftfamilie',\n};\n\n// --- Spanish Locale ---\n\nexport const FONT_LOCALE_ES: FontLocale = {\n\tlabel: 'Fuente',\n\ttooltip: 'Familia de fuente',\n};\n\n// --- French Locale ---\n\nexport const FONT_LOCALE_FR: FontLocale = {\n\tlabel: 'Police',\n\ttooltip: 'Famille de police',\n};\n\n// --- Chinese (Simplified) Locale ---\n\nexport const FONT_LOCALE_ZH: FontLocale = {\n\tlabel: '字体',\n\ttooltip: '字体系列',\n};\n\n// --- Russian Locale ---\n\nexport const FONT_LOCALE_RU: FontLocale = {\n\tlabel: 'Шрифт',\n\ttooltip: 'Семейство шрифтов',\n};\n\n// --- Arabic Locale ---\n\nexport const FONT_LOCALE_AR: FontLocale = {\n\tlabel: 'الخط',\n\ttooltip: 'عائلة الخط',\n};\n\n// --- Hindi Locale ---\n\nexport const FONT_LOCALE_HI: FontLocale = {\n\tlabel: 'फ़ॉन्ट',\n\ttooltip: 'फ़ॉन्ट परिवार',\n};\n\n// --- Locale Map ---\n\nexport const FONT_LOCALES: Record<string, FontLocale> = {\n\ten: FONT_LOCALE_EN,\n\tde: FONT_LOCALE_DE,\n\tes: FONT_LOCALE_ES,\n\tfr: FONT_LOCALE_FR,\n\tzh: FONT_LOCALE_ZH,\n\tru: FONT_LOCALE_RU,\n\tar: FONT_LOCALE_AR,\n\thi: FONT_LOCALE_HI,\n};\n","/**\n * FontPlugin: registers a font-family mark, a combobox-style toolbar selector\n * for font selection, and a developer-friendly API for registering custom fonts\n * (WOFF2, TTF, OTF).\n */\n\nimport {\n\tapplyAttributedMark,\n\tgetMarkAttrAtSelection,\n\tisAttributedMarkActive,\n\tremoveAttributedMark,\n} from '../../commands/AttributedMarkCommands.js';\nimport { FONT_SELECT_CSS } from '../../editor/styles/font-select.js';\nimport { resolvePluginLocale } from '../../i18n/resolvePluginLocale.js';\nimport { escapeHTML } from '../../model/HTMLUtils.js';\nimport { markType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport { getStyleNonceForNode, setStyleProperty } from '../../style/StyleRuntime.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { isValidCSSFontFamily } from '../shared/ColorValidation.js';\nimport type { PopupCloseOptions } from '../shared/PopupManager.js';\nimport { FONT_LOCALES, type FontLocale } from './FontLocale.js';\n\n// --- Attribute Registry Augmentation ---\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface MarkAttrRegistry {\n\t\tfont: { family: string };\n\t}\n}\n\n// --- Public Types ---\n\n/** Describes a single @font-face source. */\nexport interface FontFaceDescriptor {\n\t/** CSS `src` value, e.g. `\"url('/fonts/My.woff2') format('woff2')\"`. */\n\treadonly src: string;\n\t/** Font weight, e.g. `'400'` or `'300 700'` for variable fonts. */\n\treadonly weight?: string;\n\t/** Font style, e.g. `'normal'` or `'italic'`. */\n\treadonly style?: string;\n\t/** Font display strategy. Defaults to `'swap'`. */\n\treadonly display?: string;\n}\n\n/** Defines a font available in the editor. */\nexport interface FontDefinition {\n\t/** Display name shown in the toolbar dropdown. */\n\treadonly name: string;\n\t/** CSS `font-family` value, e.g. `\"'Fira Code', monospace\"`. */\n\treadonly family: string;\n\t/** Font category for grouping in the UI. */\n\treadonly category?: 'serif' | 'sans-serif' | 'monospace' | 'display' | 'handwriting';\n\t/**\n\t * Optional `@font-face` descriptors. When provided, the plugin\n\t * auto-injects the corresponding CSS rules into the document.\n\t */\n\treadonly fontFaces?: readonly FontFaceDescriptor[];\n}\n\n// --- Configuration ---\n\nexport interface FontConfig {\n\t/**\n\t * Fonts available in the editor. System fonts require no `fontFaces`.\n\t * Custom fonts with `fontFaces` get their `@font-face` rules auto-injected.\n\t *\n\t * Use `STARTER_FONTS` for a pre-configured set of fonts:\n\t * ```ts\n\t * new FontPlugin({ fonts: [...STARTER_FONTS] })\n\t * ```\n\t */\n\treadonly fonts: readonly FontDefinition[];\n\t/**\n\t * Name of the font that acts as the editor's default.\n\t * Selecting this font removes the mark (since the editor already uses it).\n\t * Defaults to the first font in the list.\n\t */\n\treadonly defaultFont?: string;\n\t/** When true, a separator is rendered after the font toolbar item. */\n\treadonly separatorAfter?: boolean;\n\treadonly locale?: FontLocale;\n}\n\n// --- Plugin ---\n\nexport class FontPlugin implements Plugin {\n\treadonly id = 'font';\n\treadonly name = 'Font';\n\treadonly priority = 22;\n\n\tprivate readonly config: FontConfig;\n\tprivate locale!: FontLocale;\n\tprivate injectedStyleElement: HTMLStyleElement | null = null;\n\tprivate context: PluginContext | null = null;\n\n\tconstructor(config: FontConfig) {\n\t\tthis.config = config;\n\t}\n\n\tinit(context: PluginContext): void {\n\t\tthis.locale = resolvePluginLocale(FONT_LOCALES, context, this.config.locale);\n\n\t\tcontext.registerStyleSheet(FONT_SELECT_CSS);\n\t\tthis.context = context;\n\t\tthis.registerMarkSpec(context);\n\t\tthis.registerCommands(context);\n\t\tthis.registerToolbarItem(context);\n\t\tthis.injectFontFaces();\n\t}\n\n\tdestroy(): void {\n\t\tthis.injectedStyleElement?.remove();\n\t\tthis.injectedStyleElement = null;\n\t\tthis.context = null;\n\t}\n\n\t// --- Schema ---\n\n\tprivate registerMarkSpec(context: PluginContext): void {\n\t\tcontext.registerMarkSpec({\n\t\t\ttype: 'font',\n\t\t\trank: 6,\n\t\t\tattrs: {\n\t\t\t\tfamily: { default: '' },\n\t\t\t},\n\t\t\ttoDOM(mark) {\n\t\t\t\tconst span: HTMLElement = document.createElement('span');\n\t\t\t\tconst family: string = mark.attrs?.family ?? '';\n\t\t\t\tif (family) {\n\t\t\t\t\tsetStyleProperty(span, 'fontFamily', family);\n\t\t\t\t}\n\t\t\t\treturn span;\n\t\t\t},\n\t\t\ttoHTMLString: (mark, content) => {\n\t\t\t\tconst family: string = String(mark.attrs?.family ?? '');\n\t\t\t\tif (!family || !isValidCSSFontFamily(family)) return content;\n\t\t\t\treturn `<span style=\"font-family: ${escapeHTML(family)}\">${content}</span>`;\n\t\t\t},\n\t\t\ttoHTMLStyle: (mark) => {\n\t\t\t\tconst family: string = String(mark.attrs?.family ?? '');\n\t\t\t\tif (!family || !isValidCSSFontFamily(family)) return null;\n\t\t\t\treturn `font-family: ${escapeHTML(family)}`;\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 family: string = el.style.fontFamily;\n\t\t\t\t\t\tif (!family) return false;\n\t\t\t\t\t\treturn { family };\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\t// --- Commands ---\n\n\tprivate registerCommands(context: PluginContext): void {\n\t\tcontext.registerCommand('removeFont', () => {\n\t\t\tconst state: EditorState = context.getState();\n\t\t\treturn this.removeFont(context, state);\n\t\t});\n\n\t\tcontext.registerCommand('setFont', () => {\n\t\t\treturn false;\n\t\t});\n\t}\n\n\t// --- Toolbar ---\n\n\tprivate get defaultFont(): FontDefinition {\n\t\tif (this.config.defaultFont) {\n\t\t\tconst found: FontDefinition | undefined = this.config.fonts.find(\n\t\t\t\t(f) => f.name === this.config.defaultFont,\n\t\t\t);\n\t\t\tif (found) return found;\n\t\t}\n\t\tconst first: FontDefinition | undefined = this.config.fonts[0];\n\t\tif (!first) throw new Error('FontPlugin: fonts list is empty');\n\t\treturn first;\n\t}\n\n\tprivate registerToolbarItem(context: PluginContext): void {\n\t\tcontext.registerToolbarItem({\n\t\t\tid: 'font',\n\t\t\tgroup: 'format',\n\t\t\tlabel: this.locale.label,\n\t\t\ttooltip: this.locale.tooltip,\n\t\t\tcommand: 'removeFont',\n\t\t\tpriority: 5,\n\t\t\tpopupType: 'combobox',\n\t\t\tseparatorAfter: this.config.separatorAfter,\n\t\t\tgetLabel: (state: EditorState): string => this.resolveFontName(this.getActiveFont(state)),\n\t\t\trenderPopup: (container, ctx, onClose) => {\n\t\t\t\tthis.renderFontPopup(container, ctx, onClose);\n\t\t\t},\n\t\t\tisActive: (state) => this.isFontActive(state),\n\t\t});\n\t}\n\n\tprivate resolveFontName(family: string | null): string {\n\t\tif (!family) return this.defaultFont.name;\n\t\tconst match: FontDefinition | undefined = this.config.fonts.find((f) => f.family === family);\n\t\treturn match?.name ?? (family.split(',')[0] ?? '').trim().replace(/'/g, '');\n\t}\n\n\t// --- State Queries ---\n\n\tprivate isFontActive(state: EditorState): boolean {\n\t\treturn isAttributedMarkActive(state, 'font');\n\t}\n\n\tgetActiveFont(state: EditorState): string | null {\n\t\treturn getMarkAttrAtSelection(state, 'font', (m) => m.attrs.family ?? null);\n\t}\n\n\t// --- Font Application ---\n\n\tapplyFont(context: PluginContext, state: EditorState, family: string): boolean {\n\t\tconst mark = { type: markType('font'), attrs: { family } };\n\t\tconst tr = applyAttributedMark(state, mark);\n\t\tif (!tr) return false;\n\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\tprivate removeFont(context: PluginContext, state: EditorState): boolean {\n\t\tconst tr = removeAttributedMark(state, markType('font'));\n\t\tif (!tr) return false;\n\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t}\n\n\t// --- @font-face Injection ---\n\n\tprivate injectFontFaces(): void {\n\t\tconst rules: string[] = [];\n\n\t\tfor (const font of this.config.fonts) {\n\t\t\tif (!font.fontFaces?.length) continue;\n\n\t\t\tfor (const face of font.fontFaces) {\n\t\t\t\tconst familyName: string = (font.family.split(',')[0] ?? '').trim().replace(/'/g, '');\n\t\t\t\tconst declarations: string[] = [`font-family: '${familyName}'`, `src: ${face.src}`];\n\t\t\t\tif (face.weight) {\n\t\t\t\t\tdeclarations.push(`font-weight: ${face.weight}`);\n\t\t\t\t}\n\t\t\t\tif (face.style) {\n\t\t\t\t\tdeclarations.push(`font-style: ${face.style}`);\n\t\t\t\t}\n\t\t\t\tdeclarations.push(`font-display: ${face.display ?? 'swap'}`);\n\n\t\t\t\trules.push(`@font-face {\\n\\t${declarations.join(';\\n\\t')};\\n}`);\n\t\t\t}\n\t\t}\n\n\t\tif (rules.length === 0) return;\n\n\t\tconst style: HTMLStyleElement = document.createElement('style');\n\t\tstyle.setAttribute('data-notectl-fonts', '');\n\t\tconst nonce = this.context ? getStyleNonceForNode(this.context.getContainer()) : undefined;\n\t\tif (nonce) {\n\t\t\tstyle.setAttribute('nonce', nonce);\n\t\t}\n\t\tstyle.textContent = rules.join('\\n\\n');\n\t\tdocument.head.appendChild(style);\n\t\tthis.injectedStyleElement = style;\n\t}\n\n\t// --- Popup Rendering ---\n\n\tprivate renderFontPopup(\n\t\tcontainer: HTMLElement,\n\t\tcontext: PluginContext,\n\t\tonClose: (options?: PopupCloseOptions) => void,\n\t): void {\n\t\tcontainer.classList.add('notectl-font-picker');\n\n\t\tconst state: EditorState = context.getState();\n\t\tconst activeFont: string | null = this.getActiveFont(state);\n\t\tconst defaultFamily: string = this.defaultFont.family;\n\t\tconst contentElement: HTMLElement = context.getContainer();\n\n\t\tconst list: HTMLDivElement = document.createElement('div');\n\t\tlist.className = 'notectl-font-picker__list';\n\t\tlist.setAttribute('role', 'listbox');\n\t\tlist.setAttribute('aria-label', this.locale.label);\n\n\t\tfor (const font of this.config.fonts) {\n\t\t\tconst isDefault: boolean = font.family === defaultFamily;\n\t\t\tconst isActive: boolean = isDefault\n\t\t\t\t? !activeFont || activeFont === font.family\n\t\t\t\t: activeFont === font.family;\n\n\t\t\tconst item: HTMLButtonElement = this.createFontItem(\n\t\t\t\tfont.name,\n\t\t\t\tfont.family,\n\t\t\t\tisActive,\n\t\t\t\t(e: MouseEvent) => {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\te.stopPropagation();\n\t\t\t\t\tif (isDefault) {\n\t\t\t\t\t\tcontext.executeCommand('removeFont');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.applyFont(context, context.getState(), font.family);\n\t\t\t\t\t}\n\t\t\t\t\tonClose({ restoreFocusTo: contentElement });\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tif (font.category) {\n\t\t\t\titem.setAttribute('data-category', font.category);\n\t\t\t}\n\n\t\t\tlist.appendChild(item);\n\t\t}\n\n\t\tcontainer.appendChild(list);\n\t}\n\n\tprivate createFontItem(\n\t\tname: string,\n\t\tfamily: string,\n\t\tisActive: boolean,\n\t\thandler: (e: MouseEvent) => void,\n\t): HTMLButtonElement {\n\t\tconst item: HTMLButtonElement = document.createElement('button');\n\t\titem.type = 'button';\n\t\titem.className = 'notectl-font-picker__item';\n\t\titem.setAttribute('role', 'option');\n\t\titem.setAttribute('aria-selected', String(isActive));\n\n\t\tif (isActive) {\n\t\t\titem.classList.add('notectl-font-picker__item--active');\n\t\t}\n\n\t\t// Checkmark indicator\n\t\tconst check: HTMLSpanElement = document.createElement('span');\n\t\tcheck.className = 'notectl-font-picker__check';\n\t\tcheck.textContent = isActive ? '\\u2713' : '';\n\t\titem.appendChild(check);\n\n\t\t// Font name label (rendered in the font itself for preview)\n\t\tconst label: HTMLSpanElement = document.createElement('span');\n\t\tlabel.className = 'notectl-font-picker__label';\n\t\tlabel.textContent = name;\n\t\tif (family) {\n\t\t\tsetStyleProperty(label, 'fontFamily', family);\n\t\t}\n\t\titem.appendChild(label);\n\n\t\titem.addEventListener('mousedown', handler);\n\t\treturn item;\n\t}\n}\n"],"names":["FONT_LOCALE_EN","label","tooltip","FONT_LOCALES","en","de","es","fr","zh","ru","ar","hi","FontPlugin","id","name","priority","config","locale","injectedStyleElement","context","this","resolvePluginLocale","registerStyleSheet","registerMarkSpec","registerCommands","registerToolbarItem","injectFontFaces","destroy","remove","type","rank","attrs","family","default","mark","span","document","createElement","setStyleProperty","toHTMLString","content","String","isValidCSSFontFamily","escapeHTML","toHTMLStyle","parseHTML","tag","getAttrs","el","style","fontFamily","sanitize","tags","registerCommand","state","getState","removeFont","defaultFont","found","fonts","find","f","first","Error","group","command","popupType","separatorAfter","getLabel","resolveFontName","getActiveFont","renderPopup","container","ctx","onClose","renderFontPopup","isActive","isFontActive","match","split","trim","replace","isAttributedMarkActive","getMarkAttrAtSelection","m","markType","tr","applyAttributedMark","dispatch","removeAttributedMark","rules","font","fontFaces","length","face","declarations","src","weight","push","display","join","setAttribute","nonce","getStyleNonceForNode","getContainer","textContent","head","appendChild","classList","add","activeFont","defaultFamily","contentElement","list","className","isDefault","item","createFontItem","e","preventDefault","stopPropagation","executeCommand","applyFont","restoreFocusTo","category","handler","check","addEventListener"],"mappings":"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"}
@@ -1,9 +1,10 @@
1
- import { C as e, r, i as a, a as t } from "./ColorPickerPopup-D3ysvOH-.mjs";
1
+ import { C as e, r, i as a, a as t } from "./ColorPickerPopup-TpIRlXc8.mjs";
2
2
  import { r as o } from "./resolvePluginLocale-B4w1OkPy.mjs";
3
3
  import { e as l } from "./HTMLUtils-DTqQzcKR.mjs";
4
- import { r as i, i as s } from "./ColorValidation-CV4f1wu6.mjs";
5
- const f = { label: "Highlight", tooltip: "Highlight Color", resetLabel: "None", ariaLabelPrefix: "Highlight color" }, c = { en: f, de: { label: "Hervorhebung", tooltip: "Hervorhebungsfarbe", resetLabel: "Keine", ariaLabelPrefix: "Hervorhebungsfarbe" }, es: { label: "Resaltado", tooltip: "Color de resaltado", resetLabel: "Ninguno", ariaLabelPrefix: "Color de resaltado" }, fr: { label: "Surlignage", tooltip: "Couleur de surlignage", resetLabel: "Aucun", ariaLabelPrefix: "Couleur de surlignage" }, zh: { label: "高亮", tooltip: "高亮颜色", resetLabel: "无", ariaLabelPrefix: "高亮颜色" }, ru: { label: "Выделение", tooltip: "Цвет выделения", resetLabel: "Нет", ariaLabelPrefix: "Цвет выделения" }, ar: { label: "تمييز", tooltip: "لون التمييز", resetLabel: "بدون", ariaLabelPrefix: "لون التمييز" }, hi: { label: "हाइलाइट", tooltip: "हाइलाइट रंग", resetLabel: "कोई नहीं", ariaLabelPrefix: "हाइलाइट रंग" } }, g = ["#fff176", "#aed581", "#4dd0e1", "#64b5f6", "#ce93d8", "#f48fb1", "#ffab91", "#ff8a65", "#e6ee9c", "#80cbc4", "#fff9c4", "#dcedc8", "#e0f7fa", "#e3f2fd", "#f3e5f5", "#fce4ec", "#fff3e0", "#fbe9e7", "#f9fbe7", "#e0f2f1", "#fff59d", "#c5e1a5", "#80deea", "#90caf9", "#e1bee7", "#f8bbd0", "#ffcc80", "#ffab91", "#e6ee9c", "#a5d6a7", "#ffee58", "#9ccc65", "#26c6da", "#42a5f5", "#ab47bc", "#ec407a", "#ffa726", "#ff7043", "#d4e157", "#66bb6a", "#ffffff", "#fafafa", "#f5f5f5", "#eeeeee", "#e0e0e0", "#bdbdbd", "#e8eaf6", "#efebe9", "#eceff1", "#fafafa"];
6
- class h {
4
+ import { a as i } from "./StyleRuntime-CP4NCwKT.mjs";
5
+ import { r as s, i as f } from "./ColorValidation-CV4f1wu6.mjs";
6
+ const c = { label: "Highlight", tooltip: "Highlight Color", resetLabel: "None", ariaLabelPrefix: "Highlight color" }, g = { en: c, de: { label: "Hervorhebung", tooltip: "Hervorhebungsfarbe", resetLabel: "Keine", ariaLabelPrefix: "Hervorhebungsfarbe" }, es: { label: "Resaltado", tooltip: "Color de resaltado", resetLabel: "Ninguno", ariaLabelPrefix: "Color de resaltado" }, fr: { label: "Surlignage", tooltip: "Couleur de surlignage", resetLabel: "Aucun", ariaLabelPrefix: "Couleur de surlignage" }, zh: { label: "高亮", tooltip: "高亮颜色", resetLabel: "无", ariaLabelPrefix: "高亮颜色" }, ru: { label: "Выделение", tooltip: "Цвет выделения", resetLabel: "Нет", ariaLabelPrefix: "Цвет выделения" }, ar: { label: "تمييز", tooltip: "لون التمييز", resetLabel: "بدون", ariaLabelPrefix: "لون التمييز" }, hi: { label: "हाइलाइट", tooltip: "हाइलाइट रंग", resetLabel: "कोई नहीं", ariaLabelPrefix: "हाइलाइट रंग" } }, h = ["#fff176", "#aed581", "#4dd0e1", "#64b5f6", "#ce93d8", "#f48fb1", "#ffab91", "#ff8a65", "#e6ee9c", "#80cbc4", "#fff9c4", "#dcedc8", "#e0f7fa", "#e3f2fd", "#f3e5f5", "#fce4ec", "#fff3e0", "#fbe9e7", "#f9fbe7", "#e0f2f1", "#fff59d", "#c5e1a5", "#80deea", "#90caf9", "#e1bee7", "#f8bbd0", "#ffcc80", "#ffab91", "#e6ee9c", "#a5d6a7", "#ffee58", "#9ccc65", "#26c6da", "#42a5f5", "#ab47bc", "#ec407a", "#ffa726", "#ff7043", "#d4e157", "#66bb6a", "#ffffff", "#fafafa", "#f5f5f5", "#eeeeee", "#e0e0e0", "#bdbdbd", "#e8eaf6", "#efebe9", "#eceff1", "#fafafa"];
7
+ class b {
7
8
  id = "highlight";
8
9
  name = "Highlight";
9
10
  priority = 24;
@@ -11,24 +12,24 @@ class h {
11
12
  colors;
12
13
  locale;
13
14
  constructor(e2) {
14
- this.config = { ...e2 }, this.colors = i(e2?.colors, g, "HighlightPlugin");
15
+ this.config = { ...e2 }, this.colors = s(e2?.colors, h, "HighlightPlugin");
15
16
  }
16
17
  init(r2) {
17
- this.locale = o(c, r2, this.config.locale), r2.registerStyleSheet(e), this.registerMarkSpec(r2), this.registerCommands(r2), this.registerToolbarItem(r2);
18
+ this.locale = o(g, r2, this.config.locale), r2.registerStyleSheet(e), this.registerMarkSpec(r2), this.registerCommands(r2), this.registerToolbarItem(r2);
18
19
  }
19
20
  registerMarkSpec(e2) {
20
21
  e2.registerMarkSpec({ type: "highlight", rank: 4, attrs: { color: { default: "" } }, toDOM(e3) {
21
22
  const r2 = document.createElement("span"), a2 = e3.attrs?.color ?? "";
22
- return r2.style.backgroundColor = a2, r2;
23
+ return i(r2, "backgroundColor", a2), r2;
23
24
  }, toHTMLString: (e3, r2) => {
24
25
  const a2 = String(e3.attrs?.color ?? "");
25
- return a2 && s(a2) ? `<span style="background-color: ${l(a2)}">${r2}</span>` : r2;
26
+ return a2 && f(a2) ? `<span style="background-color: ${l(a2)}">${r2}</span>` : r2;
26
27
  }, toHTMLStyle: (e3) => {
27
28
  const r2 = String(e3.attrs?.color ?? "");
28
- return r2 && s(r2) ? `background-color: ${l(r2)}` : null;
29
+ return r2 && f(r2) ? `background-color: ${l(r2)}` : null;
29
30
  }, parseHTML: [{ tag: "span", getAttrs: (e3) => {
30
31
  const r2 = e3.style.backgroundColor;
31
- return !(!r2 || !s(r2)) && { color: r2 };
32
+ return !(!r2 || !f(r2)) && { color: r2 };
32
33
  } }], sanitize: { tags: ["span"] } });
33
34
  }
34
35
  registerCommands(e2) {
@@ -42,8 +43,8 @@ class h {
42
43
  }
43
44
  }
44
45
  export {
45
- h as H,
46
- c as a,
47
- f as b
46
+ b as H,
47
+ g as a,
48
+ c as b
48
49
  };
49
- //# sourceMappingURL=index-DIvHQtE2.mjs.map
50
+ //# sourceMappingURL=index-WrqH1wG8.mjs.map