@notectl/core 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (195) hide show
  1. package/README.md +2 -2
  2. package/dist/chunks/{AttrRegistry-I-VdmRnN.mjs → AttrRegistry-Ci0qAvtS.mjs} +2 -2
  3. package/dist/chunks/{AttrRegistry-I-VdmRnN.mjs.map → AttrRegistry-Ci0qAvtS.mjs.map} +1 -1
  4. package/dist/chunks/AttributedMarkCommands-BETuHXj8.mjs +58 -0
  5. package/dist/chunks/AttributedMarkCommands-BETuHXj8.mjs.map +1 -0
  6. package/dist/chunks/{CaretNavigation-CAJXoaae.mjs → CaretNavigation-qLfeL0So.mjs} +56 -56
  7. package/dist/chunks/{CaretNavigation-CAJXoaae.mjs.map → CaretNavigation-qLfeL0So.mjs.map} +1 -1
  8. package/dist/chunks/ColorGrid-BBkN0AOb.mjs +80 -0
  9. package/dist/chunks/ColorGrid-BBkN0AOb.mjs.map +1 -0
  10. package/dist/chunks/ColorPickerPopup-D3ysvOH-.mjs +37 -0
  11. package/dist/chunks/ColorPickerPopup-D3ysvOH-.mjs.map +1 -0
  12. package/dist/chunks/ColorValidation-CV4f1wu6.mjs +39 -0
  13. package/dist/chunks/ColorValidation-CV4f1wu6.mjs.map +1 -0
  14. package/dist/chunks/{Document-CuwE73FF.mjs → Document-DfZ1NOjs.mjs} +15 -15
  15. package/dist/chunks/{Document-CuwE73FF.mjs.map → Document-DfZ1NOjs.mjs.map} +1 -1
  16. package/dist/chunks/MarkCommands-uybmkw9l.mjs +94 -0
  17. package/dist/chunks/MarkCommands-uybmkw9l.mjs.map +1 -0
  18. package/dist/chunks/{NavigationUtils-CyW0Vo8A.mjs → NavigationUtils-Cspt2ZrK.mjs} +3 -3
  19. package/dist/chunks/{NavigationUtils-CyW0Vo8A.mjs.map → NavigationUtils-Cspt2ZrK.mjs.map} +1 -1
  20. package/dist/chunks/{NodeResolver-B-wzthAQ.mjs → NodeResolver-CzLmmrph.mjs} +2 -2
  21. package/dist/chunks/{NodeResolver-B-wzthAQ.mjs.map → NodeResolver-CzLmmrph.mjs.map} +1 -1
  22. package/dist/chunks/PopupPositioning-Cn6L_mO2.mjs +30 -0
  23. package/dist/chunks/PopupPositioning-Cn6L_mO2.mjs.map +1 -0
  24. package/dist/chunks/RangeIterator-Bye0UtbY.mjs +16 -0
  25. package/dist/chunks/RangeIterator-Bye0UtbY.mjs.map +1 -0
  26. package/dist/chunks/{Selection-DmFDwiPJ.mjs → Selection-BRTab5hO.mjs} +7 -7
  27. package/dist/chunks/{Selection-DmFDwiPJ.mjs.map → Selection-BRTab5hO.mjs.map} +1 -1
  28. package/dist/chunks/ToolbarItem-BpZggUGo.mjs.map +1 -1
  29. package/dist/chunks/{ToolbarKeyboardNav-B32OMv8r.mjs → ToolbarKeyboardNav-DhpL8zNV.mjs} +3 -3
  30. package/dist/chunks/{ToolbarKeyboardNav-B32OMv8r.mjs.map → ToolbarKeyboardNav-DhpL8zNV.mjs.map} +1 -1
  31. package/dist/chunks/{ToolbarPlugin-B6JETWaw.mjs → ToolbarPlugin-B7oJRzpl.mjs} +339 -127
  32. package/dist/chunks/ToolbarPlugin-B7oJRzpl.mjs.map +1 -0
  33. package/dist/chunks/{index-CAV2N-fF.mjs → index-Bt_d4IqB.mjs} +8 -8
  34. package/dist/chunks/{index-CAV2N-fF.mjs.map → index-Bt_d4IqB.mjs.map} +1 -1
  35. package/dist/chunks/{index-pxbbDHVH.mjs → index-CFJFD4lF.mjs} +3 -3
  36. package/dist/chunks/{index-pxbbDHVH.mjs.map → index-CFJFD4lF.mjs.map} +1 -1
  37. package/dist/chunks/{index-C0cEs7Jc.mjs → index-CFPP456m.mjs} +10 -10
  38. package/dist/chunks/{index-C0cEs7Jc.mjs.map → index-CFPP456m.mjs.map} +1 -1
  39. package/dist/chunks/{index-FlTg80Pk.mjs → index-CH1r7DL-.mjs} +257 -298
  40. package/dist/chunks/index-CH1r7DL-.mjs.map +1 -0
  41. package/dist/chunks/{index-D0s0Q8Wc.mjs → index-CfyS_pgH.mjs} +25 -18
  42. package/dist/chunks/index-CfyS_pgH.mjs.map +1 -0
  43. package/dist/chunks/{index-CflvcXSd.mjs → index-Ckzqtn5D.mjs} +17 -14
  44. package/dist/chunks/{index-CflvcXSd.mjs.map → index-Ckzqtn5D.mjs.map} +1 -1
  45. package/dist/chunks/{index-C9gc3Bws.mjs → index-CrKz_IEn.mjs} +32 -32
  46. package/dist/chunks/{index-C9gc3Bws.mjs.map → index-CrKz_IEn.mjs.map} +1 -1
  47. package/dist/chunks/{index-DMt3ojrY.mjs → index-DGKQhSAl.mjs} +2 -2
  48. package/dist/chunks/{index-DMt3ojrY.mjs.map → index-DGKQhSAl.mjs.map} +1 -1
  49. package/dist/chunks/{index-CoeD4T9-.mjs → index-DIvHQtE2.mjs} +10 -7
  50. package/dist/chunks/{index-CoeD4T9-.mjs.map → index-DIvHQtE2.mjs.map} +1 -1
  51. package/dist/chunks/index-DayTn6Re.mjs +166 -0
  52. package/dist/chunks/index-DayTn6Re.mjs.map +1 -0
  53. package/dist/chunks/index-Deag_lVi.mjs +121 -0
  54. package/dist/chunks/index-Deag_lVi.mjs.map +1 -0
  55. package/dist/chunks/{index--z_Txzej.mjs → index-DmuuFS5D.mjs} +6 -6
  56. package/dist/chunks/{index--z_Txzej.mjs.map → index-DmuuFS5D.mjs.map} +1 -1
  57. package/dist/chunks/{index-B9GkDVsx.mjs → index-DoCvDkfj.mjs} +77 -94
  58. package/dist/chunks/index-DoCvDkfj.mjs.map +1 -0
  59. package/dist/chunks/index-DuRNETFv.mjs +296 -0
  60. package/dist/chunks/index-DuRNETFv.mjs.map +1 -0
  61. package/dist/chunks/{index-B-NSeaM4.mjs → index-Dum8yE_t.mjs} +12 -12
  62. package/dist/chunks/{index-B-NSeaM4.mjs.map → index-Dum8yE_t.mjs.map} +1 -1
  63. package/dist/chunks/{index-CNs4QQ8l.mjs → index-Dy6SllXW.mjs} +52 -64
  64. package/dist/chunks/index-Dy6SllXW.mjs.map +1 -0
  65. package/dist/chunks/{index-D8tbbW97.mjs → index-E7OgN7hM.mjs} +2 -2
  66. package/dist/chunks/{index-D8tbbW97.mjs.map → index-E7OgN7hM.mjs.map} +1 -1
  67. package/dist/chunks/{index-DyIwN_67.mjs → index-yhz2qeeh.mjs} +220 -218
  68. package/dist/chunks/index-yhz2qeeh.mjs.map +1 -0
  69. package/dist/commands/AttributedMarkCommands.d.ts +46 -0
  70. package/dist/commands/AttributedMarkCommands.d.ts.map +1 -0
  71. package/dist/commands/CommandHelpers.d.ts +21 -0
  72. package/dist/commands/CommandHelpers.d.ts.map +1 -0
  73. package/dist/commands/Commands.d.ts +2 -8
  74. package/dist/commands/Commands.d.ts.map +1 -1
  75. package/dist/commands/DeleteCommands.d.ts.map +1 -1
  76. package/dist/commands/GapCursorCommands.d.ts.map +1 -1
  77. package/dist/commands/NodeSelectionCommands.d.ts.map +1 -1
  78. package/dist/commands/PasteCommand.d.ts.map +1 -1
  79. package/dist/commands/RangeIterator.d.ts +10 -0
  80. package/dist/commands/RangeIterator.d.ts.map +1 -0
  81. package/dist/editor/DocumentParser.d.ts.map +1 -1
  82. package/dist/editor/DocumentSerializer.d.ts +2 -0
  83. package/dist/editor/DocumentSerializer.d.ts.map +1 -1
  84. package/dist/editor/MarkSerializer.d.ts +11 -0
  85. package/dist/editor/MarkSerializer.d.ts.map +1 -0
  86. package/dist/editor/NotectlEditor.d.ts +6 -3
  87. package/dist/editor/NotectlEditor.d.ts.map +1 -1
  88. package/dist/editor/PaperLayoutController.d.ts +2 -0
  89. package/dist/editor/PaperLayoutController.d.ts.map +1 -1
  90. package/dist/editor/styles/font-select.d.ts +1 -1
  91. package/dist/editor/styles/font-select.d.ts.map +1 -1
  92. package/dist/editor/styles/font-size-select.d.ts +1 -1
  93. package/dist/editor/styles/font-size-select.d.ts.map +1 -1
  94. package/dist/editor/styles/heading-select.d.ts +1 -1
  95. package/dist/editor/styles/heading-select.d.ts.map +1 -1
  96. package/dist/editor/styles/toolbar.d.ts +1 -1
  97. package/dist/editor/styles/toolbar.d.ts.map +1 -1
  98. package/dist/index.d.ts +8 -2
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/input/ClipboardHandler.d.ts +0 -2
  101. package/dist/input/ClipboardHandler.d.ts.map +1 -1
  102. package/dist/model/MarkSpec.d.ts +6 -0
  103. package/dist/model/MarkSpec.d.ts.map +1 -1
  104. package/dist/notectl-core.mjs +2227 -2090
  105. package/dist/notectl-core.mjs.map +1 -1
  106. package/dist/notectl-core.umd.js +2527 -2337
  107. package/dist/notectl-core.umd.js.map +1 -1
  108. package/dist/plugins/PluginManager.d.ts +2 -0
  109. package/dist/plugins/PluginManager.d.ts.map +1 -1
  110. package/dist/plugins/alignment.mjs +1 -1
  111. package/dist/plugins/blockquote.mjs +1 -1
  112. package/dist/plugins/caret-navigation.mjs +1 -1
  113. package/dist/plugins/code-block.mjs +1 -1
  114. package/dist/plugins/font/FontPlugin.d.ts +0 -6
  115. package/dist/plugins/font/FontPlugin.d.ts.map +1 -1
  116. package/dist/plugins/font-size/FontSizeOperations.d.ts.map +1 -1
  117. package/dist/plugins/font-size/FontSizePlugin.d.ts +0 -5
  118. package/dist/plugins/font-size/FontSizePlugin.d.ts.map +1 -1
  119. package/dist/plugins/font-size.mjs +1 -1
  120. package/dist/plugins/font.mjs +1 -1
  121. package/dist/plugins/gap-cursor.mjs +7 -7
  122. package/dist/plugins/hard-break.mjs +2 -25
  123. package/dist/plugins/hard-break.mjs.map +1 -1
  124. package/dist/plugins/heading/HeadingBlockTypePicker.d.ts +1 -7
  125. package/dist/plugins/heading/HeadingBlockTypePicker.d.ts.map +1 -1
  126. package/dist/plugins/heading/HeadingPlugin.d.ts +0 -6
  127. package/dist/plugins/heading/HeadingPlugin.d.ts.map +1 -1
  128. package/dist/plugins/heading.mjs +1 -1
  129. package/dist/plugins/highlight/HighlightPlugin.d.ts.map +1 -1
  130. package/dist/plugins/highlight.mjs +1 -1
  131. package/dist/plugins/horizontal-rule.mjs +1 -1
  132. package/dist/plugins/image/ImagePlugin.d.ts.map +1 -1
  133. package/dist/plugins/image.mjs +1 -1
  134. package/dist/plugins/link/LinkPlugin.d.ts.map +1 -1
  135. package/dist/plugins/link.mjs +1 -1
  136. package/dist/plugins/list/ListPlugin.d.ts.map +1 -1
  137. package/dist/plugins/list.mjs +1 -1
  138. package/dist/plugins/shared/ColorGrid.d.ts +25 -0
  139. package/dist/plugins/shared/ColorGrid.d.ts.map +1 -0
  140. package/dist/plugins/shared/ColorMarkOperations.d.ts.map +1 -1
  141. package/dist/plugins/shared/ColorPickerPopup.d.ts.map +1 -1
  142. package/dist/plugins/shared/ColorValidation.d.ts +13 -2
  143. package/dist/plugins/shared/ColorValidation.d.ts.map +1 -1
  144. package/dist/plugins/shared/PopupKeyboardPatterns.d.ts +43 -0
  145. package/dist/plugins/shared/PopupKeyboardPatterns.d.ts.map +1 -0
  146. package/dist/plugins/shared/PopupManager.d.ts +45 -0
  147. package/dist/plugins/shared/PopupManager.d.ts.map +1 -0
  148. package/dist/plugins/shared/PopupPositioning.d.ts +21 -0
  149. package/dist/plugins/shared/PopupPositioning.d.ts.map +1 -0
  150. package/dist/plugins/strikethrough.mjs +1 -1
  151. package/dist/plugins/super-sub.mjs +1 -1
  152. package/dist/plugins/table/TableBorderColor.d.ts.map +1 -1
  153. package/dist/plugins/table/TableContextMenu.d.ts +2 -1
  154. package/dist/plugins/table/TableContextMenu.d.ts.map +1 -1
  155. package/dist/plugins/table.mjs +1 -1
  156. package/dist/plugins/text-color/TextColorPlugin.d.ts.map +1 -1
  157. package/dist/plugins/text-color.mjs +1 -1
  158. package/dist/plugins/text-formatting.mjs +1 -1
  159. package/dist/plugins/toolbar/ToolbarItem.d.ts +11 -2
  160. package/dist/plugins/toolbar/ToolbarItem.d.ts.map +1 -1
  161. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts +5 -1
  162. package/dist/plugins/toolbar/ToolbarOverflowController.d.ts.map +1 -1
  163. package/dist/plugins/toolbar/ToolbarPlugin.d.ts +1 -0
  164. package/dist/plugins/toolbar/ToolbarPlugin.d.ts.map +1 -1
  165. package/dist/plugins/toolbar/ToolbarPopupController.d.ts +9 -1
  166. package/dist/plugins/toolbar/ToolbarPopupController.d.ts.map +1 -1
  167. package/dist/plugins/toolbar/index.d.ts +1 -1
  168. package/dist/plugins/toolbar/index.d.ts.map +1 -1
  169. package/dist/plugins/toolbar.mjs +1 -1
  170. package/dist/state/BlockTreeOps.d.ts +21 -0
  171. package/dist/state/BlockTreeOps.d.ts.map +1 -0
  172. package/dist/state/InlineContentOps.d.ts +37 -0
  173. package/dist/state/InlineContentOps.d.ts.map +1 -0
  174. package/dist/state/StepApplication.d.ts.map +1 -1
  175. package/dist/test/PluginTestUtils.d.ts +4 -0
  176. package/dist/test/PluginTestUtils.d.ts.map +1 -1
  177. package/package.json +2 -2
  178. package/dist/chunks/ColorNames-BdsHwA2f.mjs +0 -59
  179. package/dist/chunks/ColorNames-BdsHwA2f.mjs.map +0 -1
  180. package/dist/chunks/ColorPickerPopup-xL8ZUfpB.mjs +0 -125
  181. package/dist/chunks/ColorPickerPopup-xL8ZUfpB.mjs.map +0 -1
  182. package/dist/chunks/Commands-CicwYoTQ.mjs +0 -286
  183. package/dist/chunks/Commands-CicwYoTQ.mjs.map +0 -1
  184. package/dist/chunks/MarkCommands-CC37WA7Z.mjs +0 -94
  185. package/dist/chunks/MarkCommands-CC37WA7Z.mjs.map +0 -1
  186. package/dist/chunks/ToolbarPlugin-B6JETWaw.mjs.map +0 -1
  187. package/dist/chunks/index-B9GkDVsx.mjs.map +0 -1
  188. package/dist/chunks/index-CKPrAOr6.mjs +0 -209
  189. package/dist/chunks/index-CKPrAOr6.mjs.map +0 -1
  190. package/dist/chunks/index-CNs4QQ8l.mjs.map +0 -1
  191. package/dist/chunks/index-D0s0Q8Wc.mjs.map +0 -1
  192. package/dist/chunks/index-DfzCof6H.mjs +0 -191
  193. package/dist/chunks/index-DfzCof6H.mjs.map +0 -1
  194. package/dist/chunks/index-DyIwN_67.mjs.map +0 -1
  195. package/dist/chunks/index-FlTg80Pk.mjs.map +0 -1
@@ -1,4 +1,4 @@
1
- import { a as n } from "./Document-CuwE73FF.mjs";
1
+ import { b as n } from "./Document-DfZ1NOjs.mjs";
2
2
  function i(i2, r2) {
3
3
  if (0 === r2.length) return;
4
4
  let t2 = i2.children.find((n2) => n2.id === r2[0]);
@@ -78,4 +78,4 @@ export {
78
78
  i as r,
79
79
  o as w
80
80
  };
81
- //# sourceMappingURL=NodeResolver-B-wzthAQ.mjs.map
81
+ //# sourceMappingURL=NodeResolver-CzLmmrph.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"NodeResolver-B-wzthAQ.mjs","sources":["../../src/model/NodeResolver.ts"],"sourcesContent":["/**\n * Utilities for resolving nodes by path within the document tree.\n * Supports both flat and recursive (nested) document structures.\n */\n\nimport type { BlockNode, Document } from './Document.js';\nimport { isBlockNode } from './Document.js';\n\n/**\n * Resolves a node in the document tree by its path (array of block IDs).\n * The path traces the lineage from the root block down to the target.\n */\nexport function resolveNodeByPath(doc: Document, path: readonly string[]): BlockNode | undefined {\n\tif (path.length === 0) return undefined;\n\n\tlet current: BlockNode | undefined = doc.children.find((b) => b.id === path[0]);\n\tif (!current) return undefined;\n\n\tfor (let i = 1; i < path.length; i++) {\n\t\tconst childId = path[i];\n\t\tif (!childId) return undefined;\n\t\tconst next: BlockNode | undefined = current?.children.find(\n\t\t\t(c): c is BlockNode => isBlockNode(c) && c.id === childId,\n\t\t);\n\t\tif (!next) return undefined;\n\t\tcurrent = next;\n\t}\n\n\treturn current;\n}\n\n/**\n * Resolves the parent of a node at the given path.\n * Returns the parent container (Document or BlockNode) and the child's index within it.\n */\nexport function resolveParentByPath(\n\tdoc: Document,\n\tpath: readonly string[],\n): { parent: Document | BlockNode; index: number } | undefined {\n\tif (path.length === 0) return undefined;\n\n\tif (path.length === 1) {\n\t\tconst index = doc.children.findIndex((b) => b.id === path[0]);\n\t\tif (index === -1) return undefined;\n\t\treturn { parent: doc, index };\n\t}\n\n\tconst parentPath = path.slice(0, -1);\n\tconst parent = resolveNodeByPath(doc, parentPath);\n\tif (!parent) return undefined;\n\n\tconst childId = path[path.length - 1];\n\tif (!childId) return undefined;\n\tconst index = parent.children.findIndex(\n\t\t(c): c is BlockNode => isBlockNode(c) && c.id === childId,\n\t);\n\tif (index === -1) return undefined;\n\n\treturn { parent, index };\n}\n\n/**\n * Finds the path (array of block IDs) to a node by its ID.\n * Performs recursive DFS through the document tree.\n */\nexport function findNodePath(doc: Document, nodeId: string): string[] | undefined {\n\tfor (const block of doc.children) {\n\t\tif (block.id === nodeId) return [nodeId];\n\n\t\tconst subPath = findNodePathInBlock(block, nodeId);\n\t\tif (subPath) return [block.id, ...subPath];\n\t}\n\treturn undefined;\n}\n\nfunction findNodePathInBlock(block: BlockNode, nodeId: string): string[] | undefined {\n\tfor (const child of block.children) {\n\t\tif (!isBlockNode(child)) continue;\n\t\tif (child.id === nodeId) return [nodeId];\n\n\t\tconst subPath = findNodePathInBlock(child, nodeId);\n\t\tif (subPath) return [child.id, ...subPath];\n\t}\n\treturn undefined;\n}\n\n/**\n * Walks all block nodes in the document tree in depth-first order.\n * Visits every BlockNode, including nested ones, with their full path.\n */\nexport function walkNodes(\n\tdoc: Document,\n\tcallback: (node: BlockNode, path: string[]) => void,\n): void {\n\tfor (const block of doc.children) {\n\t\twalkNodeRecursive(block, [block.id], callback);\n\t}\n}\n\nfunction walkNodeRecursive(\n\tnode: BlockNode,\n\tpath: string[],\n\tcallback: (node: BlockNode, path: string[]) => void,\n): void {\n\tcallback(node, path);\n\tfor (const child of node.children) {\n\t\tif (isBlockNode(child)) {\n\t\t\twalkNodeRecursive(child, [...path, child.id], callback);\n\t\t}\n\t}\n}\n\n/**\n * Finds a block node by ID anywhere in the document tree (recursive DFS).\n */\nexport function findNode(doc: Document, nodeId: string): BlockNode | undefined {\n\tfor (const block of doc.children) {\n\t\tif (block.id === nodeId) return block;\n\t\tconst found = findNodeInBlock(block, nodeId);\n\t\tif (found) return found;\n\t}\n\treturn undefined;\n}\n\nfunction findNodeInBlock(block: BlockNode, nodeId: string): BlockNode | undefined {\n\tfor (const child of block.children) {\n\t\tif (!isBlockNode(child)) continue;\n\t\tif (child.id === nodeId) return child;\n\t\tconst found = findNodeInBlock(child, nodeId);\n\t\tif (found) return found;\n\t}\n\treturn undefined;\n}\n\n/**\n * Finds a block node and returns it together with its path.\n */\nexport function findNodeWithPath(\n\tdoc: Document,\n\tnodeId: string,\n): { node: BlockNode; path: string[] } | undefined {\n\tconst path = findNodePath(doc, nodeId);\n\tif (!path) return undefined;\n\tconst node = resolveNodeByPath(doc, path);\n\tif (!node) return undefined;\n\treturn { node, path };\n}\n"],"names":["resolveNodeByPath","doc","path","length","current","children","find","b","id","i","childId","next","c","isBlockNode","resolveParentByPath","index","findIndex","parent","slice","findNodePath","nodeId","block","subPath","findNodePathInBlock","child","walkNodes","callback","walkNodeRecursive","node","findNode","found","findNodeInBlock","findNodeWithPath"],"mappings":"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"}
1
+ {"version":3,"file":"NodeResolver-CzLmmrph.mjs","sources":["../../src/model/NodeResolver.ts"],"sourcesContent":["/**\n * Utilities for resolving nodes by path within the document tree.\n * Supports both flat and recursive (nested) document structures.\n */\n\nimport type { BlockNode, Document } from './Document.js';\nimport { isBlockNode } from './Document.js';\n\n/**\n * Resolves a node in the document tree by its path (array of block IDs).\n * The path traces the lineage from the root block down to the target.\n */\nexport function resolveNodeByPath(doc: Document, path: readonly string[]): BlockNode | undefined {\n\tif (path.length === 0) return undefined;\n\n\tlet current: BlockNode | undefined = doc.children.find((b) => b.id === path[0]);\n\tif (!current) return undefined;\n\n\tfor (let i = 1; i < path.length; i++) {\n\t\tconst childId = path[i];\n\t\tif (!childId) return undefined;\n\t\tconst next: BlockNode | undefined = current?.children.find(\n\t\t\t(c): c is BlockNode => isBlockNode(c) && c.id === childId,\n\t\t);\n\t\tif (!next) return undefined;\n\t\tcurrent = next;\n\t}\n\n\treturn current;\n}\n\n/**\n * Resolves the parent of a node at the given path.\n * Returns the parent container (Document or BlockNode) and the child's index within it.\n */\nexport function resolveParentByPath(\n\tdoc: Document,\n\tpath: readonly string[],\n): { parent: Document | BlockNode; index: number } | undefined {\n\tif (path.length === 0) return undefined;\n\n\tif (path.length === 1) {\n\t\tconst index = doc.children.findIndex((b) => b.id === path[0]);\n\t\tif (index === -1) return undefined;\n\t\treturn { parent: doc, index };\n\t}\n\n\tconst parentPath = path.slice(0, -1);\n\tconst parent = resolveNodeByPath(doc, parentPath);\n\tif (!parent) return undefined;\n\n\tconst childId = path[path.length - 1];\n\tif (!childId) return undefined;\n\tconst index = parent.children.findIndex(\n\t\t(c): c is BlockNode => isBlockNode(c) && c.id === childId,\n\t);\n\tif (index === -1) return undefined;\n\n\treturn { parent, index };\n}\n\n/**\n * Finds the path (array of block IDs) to a node by its ID.\n * Performs recursive DFS through the document tree.\n */\nexport function findNodePath(doc: Document, nodeId: string): string[] | undefined {\n\tfor (const block of doc.children) {\n\t\tif (block.id === nodeId) return [nodeId];\n\n\t\tconst subPath = findNodePathInBlock(block, nodeId);\n\t\tif (subPath) return [block.id, ...subPath];\n\t}\n\treturn undefined;\n}\n\nfunction findNodePathInBlock(block: BlockNode, nodeId: string): string[] | undefined {\n\tfor (const child of block.children) {\n\t\tif (!isBlockNode(child)) continue;\n\t\tif (child.id === nodeId) return [nodeId];\n\n\t\tconst subPath = findNodePathInBlock(child, nodeId);\n\t\tif (subPath) return [child.id, ...subPath];\n\t}\n\treturn undefined;\n}\n\n/**\n * Walks all block nodes in the document tree in depth-first order.\n * Visits every BlockNode, including nested ones, with their full path.\n */\nexport function walkNodes(\n\tdoc: Document,\n\tcallback: (node: BlockNode, path: string[]) => void,\n): void {\n\tfor (const block of doc.children) {\n\t\twalkNodeRecursive(block, [block.id], callback);\n\t}\n}\n\nfunction walkNodeRecursive(\n\tnode: BlockNode,\n\tpath: string[],\n\tcallback: (node: BlockNode, path: string[]) => void,\n): void {\n\tcallback(node, path);\n\tfor (const child of node.children) {\n\t\tif (isBlockNode(child)) {\n\t\t\twalkNodeRecursive(child, [...path, child.id], callback);\n\t\t}\n\t}\n}\n\n/**\n * Finds a block node by ID anywhere in the document tree (recursive DFS).\n */\nexport function findNode(doc: Document, nodeId: string): BlockNode | undefined {\n\tfor (const block of doc.children) {\n\t\tif (block.id === nodeId) return block;\n\t\tconst found = findNodeInBlock(block, nodeId);\n\t\tif (found) return found;\n\t}\n\treturn undefined;\n}\n\nfunction findNodeInBlock(block: BlockNode, nodeId: string): BlockNode | undefined {\n\tfor (const child of block.children) {\n\t\tif (!isBlockNode(child)) continue;\n\t\tif (child.id === nodeId) return child;\n\t\tconst found = findNodeInBlock(child, nodeId);\n\t\tif (found) return found;\n\t}\n\treturn undefined;\n}\n\n/**\n * Finds a block node and returns it together with its path.\n */\nexport function findNodeWithPath(\n\tdoc: Document,\n\tnodeId: string,\n): { node: BlockNode; path: string[] } | undefined {\n\tconst path = findNodePath(doc, nodeId);\n\tif (!path) return undefined;\n\tconst node = resolveNodeByPath(doc, path);\n\tif (!node) return undefined;\n\treturn { node, path };\n}\n"],"names":["resolveNodeByPath","doc","path","length","current","children","find","b","id","i","childId","next","c","isBlockNode","resolveParentByPath","index","findIndex","parent","slice","findNodePath","nodeId","block","subPath","findNodePathInBlock","child","walkNodes","callback","walkNodeRecursive","node","findNode","found","findNodeInBlock","findNodeWithPath"],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ function t(t2, e2, o) {
2
+ const s = o.offset ?? 2, f = window.innerWidth, i = window.innerHeight;
3
+ switch (t2.style.position = "fixed", t2.style.zIndex = "10000", o.position) {
4
+ case "below-start": {
5
+ let o2 = e2.bottom + s, n = e2.left;
6
+ n + t2.offsetWidth > f - 4 && (n = f - t2.offsetWidth - 4), o2 + t2.offsetHeight > i - 4 && (o2 = e2.top - t2.offsetHeight - s), n < 4 && (n = 4), o2 < 4 && (o2 = 4), t2.style.top = `${o2}px`, t2.style.left = `${n}px`;
7
+ break;
8
+ }
9
+ case "below-end": {
10
+ let o2 = e2.bottom + s;
11
+ const n = f - e2.right;
12
+ o2 + t2.offsetHeight > i - 4 && (o2 = e2.top - t2.offsetHeight - s), o2 < 4 && (o2 = 4), t2.style.top = `${o2}px`, t2.style.right = `${n}px`, t2.style.left = "auto";
13
+ break;
14
+ }
15
+ case "right": {
16
+ let o2 = e2.right + s, n = e2.top;
17
+ o2 + t2.offsetWidth > f - 4 && (o2 = e2.left - t2.offsetWidth - s), n + t2.offsetHeight > i - 4 && (n = i - t2.offsetHeight - 4), o2 < 4 && (o2 = 4), n < 4 && (n = 4), t2.style.top = `${n}px`, t2.style.left = `${o2}px`;
18
+ break;
19
+ }
20
+ }
21
+ }
22
+ function e(t2, e2) {
23
+ const o = e2.getRootNode();
24
+ o instanceof ShadowRoot ? o.appendChild(t2) : document.body.appendChild(t2);
25
+ }
26
+ export {
27
+ e as a,
28
+ t as p
29
+ };
30
+ //# sourceMappingURL=PopupPositioning-Cn6L_mO2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PopupPositioning-Cn6L_mO2.mjs","sources":["../../src/plugins/shared/PopupPositioning.ts"],"sourcesContent":["/**\n * Shared popup positioning logic. Positions a popup element relative to an\n * anchor rectangle, clamping to the viewport. Also provides a shadow DOM-aware\n * append helper.\n */\n\n// --- Types ---\n\nexport type PopupPosition = 'below-start' | 'below-end' | 'right';\n\nexport interface PositionOptions {\n\treadonly position: PopupPosition;\n\treadonly offset?: number;\n}\n\n// --- Constants ---\n\nconst DEFAULT_OFFSET = 2;\nconst Z_INDEX = '10000';\nconst POPUP_MIN_MARGIN = 4;\n\n// --- Positioning ---\n\n/**\n * Positions a popup element relative to the given anchor rectangle.\n * Uses fixed positioning and clamps to the viewport edges.\n */\nexport function positionPopup(popup: HTMLElement, anchor: DOMRect, options: PositionOptions): void {\n\tconst offset: number = options.offset ?? DEFAULT_OFFSET;\n\tconst vpWidth: number = window.innerWidth;\n\tconst vpHeight: number = window.innerHeight;\n\n\tpopup.style.position = 'fixed';\n\tpopup.style.zIndex = Z_INDEX;\n\n\tswitch (options.position) {\n\t\tcase 'below-start': {\n\t\t\tlet top: number = anchor.bottom + offset;\n\t\t\tlet left: number = anchor.left;\n\n\t\t\tif (left + popup.offsetWidth > vpWidth - POPUP_MIN_MARGIN) {\n\t\t\t\tleft = vpWidth - popup.offsetWidth - POPUP_MIN_MARGIN;\n\t\t\t}\n\t\t\tif (top + popup.offsetHeight > vpHeight - POPUP_MIN_MARGIN) {\n\t\t\t\ttop = anchor.top - popup.offsetHeight - offset;\n\t\t\t}\n\t\t\tif (left < POPUP_MIN_MARGIN) left = POPUP_MIN_MARGIN;\n\t\t\tif (top < POPUP_MIN_MARGIN) top = POPUP_MIN_MARGIN;\n\n\t\t\tpopup.style.top = `${top}px`;\n\t\t\tpopup.style.left = `${left}px`;\n\t\t\tbreak;\n\t\t}\n\t\tcase 'below-end': {\n\t\t\tlet top: number = anchor.bottom + offset;\n\t\t\tconst rightEdge: number = vpWidth - anchor.right;\n\n\t\t\tif (top + popup.offsetHeight > vpHeight - POPUP_MIN_MARGIN) {\n\t\t\t\ttop = anchor.top - popup.offsetHeight - offset;\n\t\t\t}\n\t\t\tif (top < POPUP_MIN_MARGIN) top = POPUP_MIN_MARGIN;\n\n\t\t\tpopup.style.top = `${top}px`;\n\t\t\tpopup.style.right = `${rightEdge}px`;\n\t\t\tpopup.style.left = 'auto';\n\t\t\tbreak;\n\t\t}\n\t\tcase 'right': {\n\t\t\tlet left: number = anchor.right + offset;\n\t\t\tlet top: number = anchor.top;\n\n\t\t\tif (left + popup.offsetWidth > vpWidth - POPUP_MIN_MARGIN) {\n\t\t\t\tleft = anchor.left - popup.offsetWidth - offset;\n\t\t\t}\n\t\t\tif (top + popup.offsetHeight > vpHeight - POPUP_MIN_MARGIN) {\n\t\t\t\ttop = vpHeight - popup.offsetHeight - POPUP_MIN_MARGIN;\n\t\t\t}\n\t\t\tif (left < POPUP_MIN_MARGIN) left = POPUP_MIN_MARGIN;\n\t\t\tif (top < POPUP_MIN_MARGIN) top = POPUP_MIN_MARGIN;\n\n\t\t\tpopup.style.top = `${top}px`;\n\t\t\tpopup.style.left = `${left}px`;\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/**\n * Appends an element to the appropriate root: the shadow root if the\n * reference node lives inside one, otherwise `document.body`.\n */\nexport function appendToRoot(element: HTMLElement, referenceNode: Node): void {\n\tconst root: Node = referenceNode.getRootNode();\n\tif (root instanceof ShadowRoot) {\n\t\troot.appendChild(element);\n\t} else {\n\t\tdocument.body.appendChild(element);\n\t}\n}\n"],"names":["positionPopup","popup","anchor","options","offset","vpWidth","window","innerWidth","vpHeight","innerHeight","style","position","zIndex","top","bottom","left","offsetWidth","offsetHeight","rightEdge","right","appendToRoot","element","referenceNode","root","getRootNode","ShadowRoot","appendChild","document","body"],"mappings":"AA2BO,SAASA,EAAcC,IAAoBC,IAAiBC,GAAAA;AAClE,QAAMC,IAAiBD,EAAQC,UAXT,GAYhBC,IAAkBC,OAAOC,YACzBC,IAAmBF,OAAOG;AAKhC,UAHAR,GAAMS,MAAMC,WAAW,SACvBV,GAAMS,MAAME,SAfG,SAiBPT,EAAQQ;IACf,KAAK,eAAe;AACnB,UAAIE,KAAcX,GAAOY,SAASV,GAC9BW,IAAeb,GAAOa;AAEtBA,UAAOd,GAAMe,cAAcX,IArBT,MAsBrBU,IAAOV,IAAUJ,GAAMe,cAtBF,IAwBlBH,KAAMZ,GAAMgB,eAAeT,IAxBT,MAyBrBK,KAAMX,GAAOW,MAAMZ,GAAMgB,eAAeb,IAErCW,IA3BkB,MA2BOA,IA3BP,IA4BlBF,KA5BkB,MA4BMA,KA5BN,IA8BtBZ,GAAMS,MAAMG,MAAM,GAAGA,EAAAA,MACrBZ,GAAMS,MAAMK,OAAO,GAAGA,CAAAA;AACtB;AAAA,IACD;AAAA,IACA,KAAK,aAAa;AACjB,UAAIF,KAAcX,GAAOY,SAASV;AAClC,YAAMc,IAAoBb,IAAUH,GAAOiB;AAEvCN,MAAAA,KAAMZ,GAAMgB,eAAeT,IAtCT,MAuCrBK,KAAMX,GAAOW,MAAMZ,GAAMgB,eAAeb,IAErCS,KAzCkB,MAyCMA,KAzCN,IA2CtBZ,GAAMS,MAAMG,MAAM,GAAGA,EAAAA,MACrBZ,GAAMS,MAAMS,QAAQ,GAAGD,CAAAA,MACvBjB,GAAMS,MAAMK,OAAO;AACnB;AAAA,IACD;AAAA,IACA,KAAK,SAAS;AACb,UAAIA,KAAeb,GAAOiB,QAAQf,GAC9BS,IAAcX,GAAOW;AAErBE,MAAAA,KAAOd,GAAMe,cAAcX,IApDT,MAqDrBU,KAAOb,GAAOa,OAAOd,GAAMe,cAAcZ,IAEtCS,IAAMZ,GAAMgB,eAAeT,IAvDT,MAwDrBK,IAAML,IAAWP,GAAMgB,eAxDF,IA0DlBF,KA1DkB,MA0DOA,KA1DP,IA2DlBF,IA3DkB,MA2DMA,IA3DN,IA6DtBZ,GAAMS,MAAMG,MAAM,GAAGA,CAAAA,MACrBZ,GAAMS,MAAMK,OAAO,GAAGA,EAAAA;AACtB;AAAA,IACD;AAAA;AAEF;AAMO,SAASK,EAAaC,IAAsBC,IAAAA;AAClD,QAAMC,IAAaD,GAAcE;AAC7BD,eAAgBE,aACnBF,EAAKG,YAAYL,EAAAA,IAEjBM,SAASC,KAAKF,YAAYL,EAAAA;AAE5B;"}
@@ -0,0 +1,16 @@
1
+ import { a as o } from "./Document-DfZ1NOjs.mjs";
2
+ function t(t2, f, n) {
3
+ const c = t2.getBlockOrder(), e = c.indexOf(f.from.blockId), s = c.indexOf(f.to.blockId);
4
+ for (let i = e; i <= s; i++) {
5
+ const r = c[i];
6
+ if (!r) continue;
7
+ const m = t2.getBlock(r);
8
+ if (!m) continue;
9
+ const d = i === e ? f.from.offset : 0, l = i === s ? f.to.offset : o(m);
10
+ d !== l && n(r, d, l);
11
+ }
12
+ }
13
+ export {
14
+ t as f
15
+ };
16
+ //# sourceMappingURL=RangeIterator-Bye0UtbY.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RangeIterator-Bye0UtbY.mjs","sources":["../../src/commands/RangeIterator.ts"],"sourcesContent":["/**\n * Utility for iterating over blocks within a selection range.\n *\n * Extracted from Commands.ts to break circular dependencies:\n * Commands.ts re-exports from MarkCommands.ts / AttributedMarkCommands.ts,\n * which in turn import forEachBlockInRange from Commands.ts.\n */\n\nimport { getBlockLength } from '../model/Document.js';\nimport type { SelectionRange } from '../model/Selection.js';\nimport type { BlockId } from '../model/TypeBrands.js';\nimport type { EditorState } from '../state/EditorState.js';\n\n/**\n * Iterates over each block in the given selection range, invoking the callback\n * with the block ID, per-block start offset, and per-block end offset.\n * Blocks where `from === to` are skipped automatically.\n */\nexport function forEachBlockInRange(\n\tstate: EditorState,\n\trange: SelectionRange,\n\tcallback: (blockId: BlockId, from: number, to: number) => void,\n): void {\n\tconst blockOrder: readonly BlockId[] = state.getBlockOrder();\n\tconst fromIdx: number = blockOrder.indexOf(range.from.blockId);\n\tconst toIdx: number = blockOrder.indexOf(range.to.blockId);\n\n\tfor (let i: number = fromIdx; i <= toIdx; i++) {\n\t\tconst blockId: BlockId | undefined = blockOrder[i];\n\t\tif (!blockId) continue;\n\t\tconst block = state.getBlock(blockId);\n\t\tif (!block) continue;\n\n\t\tconst from: number = i === fromIdx ? range.from.offset : 0;\n\t\tconst to: number = i === toIdx ? range.to.offset : getBlockLength(block);\n\n\t\tif (from === to) continue;\n\t\tcallback(blockId, from, to);\n\t}\n}\n"],"names":["forEachBlockInRange","state","range","callback","blockOrder","getBlockOrder","fromIdx","indexOf","from","blockId","toIdx","to","i","block","getBlock","offset","getBlockLength"],"mappings":";AAkBO,SAASA,EACfC,IACAC,GACAC,GAAAA;AAEA,QAAMC,IAAiCH,GAAMI,cAAAA,GACvCC,IAAkBF,EAAWG,QAAQL,EAAMM,KAAKC,OAAAA,GAChDC,IAAgBN,EAAWG,QAAQL,EAAMS,GAAGF,OAAAA;AAElD,WAASG,IAAYN,GAASM,KAAKF,GAAOE,KAAK;AAC9C,UAAMH,IAA+BL,EAAWQ,CAAAA;AAChD,QAAA,CAAKH,EAAS;AACd,UAAMI,IAAQZ,GAAMa,SAASL,CAAAA;AAC7B,QAAA,CAAKI,EAAO;AAEZ,UAAML,IAAeI,MAAMN,IAAUJ,EAAMM,KAAKO,SAAS,GACnDJ,IAAaC,MAAMF,IAAQR,EAAMS,GAAGI,SAASC,EAAeH,CAAAA;AAE9DL,UAASG,KACbR,EAASM,GAASD,GAAMG,CAAAA;AAAAA,EACzB;AACD;"}
@@ -38,15 +38,15 @@ function u(o2, n2) {
38
38
  export {
39
39
  t as a,
40
40
  h as b,
41
- f as c,
42
- n as d,
41
+ r as c,
42
+ f as d,
43
43
  o as e,
44
- r as f,
45
- d as g,
46
- c as h,
44
+ d as f,
45
+ c as g,
46
+ a as h,
47
47
  e as i,
48
- a as j,
48
+ n as j,
49
49
  s as k,
50
50
  u as s
51
51
  };
52
- //# sourceMappingURL=Selection-DmFDwiPJ.mjs.map
52
+ //# sourceMappingURL=Selection-BRTab5hO.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Selection-DmFDwiPJ.mjs","sources":["../../src/model/Selection.ts"],"sourcesContent":["/**\n * Selection model for the Notectl editor.\n * A selection is defined by an anchor and head position within the document.\n */\n\nimport type { BlockId } from './TypeBrands.js';\n\nexport interface Position {\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n\t/** Path from root block to leaf block (optional, for nested structures). */\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface Selection {\n\treadonly anchor: Position;\n\treadonly head: Position;\n}\n\nexport interface SelectionRange {\n\treadonly from: Position;\n\treadonly to: Position;\n}\n\n/** A selection that selects an entire node (e.g. void blocks, table selection). */\nexport interface NodeSelection {\n\treadonly type: 'node';\n\treadonly nodeId: BlockId;\n\treadonly path: readonly BlockId[];\n}\n\n/** A virtual cursor at the boundary of a void block where no native caret can exist. */\nexport interface GapCursorSelection {\n\treadonly type: 'gap';\n\treadonly side: 'before' | 'after';\n\treadonly blockId: BlockId;\n\treadonly path: readonly BlockId[];\n}\n\n/** Union type representing a text selection, node selection, or gap cursor. */\nexport type EditorSelection = Selection | NodeSelection | GapCursorSelection;\n\n/** Creates a NodeSelection for the given block. */\nexport function createNodeSelection(nodeId: BlockId, path: readonly BlockId[]): NodeSelection {\n\treturn { type: 'node', nodeId, path };\n}\n\n/** Creates a GapCursorSelection at the boundary of a void block. */\nexport function createGapCursor(\n\tblockId: BlockId,\n\tside: 'before' | 'after',\n\tpath: readonly BlockId[],\n): GapCursorSelection {\n\treturn { type: 'gap', side, blockId, path };\n}\n\n/** Type guard: returns true if the selection is a NodeSelection. */\nexport function isNodeSelection(sel: EditorSelection): sel is NodeSelection {\n\treturn 'type' in sel && sel.type === 'node';\n}\n\n/** Type guard: returns true if the selection is a GapCursorSelection. */\nexport function isGapCursor(sel: EditorSelection): sel is GapCursorSelection {\n\treturn 'type' in sel && sel.type === 'gap';\n}\n\n/** Type guard: returns true if the selection is a text Selection. */\nexport function isTextSelection(sel: EditorSelection): sel is Selection {\n\treturn !('type' in sel);\n}\n\n/** Compares two EditorSelections for equality. */\nexport function selectionsEqual(a: EditorSelection, b: EditorSelection): boolean {\n\tif (isNodeSelection(a) && isNodeSelection(b)) {\n\t\treturn a.nodeId === b.nodeId;\n\t}\n\tif (isGapCursor(a) && isGapCursor(b)) {\n\t\treturn a.blockId === b.blockId && a.side === b.side;\n\t}\n\tif (isTextSelection(a) && isTextSelection(b)) {\n\t\treturn (\n\t\t\ta.anchor.blockId === b.anchor.blockId &&\n\t\t\ta.anchor.offset === b.anchor.offset &&\n\t\t\ta.head.blockId === b.head.blockId &&\n\t\t\ta.head.offset === b.head.offset\n\t\t);\n\t}\n\treturn false;\n}\n\n/** Creates a Position, optionally with a path. */\nexport function createPosition(\n\tblockId: BlockId,\n\toffset: number,\n\tpath?: readonly BlockId[],\n): Position {\n\treturn path ? { blockId, offset, path } : { blockId, offset };\n}\n\n/** Creates a selection with distinct anchor and head. */\nexport function createSelection(anchor: Position, head: Position): Selection {\n\treturn { anchor, head };\n}\n\n/** Creates a collapsed selection (cursor) at the given position. */\nexport function createCollapsedSelection(blockId: BlockId, offset: number): Selection {\n\tconst pos: Position = { blockId, offset };\n\treturn { anchor: pos, head: pos };\n}\n\n/** Returns true if the selection is collapsed (cursor with no range). NodeSelection and GapCursor are never collapsed. */\nexport function isCollapsed(sel: EditorSelection): boolean {\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return false;\n\treturn sel.anchor.blockId === sel.head.blockId && sel.anchor.offset === sel.head.offset;\n}\n\n/**\n * Returns true if the selection direction is forward (anchor before head).\n * When anchor and head are in the same block, compares offsets.\n * Cross-block ordering uses document order (not determinable here — caller provides block order).\n * For NodeSelection, always returns true.\n */\nexport function isForward(sel: EditorSelection, blockOrder?: readonly BlockId[]): boolean {\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return true;\n\tif (sel.anchor.blockId === sel.head.blockId) {\n\t\treturn sel.anchor.offset <= sel.head.offset;\n\t}\n\tif (blockOrder) {\n\t\tconst anchorIdx = blockOrder.indexOf(sel.anchor.blockId);\n\t\tconst headIdx = blockOrder.indexOf(sel.head.blockId);\n\t\treturn anchorIdx <= headIdx;\n\t}\n\treturn true;\n}\n\n/**\n * Returns a normalized range where `from` is always before `to`.\n * Throws for NodeSelection — use isNodeSelection() guard first.\n */\nexport function selectionRange(sel: Selection, blockOrder?: readonly BlockId[]): SelectionRange {\n\tif (isForward(sel, blockOrder)) {\n\t\treturn { from: sel.anchor, to: sel.head };\n\t}\n\treturn { from: sel.head, to: sel.anchor };\n}\n"],"names":["createNodeSelection","nodeId","path","type","createGapCursor","blockId","side","isNodeSelection","sel","isGapCursor","isTextSelection","selectionsEqual","a","b","anchor","offset","head","createPosition","createSelection","createCollapsedSelection","pos","isCollapsed","isForward","blockOrder","indexOf","selectionRange","from","to"],"mappings":"AA2CO,SAASA,EAAoBC,IAAiBC,IAAAA;AACpD,SAAO,EAAEC,MAAM,QAAQF,QAAAA,IAAQC,MAAAA,GAAAA;AAChC;AAGO,SAASE,EACfC,IACAC,IACAJ,IAAAA;AAEA,SAAO,EAAEC,MAAM,OAAOG,MAAAA,IAAMD,SAAAA,IAASH,MAAAA,GAAAA;AACtC;AAGO,SAASK,EAAgBC,IAAAA;AAC/B,SAAO,UAAUA,MAAoB,WAAbA,GAAIL;AAC7B;AAGO,SAASM,EAAYD,IAAAA;AAC3B,SAAO,UAAUA,MAAoB,UAAbA,GAAIL;AAC7B;AAGO,SAASO,EAAgBF,IAAAA;AAC/B,SAAA,EAAS,UAAUA;AACpB;AAGO,SAASG,EAAgBC,IAAoBC,IAAAA;AACnD,SAAIN,EAAgBK,OAAML,EAAgBM,EAAAA,IAClCD,GAAEX,WAAWY,GAAEZ,SAEnBQ,EAAYG,EAAAA,KAAMH,EAAYI,EAAAA,IAC1BD,GAAEP,YAAYQ,GAAER,WAAWO,GAAEN,SAASO,GAAEP,OAAAA,EAAAA,CAE5CI,EAAgBE,EAAAA,KAAAA,CAAMF,EAAgBG,EAAAA,MAExCD,GAAEE,OAAOT,YAAYQ,GAAEC,OAAOT,WAC9BO,GAAEE,OAAOC,WAAWF,GAAEC,OAAOC,UAC7BH,GAAEI,KAAKX,YAAYQ,GAAEG,KAAKX,WAC1BO,GAAEI,KAAKD,WAAWF,GAAEG,KAAKD;AAI5B;AAGO,SAASE,EACfZ,IACAU,IACAb,IAAAA;AAEA,SAAOA,KAAO,EAAEG,SAAAA,IAASU,QAAAA,IAAQb,MAAAA,GAAAA,IAAS,EAAEG,SAAAA,IAASU,QAAAA,GAAAA;AACtD;AAGO,SAASG,EAAgBJ,IAAkBE;AACjD,SAAO,EAAEF,QAAAA,IAAQE,MAAAA,GAAAA;AAClB;AAGO,SAASG,EAAyBd,IAAkBU,IAAAA;AAC1D,QAAMK,KAAgB,EAAEf,SAAAA,IAASU,QAAAA,GAAAA;AACjC,SAAO,EAAED,QAAQM,IAAKJ,MAAMI,GAAAA;AAC7B;AAGO,SAASC,EAAYb,IAAAA;AAC3B,SAAA,CAAID,EAAgBC,EAAAA,KAAAA,CAAQC,EAAYD,EAAAA,KACjCA,GAAIM,OAAOT,YAAYG,GAAIQ,KAAKX,WAAWG,GAAIM,OAAOC,WAAWP,GAAIQ,KAAKD;AAClF;AAQO,SAASO,EAAUd,IAAsBe,IAAAA;AAC/C,SAAA,EAAA,CAAIhB,EAAgBC,EAAAA,KAAAA,CAAQC,EAAYD,EAAAA,OACpCA,GAAIM,OAAOT,YAAYG,GAAIQ,KAAKX,UAC5BG,GAAIM,OAAOC,UAAUP,GAAIQ,KAAKD,SAAAA,CAElCQ,MACeA,GAAWC,QAAQhB,GAAIM,OAAOT,OAAAA,KAChCkB,GAAWC,QAAQhB,GAAIQ,KAAKX,OAAAA;AAI9C;AAMO,SAASoB,EAAejB,IAAgBe,IAAAA;AAC9C,SAAID,EAAUd,IAAKe,EAAAA,IACX,EAAEG,MAAMlB,GAAIM,QAAQa,IAAInB,GAAIQ,KAAAA,IAE7B,EAAEU,MAAMlB,GAAIQ,MAAMW,IAAInB,GAAIM,OAAAA;AAClC;"}
1
+ {"version":3,"file":"Selection-BRTab5hO.mjs","sources":["../../src/model/Selection.ts"],"sourcesContent":["/**\n * Selection model for the Notectl editor.\n * A selection is defined by an anchor and head position within the document.\n */\n\nimport type { BlockId } from './TypeBrands.js';\n\nexport interface Position {\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n\t/** Path from root block to leaf block (optional, for nested structures). */\n\treadonly path?: readonly BlockId[];\n}\n\nexport interface Selection {\n\treadonly anchor: Position;\n\treadonly head: Position;\n}\n\nexport interface SelectionRange {\n\treadonly from: Position;\n\treadonly to: Position;\n}\n\n/** A selection that selects an entire node (e.g. void blocks, table selection). */\nexport interface NodeSelection {\n\treadonly type: 'node';\n\treadonly nodeId: BlockId;\n\treadonly path: readonly BlockId[];\n}\n\n/** A virtual cursor at the boundary of a void block where no native caret can exist. */\nexport interface GapCursorSelection {\n\treadonly type: 'gap';\n\treadonly side: 'before' | 'after';\n\treadonly blockId: BlockId;\n\treadonly path: readonly BlockId[];\n}\n\n/** Union type representing a text selection, node selection, or gap cursor. */\nexport type EditorSelection = Selection | NodeSelection | GapCursorSelection;\n\n/** Creates a NodeSelection for the given block. */\nexport function createNodeSelection(nodeId: BlockId, path: readonly BlockId[]): NodeSelection {\n\treturn { type: 'node', nodeId, path };\n}\n\n/** Creates a GapCursorSelection at the boundary of a void block. */\nexport function createGapCursor(\n\tblockId: BlockId,\n\tside: 'before' | 'after',\n\tpath: readonly BlockId[],\n): GapCursorSelection {\n\treturn { type: 'gap', side, blockId, path };\n}\n\n/** Type guard: returns true if the selection is a NodeSelection. */\nexport function isNodeSelection(sel: EditorSelection): sel is NodeSelection {\n\treturn 'type' in sel && sel.type === 'node';\n}\n\n/** Type guard: returns true if the selection is a GapCursorSelection. */\nexport function isGapCursor(sel: EditorSelection): sel is GapCursorSelection {\n\treturn 'type' in sel && sel.type === 'gap';\n}\n\n/** Type guard: returns true if the selection is a text Selection. */\nexport function isTextSelection(sel: EditorSelection): sel is Selection {\n\treturn !('type' in sel);\n}\n\n/** Compares two EditorSelections for equality. */\nexport function selectionsEqual(a: EditorSelection, b: EditorSelection): boolean {\n\tif (isNodeSelection(a) && isNodeSelection(b)) {\n\t\treturn a.nodeId === b.nodeId;\n\t}\n\tif (isGapCursor(a) && isGapCursor(b)) {\n\t\treturn a.blockId === b.blockId && a.side === b.side;\n\t}\n\tif (isTextSelection(a) && isTextSelection(b)) {\n\t\treturn (\n\t\t\ta.anchor.blockId === b.anchor.blockId &&\n\t\t\ta.anchor.offset === b.anchor.offset &&\n\t\t\ta.head.blockId === b.head.blockId &&\n\t\t\ta.head.offset === b.head.offset\n\t\t);\n\t}\n\treturn false;\n}\n\n/** Creates a Position, optionally with a path. */\nexport function createPosition(\n\tblockId: BlockId,\n\toffset: number,\n\tpath?: readonly BlockId[],\n): Position {\n\treturn path ? { blockId, offset, path } : { blockId, offset };\n}\n\n/** Creates a selection with distinct anchor and head. */\nexport function createSelection(anchor: Position, head: Position): Selection {\n\treturn { anchor, head };\n}\n\n/** Creates a collapsed selection (cursor) at the given position. */\nexport function createCollapsedSelection(blockId: BlockId, offset: number): Selection {\n\tconst pos: Position = { blockId, offset };\n\treturn { anchor: pos, head: pos };\n}\n\n/** Returns true if the selection is collapsed (cursor with no range). NodeSelection and GapCursor are never collapsed. */\nexport function isCollapsed(sel: EditorSelection): boolean {\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return false;\n\treturn sel.anchor.blockId === sel.head.blockId && sel.anchor.offset === sel.head.offset;\n}\n\n/**\n * Returns true if the selection direction is forward (anchor before head).\n * When anchor and head are in the same block, compares offsets.\n * Cross-block ordering uses document order (not determinable here — caller provides block order).\n * For NodeSelection, always returns true.\n */\nexport function isForward(sel: EditorSelection, blockOrder?: readonly BlockId[]): boolean {\n\tif (isNodeSelection(sel) || isGapCursor(sel)) return true;\n\tif (sel.anchor.blockId === sel.head.blockId) {\n\t\treturn sel.anchor.offset <= sel.head.offset;\n\t}\n\tif (blockOrder) {\n\t\tconst anchorIdx = blockOrder.indexOf(sel.anchor.blockId);\n\t\tconst headIdx = blockOrder.indexOf(sel.head.blockId);\n\t\treturn anchorIdx <= headIdx;\n\t}\n\treturn true;\n}\n\n/**\n * Returns a normalized range where `from` is always before `to`.\n * Throws for NodeSelection — use isNodeSelection() guard first.\n */\nexport function selectionRange(sel: Selection, blockOrder?: readonly BlockId[]): SelectionRange {\n\tif (isForward(sel, blockOrder)) {\n\t\treturn { from: sel.anchor, to: sel.head };\n\t}\n\treturn { from: sel.head, to: sel.anchor };\n}\n"],"names":["createNodeSelection","nodeId","path","type","createGapCursor","blockId","side","isNodeSelection","sel","isGapCursor","isTextSelection","selectionsEqual","a","b","anchor","offset","head","createPosition","createSelection","createCollapsedSelection","pos","isCollapsed","isForward","blockOrder","indexOf","selectionRange","from","to"],"mappings":"AA2CO,SAASA,EAAoBC,IAAiBC,IAAAA;AACpD,SAAO,EAAEC,MAAM,QAAQF,QAAAA,IAAQC,MAAAA,GAAAA;AAChC;AAGO,SAASE,EACfC,IACAC,IACAJ,IAAAA;AAEA,SAAO,EAAEC,MAAM,OAAOG,MAAAA,IAAMD,SAAAA,IAASH,MAAAA,GAAAA;AACtC;AAGO,SAASK,EAAgBC,IAAAA;AAC/B,SAAO,UAAUA,MAAoB,WAAbA,GAAIL;AAC7B;AAGO,SAASM,EAAYD,IAAAA;AAC3B,SAAO,UAAUA,MAAoB,UAAbA,GAAIL;AAC7B;AAGO,SAASO,EAAgBF,IAAAA;AAC/B,SAAA,EAAS,UAAUA;AACpB;AAGO,SAASG,EAAgBC,IAAoBC,IAAAA;AACnD,SAAIN,EAAgBK,OAAML,EAAgBM,EAAAA,IAClCD,GAAEX,WAAWY,GAAEZ,SAEnBQ,EAAYG,EAAAA,KAAMH,EAAYI,EAAAA,IAC1BD,GAAEP,YAAYQ,GAAER,WAAWO,GAAEN,SAASO,GAAEP,OAAAA,EAAAA,CAE5CI,EAAgBE,EAAAA,KAAAA,CAAMF,EAAgBG,EAAAA,MAExCD,GAAEE,OAAOT,YAAYQ,GAAEC,OAAOT,WAC9BO,GAAEE,OAAOC,WAAWF,GAAEC,OAAOC,UAC7BH,GAAEI,KAAKX,YAAYQ,GAAEG,KAAKX,WAC1BO,GAAEI,KAAKD,WAAWF,GAAEG,KAAKD;AAI5B;AAGO,SAASE,EACfZ,IACAU,IACAb,IAAAA;AAEA,SAAOA,KAAO,EAAEG,SAAAA,IAASU,QAAAA,IAAQb,MAAAA,GAAAA,IAAS,EAAEG,SAAAA,IAASU,QAAAA,GAAAA;AACtD;AAGO,SAASG,EAAgBJ,IAAkBE;AACjD,SAAO,EAAEF,QAAAA,IAAQE,MAAAA,GAAAA;AAClB;AAGO,SAASG,EAAyBd,IAAkBU,IAAAA;AAC1D,QAAMK,KAAgB,EAAEf,SAAAA,IAASU,QAAAA,GAAAA;AACjC,SAAO,EAAED,QAAQM,IAAKJ,MAAMI,GAAAA;AAC7B;AAGO,SAASC,EAAYb,IAAAA;AAC3B,SAAA,CAAID,EAAgBC,EAAAA,KAAAA,CAAQC,EAAYD,EAAAA,KACjCA,GAAIM,OAAOT,YAAYG,GAAIQ,KAAKX,WAAWG,GAAIM,OAAOC,WAAWP,GAAIQ,KAAKD;AAClF;AAQO,SAASO,EAAUd,IAAsBe,IAAAA;AAC/C,SAAA,EAAA,CAAIhB,EAAgBC,EAAAA,KAAAA,CAAQC,EAAYD,EAAAA,OACpCA,GAAIM,OAAOT,YAAYG,GAAIQ,KAAKX,UAC5BG,GAAIM,OAAOC,UAAUP,GAAIQ,KAAKD,SAAAA,CAElCQ,MACeA,GAAWC,QAAQhB,GAAIM,OAAOT,OAAAA,KAChCkB,GAAWC,QAAQhB,GAAIQ,KAAKX,OAAAA;AAI9C;AAMO,SAASoB,EAAejB,IAAgBe,IAAAA;AAC9C,SAAID,EAAUd,IAAKe,EAAAA,IACX,EAAEG,MAAMlB,GAAIM,QAAQa,IAAInB,GAAIQ,KAAAA,IAE7B,EAAEU,MAAMlB,GAAIQ,MAAMW,IAAInB,GAAIM,OAAAA;AAClC;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ToolbarItem-BpZggUGo.mjs","sources":["../../src/plugins/toolbar/ToolbarItem.ts"],"sourcesContent":["/**\n * ToolbarItem: describes a toolbar button registered by a plugin.\n */\n\nimport type { EditorState } from '../../state/EditorState.js';\nimport { isMac } from '../../view/Platform.js';\nimport type { PluginContext } from '../Plugin.js';\n\nexport interface GridPickerConfig {\n\treadonly maxRows: number;\n\treadonly maxCols: number;\n\tonSelect(rows: number, cols: number): void;\n}\n\nexport interface DropdownConfig {\n\treadonly items: readonly { label: string; command: string; icon?: string }[];\n}\n\nexport type ToolbarGroup = 'format' | 'block' | 'insert' | (string & {});\nexport type PopupType = 'gridPicker' | 'dropdown' | 'custom';\n\ninterface ToolbarItemBase {\n\treadonly id: string;\n\t/** Grouping key: 'format' | 'insert' | 'block' or custom. */\n\treadonly group: ToolbarGroup;\n\t/** Icon content: inline SVG markup or plain text. Rendered via innerHTML. */\n\treadonly icon: string;\n\treadonly label: string;\n\t/** Tooltip shown on hover, e.g. \"Bold (Ctrl+B)\". Falls back to label. */\n\treadonly tooltip?: string;\n\t/** Command name to execute on click. */\n\treadonly command: string;\n\t/**\n\t * Lower priority renders further left.\n\t * @deprecated Use the declarative `toolbar` config on `createEditor()` instead.\n\t */\n\treadonly priority?: number;\n\t/**\n\t * When true, a visual separator is rendered after this item.\n\t * @deprecated Use the declarative `toolbar` config on `createEditor()` instead.\n\t */\n\treadonly separatorAfter?: boolean;\n\tisActive?(state: EditorState): boolean;\n\tisEnabled?(state: EditorState): boolean;\n}\n\ninterface ToolbarItemNoPopup extends ToolbarItemBase {\n\treadonly popupType?: undefined;\n}\n\ninterface ToolbarItemGridPicker extends ToolbarItemBase {\n\treadonly popupType: 'gridPicker';\n\treadonly popupConfig: GridPickerConfig;\n}\n\ninterface ToolbarItemDropdown extends ToolbarItemBase {\n\treadonly popupType: 'dropdown';\n\treadonly popupConfig: DropdownConfig;\n}\n\ninterface ToolbarItemCustomPopup extends ToolbarItemBase {\n\treadonly popupType: 'custom';\n\trenderPopup(container: HTMLElement, context: PluginContext, onClose: () => void): void;\n}\n\nexport type ToolbarItem =\n\t| ToolbarItemNoPopup\n\t| ToolbarItemGridPicker\n\t| ToolbarItemDropdown\n\t| ToolbarItemCustomPopup;\n\n/**\n * Formats a keymap binding string into a human-readable shortcut,\n * using platform-appropriate modifier symbols (⌘ on Mac, Ctrl on others).\n *\n * @example formatShortcut('Mod-B') → \"Ctrl+B\" or \"⌘B\"\n * @example formatShortcut('Mod-Shift-X') → \"Ctrl+Shift+X\" or \"⌘⇧X\"\n */\nexport function formatShortcut(binding: string): string {\n\tif (isMac()) {\n\t\treturn binding\n\t\t\t.replace(/Mod/g, '⌘')\n\t\t\t.replace(/Shift/g, '⇧')\n\t\t\t.replace(/Alt/g, '⌥')\n\t\t\t.replace(/-/g, '');\n\t}\n\treturn binding.replace(/Mod/g, 'Ctrl').replace(/-/g, '+');\n}\n"],"names":["formatShortcut","binding","isMac","replace"],"mappings":";AA8EO,SAASA,EAAeC,IAAAA;AAC9B,SAAIC,EAAAA,IACID,GACLE,QAAQ,QAAQ,GAAA,EAChBA,QAAQ,UAAU,GAAA,EAClBA,QAAQ,QAAQ,GAAA,EAChBA,QAAQ,MAAM,EAAA,IAEVF,GAAQE,QAAQ,QAAQ,MAAA,EAAQA,QAAQ,MAAM,GAAA;AACtD;"}
1
+ {"version":3,"file":"ToolbarItem-BpZggUGo.mjs","sources":["../../src/plugins/toolbar/ToolbarItem.ts"],"sourcesContent":["/**\n * ToolbarItem: describes a toolbar button registered by a plugin.\n */\n\nimport type { EditorState } from '../../state/EditorState.js';\nimport { isMac } from '../../view/Platform.js';\nimport type { PluginContext } from '../Plugin.js';\n\nexport interface GridPickerConfig {\n\treadonly maxRows: number;\n\treadonly maxCols: number;\n\tonSelect(rows: number, cols: number): void;\n}\n\nexport interface DropdownConfig {\n\treadonly items: readonly { label: string; command: string; icon?: string }[];\n}\n\nexport type ToolbarGroup = 'format' | 'block' | 'insert' | (string & {});\nexport type PopupType = 'gridPicker' | 'dropdown' | 'custom' | 'combobox';\n\ninterface ToolbarItemBase {\n\treadonly id: string;\n\t/** Grouping key: 'format' | 'insert' | 'block' or custom. */\n\treadonly group: ToolbarGroup;\n\t/** Icon content: inline SVG markup or plain text. Rendered via innerHTML. */\n\treadonly icon: string;\n\treadonly label: string;\n\t/** Tooltip shown on hover, e.g. \"Bold (Ctrl+B)\". Falls back to label. */\n\treadonly tooltip?: string;\n\t/** Command name to execute on click. */\n\treadonly command: string;\n\t/**\n\t * Lower priority renders further left.\n\t * @deprecated Use the declarative `toolbar` config on `createEditor()` instead.\n\t */\n\treadonly priority?: number;\n\t/**\n\t * When true, a visual separator is rendered after this item.\n\t * @deprecated Use the declarative `toolbar` config on `createEditor()` instead.\n\t */\n\treadonly separatorAfter?: boolean;\n\tisActive?(state: EditorState): boolean;\n\tisEnabled?(state: EditorState): boolean;\n}\n\ninterface ToolbarItemNoPopup extends ToolbarItemBase {\n\treadonly popupType?: undefined;\n}\n\ninterface ToolbarItemGridPicker extends ToolbarItemBase {\n\treadonly popupType: 'gridPicker';\n\treadonly popupConfig: GridPickerConfig;\n}\n\ninterface ToolbarItemDropdown extends ToolbarItemBase {\n\treadonly popupType: 'dropdown';\n\treadonly popupConfig: DropdownConfig;\n}\n\ninterface ToolbarItemCustomPopup extends ToolbarItemBase {\n\treadonly popupType: 'custom';\n\trenderPopup(container: HTMLElement, context: PluginContext, onClose: () => void): void;\n}\n\nexport interface ToolbarItemCombobox extends Omit<ToolbarItemBase, 'icon'> {\n\treadonly popupType: 'combobox';\n\t/** Optional icon — combobox items typically display a text label instead. */\n\treadonly icon?: string;\n\t/** Pure function returning the current label text. Called on every state change. */\n\tgetLabel(state: EditorState): string;\n\t/** Renders the popup content when the combobox is opened. */\n\trenderPopup(container: HTMLElement, context: PluginContext, onClose: () => void): void;\n}\n\nexport type ToolbarItem =\n\t| ToolbarItemNoPopup\n\t| ToolbarItemGridPicker\n\t| ToolbarItemDropdown\n\t| ToolbarItemCustomPopup\n\t| ToolbarItemCombobox;\n\n/**\n * Formats a keymap binding string into a human-readable shortcut,\n * using platform-appropriate modifier symbols (⌘ on Mac, Ctrl on others).\n *\n * @example formatShortcut('Mod-B') → \"Ctrl+B\" or \"⌘B\"\n * @example formatShortcut('Mod-Shift-X') → \"Ctrl+Shift+X\" or \"⌘⇧X\"\n */\nexport function formatShortcut(binding: string): string {\n\tif (isMac()) {\n\t\treturn binding\n\t\t\t.replace(/Mod/g, '⌘')\n\t\t\t.replace(/Shift/g, '⇧')\n\t\t\t.replace(/Alt/g, '⌥')\n\t\t\t.replace(/-/g, '');\n\t}\n\treturn binding.replace(/Mod/g, 'Ctrl').replace(/-/g, '+');\n}\n"],"names":["formatShortcut","binding","isMac","replace"],"mappings":";AAyFO,SAASA,EAAeC,IAAAA;AAC9B,SAAIC,EAAAA,IACID,GACLE,QAAQ,QAAQ,GAAA,EAChBA,QAAQ,UAAU,GAAA,EAClBA,QAAQ,QAAQ,GAAA,EAChBA,QAAQ,MAAM,EAAA,IAEVF,GAAQE,QAAQ,QAAQ,MAAA,EAAQA,QAAQ,MAAM,GAAA;AACtD;"}
@@ -36,11 +36,11 @@ function u(t2, r2, n2, e2, o2) {
36
36
  }
37
37
  }
38
38
  export {
39
- r as a,
40
- e as b,
39
+ e as a,
40
+ r as b,
41
41
  n as c,
42
42
  t as d,
43
43
  o as f,
44
44
  u as n
45
45
  };
46
- //# sourceMappingURL=ToolbarKeyboardNav-B32OMv8r.mjs.map
46
+ //# sourceMappingURL=ToolbarKeyboardNav-DhpL8zNV.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ToolbarKeyboardNav-B32OMv8r.mjs","sources":["../../src/plugins/toolbar/ToolbarKeyboardNav.ts"],"sourcesContent":["/**\n * Keyboard navigation helpers for the toolbar (WAI-ARIA Toolbar pattern).\n * Pure functions that operate on arrays of buttons and DOM elements.\n */\n\n/** Returns indices of all enabled buttons. */\nexport function getEnabledIndices(buttons: readonly HTMLButtonElement[]): number[] {\n\tconst result: number[] = [];\n\tfor (let i = 0; i < buttons.length; i++) {\n\t\tif (!buttons[i]?.disabled) {\n\t\t\tresult.push(i);\n\t\t}\n\t}\n\treturn result;\n}\n\n/** Finds the next enabled button index in the given direction (wraps around). */\nexport function findNextEnabled(\n\tbuttons: readonly HTMLButtonElement[],\n\tcurrent: number,\n\tdirection: 1 | -1,\n): number {\n\tconst len = buttons.length;\n\tif (len === 0) return -1;\n\n\tlet index = current;\n\tfor (let i = 0; i < len; i++) {\n\t\tindex = (index + direction + len) % len;\n\t\tif (!buttons[index]?.disabled) {\n\t\t\treturn index;\n\t\t}\n\t}\n\treturn current;\n}\n\n/** Finds the first enabled button index. */\nexport function findFirstEnabled(buttons: readonly HTMLButtonElement[]): number {\n\tfor (let i = 0; i < buttons.length; i++) {\n\t\tif (!buttons[i]?.disabled) return i;\n\t}\n\treturn -1;\n}\n\n/** Finds the last enabled button index. */\nexport function findLastEnabled(buttons: readonly HTMLButtonElement[]): number {\n\tfor (let i = buttons.length - 1; i >= 0; i--) {\n\t\tif (!buttons[i]?.disabled) return i;\n\t}\n\treturn -1;\n}\n\n/**\n * Applies roving tabindex: sets tabindex=\"0\" on the focused button,\n * tabindex=\"-1\" on all others.\n */\nexport function applyRovingTabindex(\n\tbuttons: readonly HTMLButtonElement[],\n\tfocusedIndex: number,\n): void {\n\tfor (let i = 0; i < buttons.length; i++) {\n\t\tconst btn = buttons[i];\n\t\tif (btn) {\n\t\t\tbtn.setAttribute('tabindex', i === focusedIndex ? '0' : '-1');\n\t\t}\n\t}\n}\n\n/** Navigates dropdown items with arrow keys (wraps around). */\nexport function findNextDropdownItem(\n\titems: readonly HTMLElement[],\n\tcurrent: number,\n\tdirection: 1 | -1,\n): number {\n\tconst len = items.length;\n\tif (len === 0) return -1;\n\treturn (current + direction + len) % len;\n}\n\n/**\n * Navigates a grid of cells with arrow keys.\n * Returns the new [row, col] position.\n */\nexport function navigateGrid(\n\trow: number,\n\tcol: number,\n\tmaxRows: number,\n\tmaxCols: number,\n\tkey: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight',\n): [number, number] {\n\tswitch (key) {\n\t\tcase 'ArrowUp':\n\t\t\treturn [row > 1 ? row - 1 : maxRows, col];\n\t\tcase 'ArrowDown':\n\t\t\treturn [row < maxRows ? row + 1 : 1, col];\n\t\tcase 'ArrowLeft':\n\t\t\treturn [row, col > 1 ? col - 1 : maxCols];\n\t\tcase 'ArrowRight':\n\t\t\treturn [row, col < maxCols ? col + 1 : 1];\n\t}\n}\n"],"names":["findNextEnabled","buttons","current","direction","len","length","index","i","disabled","findFirstEnabled","findLastEnabled","applyRovingTabindex","focusedIndex","btn","setAttribute","findNextDropdownItem","items","navigateGrid","row","col","maxRows","maxCols","key"],"mappings":"AAiBO,SAASA,EACfC,IACAC,IACAC;AAEA,QAAMC,KAAMH,GAAQI;AACpB,MAAY,MAARD,GAAW;AAEf,MAAIE,KAAQJ;AACZ,WAASK,KAAI,GAAGA,KAAIH,IAAKG,KAExB,KADAD,MAASA,KAAQH,KAAYC,MAAOA,KAC/BH,GAAQK,EAAAA,GAAQE,SACpB,QAAOF;AAGT,SAAOJ;AACR;AAGO,SAASO,EAAiBR,IAAAA;AAChC,WAASM,KAAI,GAAGA,KAAIN,GAAQI,QAAQE,KACnC,MAAKN,GAAQM,EAAAA,GAAIC,SAAU,QAAOD;AAEnC,SAAA;AACD;AAGO,SAASG,EAAgBT;AAC/B,WAASM,KAAIN,GAAQI,SAAS,GAAGE,MAAK,GAAGA,KACxC,KAAA,CAAKN,GAAQM,EAAAA,GAAIC,SAAU,QAAOD;AAEnC,SAAA;AACD;AAMO,SAASI,EACfV,IACAW,IAAAA;AAEA,WAASL,KAAI,GAAGA,KAAIN,GAAQI,QAAQE,MAAK;AACxC,UAAMM,KAAMZ,GAAQM,EAAAA;AAChBM,IAAAA,MACHA,GAAIC,aAAa,YAAYP,OAAMK,KAAe,MAAM,IAAA;AAAA,EAE1D;AACD;AAGO,SAASG,EACfC,IACAd,IACAC,IAAAA;AAEA,QAAMC,KAAMY,GAAMX;AAClB,SAAY,MAARD,KAAAA,MACIF,KAAUC,KAAYC,MAAOA;AACtC;AAMO,SAASa,EACfC,IACAC,IACAC,IACAC,IACAC,IAAAA;AAEA,UAAQA,IAAAA;AAAAA,IACP,KAAK;AACJ,aAAO,CAACJ,KAAM,IAAIA,KAAM,IAAIE,IAASD;IACtC,KAAK;AACJ,aAAO,CAACD,KAAME,KAAUF,KAAM,IAAI,GAAGC,EAAAA;AAAAA,IACtC,KAAK;AACJ,aAAO,CAACD,IAAKC,KAAM,IAAIA,KAAM,IAAIE;IAClC,KAAK;AACJ,aAAO,CAACH,IAAKC,KAAME,KAAUF,KAAM,IAAI,CAAA;AAAA,EAAA;AAE1C;"}
1
+ {"version":3,"file":"ToolbarKeyboardNav-DhpL8zNV.mjs","sources":["../../src/plugins/toolbar/ToolbarKeyboardNav.ts"],"sourcesContent":["/**\n * Keyboard navigation helpers for the toolbar (WAI-ARIA Toolbar pattern).\n * Pure functions that operate on arrays of buttons and DOM elements.\n */\n\n/** Returns indices of all enabled buttons. */\nexport function getEnabledIndices(buttons: readonly HTMLButtonElement[]): number[] {\n\tconst result: number[] = [];\n\tfor (let i = 0; i < buttons.length; i++) {\n\t\tif (!buttons[i]?.disabled) {\n\t\t\tresult.push(i);\n\t\t}\n\t}\n\treturn result;\n}\n\n/** Finds the next enabled button index in the given direction (wraps around). */\nexport function findNextEnabled(\n\tbuttons: readonly HTMLButtonElement[],\n\tcurrent: number,\n\tdirection: 1 | -1,\n): number {\n\tconst len = buttons.length;\n\tif (len === 0) return -1;\n\n\tlet index = current;\n\tfor (let i = 0; i < len; i++) {\n\t\tindex = (index + direction + len) % len;\n\t\tif (!buttons[index]?.disabled) {\n\t\t\treturn index;\n\t\t}\n\t}\n\treturn current;\n}\n\n/** Finds the first enabled button index. */\nexport function findFirstEnabled(buttons: readonly HTMLButtonElement[]): number {\n\tfor (let i = 0; i < buttons.length; i++) {\n\t\tif (!buttons[i]?.disabled) return i;\n\t}\n\treturn -1;\n}\n\n/** Finds the last enabled button index. */\nexport function findLastEnabled(buttons: readonly HTMLButtonElement[]): number {\n\tfor (let i = buttons.length - 1; i >= 0; i--) {\n\t\tif (!buttons[i]?.disabled) return i;\n\t}\n\treturn -1;\n}\n\n/**\n * Applies roving tabindex: sets tabindex=\"0\" on the focused button,\n * tabindex=\"-1\" on all others.\n */\nexport function applyRovingTabindex(\n\tbuttons: readonly HTMLButtonElement[],\n\tfocusedIndex: number,\n): void {\n\tfor (let i = 0; i < buttons.length; i++) {\n\t\tconst btn = buttons[i];\n\t\tif (btn) {\n\t\t\tbtn.setAttribute('tabindex', i === focusedIndex ? '0' : '-1');\n\t\t}\n\t}\n}\n\n/** Navigates dropdown items with arrow keys (wraps around). */\nexport function findNextDropdownItem(\n\titems: readonly HTMLElement[],\n\tcurrent: number,\n\tdirection: 1 | -1,\n): number {\n\tconst len = items.length;\n\tif (len === 0) return -1;\n\treturn (current + direction + len) % len;\n}\n\n/**\n * Navigates a grid of cells with arrow keys.\n * Returns the new [row, col] position.\n */\nexport function navigateGrid(\n\trow: number,\n\tcol: number,\n\tmaxRows: number,\n\tmaxCols: number,\n\tkey: 'ArrowUp' | 'ArrowDown' | 'ArrowLeft' | 'ArrowRight',\n): [number, number] {\n\tswitch (key) {\n\t\tcase 'ArrowUp':\n\t\t\treturn [row > 1 ? row - 1 : maxRows, col];\n\t\tcase 'ArrowDown':\n\t\t\treturn [row < maxRows ? row + 1 : 1, col];\n\t\tcase 'ArrowLeft':\n\t\t\treturn [row, col > 1 ? col - 1 : maxCols];\n\t\tcase 'ArrowRight':\n\t\t\treturn [row, col < maxCols ? col + 1 : 1];\n\t}\n}\n"],"names":["findNextEnabled","buttons","current","direction","len","length","index","i","disabled","findFirstEnabled","findLastEnabled","applyRovingTabindex","focusedIndex","btn","setAttribute","findNextDropdownItem","items","navigateGrid","row","col","maxRows","maxCols","key"],"mappings":"AAiBO,SAASA,EACfC,IACAC,IACAC;AAEA,QAAMC,KAAMH,GAAQI;AACpB,MAAY,MAARD,GAAW;AAEf,MAAIE,KAAQJ;AACZ,WAASK,KAAI,GAAGA,KAAIH,IAAKG,KAExB,KADAD,MAASA,KAAQH,KAAYC,MAAOA,KAC/BH,GAAQK,EAAAA,GAAQE,SACpB,QAAOF;AAGT,SAAOJ;AACR;AAGO,SAASO,EAAiBR,IAAAA;AAChC,WAASM,KAAI,GAAGA,KAAIN,GAAQI,QAAQE,KACnC,MAAKN,GAAQM,EAAAA,GAAIC,SAAU,QAAOD;AAEnC,SAAA;AACD;AAGO,SAASG,EAAgBT;AAC/B,WAASM,KAAIN,GAAQI,SAAS,GAAGE,MAAK,GAAGA,KACxC,KAAA,CAAKN,GAAQM,EAAAA,GAAIC,SAAU,QAAOD;AAEnC,SAAA;AACD;AAMO,SAASI,EACfV,IACAW,IAAAA;AAEA,WAASL,KAAI,GAAGA,KAAIN,GAAQI,QAAQE,MAAK;AACxC,UAAMM,KAAMZ,GAAQM,EAAAA;AAChBM,IAAAA,MACHA,GAAIC,aAAa,YAAYP,OAAMK,KAAe,MAAM,IAAA;AAAA,EAE1D;AACD;AAGO,SAASG,EACfC,IACAd,IACAC,IAAAA;AAEA,QAAMC,KAAMY,GAAMX;AAClB,SAAY,MAARD,KAAAA,MACIF,KAAUC,KAAYC,MAAOA;AACtC;AAMO,SAASa,EACfC,IACAC,IACAC,IACAC,IACAC,IAAAA;AAEA,UAAQA,IAAAA;AAAAA,IACP,KAAK;AACJ,aAAO,CAACJ,KAAM,IAAIA,KAAM,IAAIE,IAASD;IACtC,KAAK;AACJ,aAAO,CAACD,KAAME,KAAUF,KAAM,IAAI,GAAGC,EAAAA;AAAAA,IACtC,KAAK;AACJ,aAAO,CAACD,IAAKC,KAAM,IAAIA,KAAM,IAAIE;IAClC,KAAK;AACJ,aAAO,CAACH,IAAKC,KAAME,KAAUF,KAAM,IAAI,CAAA;AAAA,EAAA;AAE1C;"}