@notectl/core 2.3.1 → 2.3.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 (197) hide show
  1. package/README.md +1 -1
  2. package/THIRD-PARTY-NOTICES.md +129 -0
  3. package/dist/chunks/{AlignmentPlugin--xAFlRqE.mjs → AlignmentPlugin-C9Rr_R-g.mjs} +2 -2
  4. package/dist/chunks/{AlignmentPlugin--xAFlRqE.mjs.map → AlignmentPlugin-C9Rr_R-g.mjs.map} +1 -1
  5. package/dist/chunks/{AttributedMarkCommands-bagbH8Qt.mjs → AttributedMarkCommands-BCvmqeFZ.mjs} +2 -2
  6. package/dist/chunks/{AttributedMarkCommands-bagbH8Qt.mjs.map → AttributedMarkCommands-BCvmqeFZ.mjs.map} +1 -1
  7. package/dist/chunks/{BidiIsolationPlugin-DBXyXpgm.mjs → BidiIsolationPlugin-Cw2KMk-H.mjs} +2 -2
  8. package/dist/chunks/{BidiIsolationPlugin-DBXyXpgm.mjs.map → BidiIsolationPlugin-Cw2KMk-H.mjs.map} +1 -1
  9. package/dist/chunks/{BlockInsertion-CJusvrDL.mjs → BlockInsertion-CYH2gRkY.mjs} +2 -2
  10. package/dist/chunks/{BlockInsertion-CJusvrDL.mjs.map → BlockInsertion-CYH2gRkY.mjs.map} +1 -1
  11. package/dist/chunks/{BlockquotePlugin-Bz2glHwX.mjs → BlockquotePlugin-0bZSbkyo.mjs} +2 -2
  12. package/dist/chunks/{BlockquotePlugin-Bz2glHwX.mjs.map → BlockquotePlugin-0bZSbkyo.mjs.map} +1 -1
  13. package/dist/chunks/CaretNavigationPlugin-BPZ9b6XR.mjs +2 -0
  14. package/dist/chunks/CaretNavigationPlugin-BPZ9b6XR.mjs.map +1 -0
  15. package/dist/chunks/CodeBlockPlugin-BCJ3faXx.mjs +2 -0
  16. package/dist/chunks/{CodeBlockPlugin-C1hrdbSZ.mjs.map → CodeBlockPlugin-BCJ3faXx.mjs.map} +1 -1
  17. package/dist/chunks/{ColorGrid-C9RQoEWF.mjs → ColorGrid-DQEkJ-0y.mjs} +2 -2
  18. package/dist/chunks/{ColorGrid-C9RQoEWF.mjs.map → ColorGrid-DQEkJ-0y.mjs.map} +1 -1
  19. package/dist/chunks/ColorPickerPopup-CyF26zIU.mjs +2 -0
  20. package/dist/chunks/{ColorPickerPopup-DiA68Pzz.mjs.map → ColorPickerPopup-CyF26zIU.mjs.map} +1 -1
  21. package/dist/chunks/Commands-D5ND50PQ.mjs +2 -0
  22. package/dist/chunks/{Commands-1dFFldi7.mjs.map → Commands-D5ND50PQ.mjs.map} +1 -1
  23. package/dist/chunks/{Decoration-BpoEOANl.mjs → Decoration-BOP1TAUd.mjs} +2 -2
  24. package/dist/chunks/{Decoration-BpoEOANl.mjs.map → Decoration-BOP1TAUd.mjs.map} +1 -1
  25. package/dist/chunks/{FontPlugin-By-TGrQo.mjs → FontPlugin-D041tiLe.mjs} +2 -2
  26. package/dist/chunks/{FontPlugin-By-TGrQo.mjs.map → FontPlugin-D041tiLe.mjs.map} +1 -1
  27. package/dist/chunks/{FontSizePlugin-Dln-tYXV.mjs → FontSizePlugin-8CAvj1RD.mjs} +2 -2
  28. package/dist/chunks/{FontSizePlugin-Dln-tYXV.mjs.map → FontSizePlugin-8CAvj1RD.mjs.map} +1 -1
  29. package/dist/chunks/{FormulaPlugin-By1befrR.mjs → FormulaPlugin-DJ39BtqV.mjs} +2 -2
  30. package/dist/chunks/FormulaPlugin-DJ39BtqV.mjs.map +1 -0
  31. package/dist/chunks/GapCursorNavigation-DCWOmopl.mjs +2 -0
  32. package/dist/chunks/{GapCursorNavigation-BuXngVu-.mjs.map → GapCursorNavigation-DCWOmopl.mjs.map} +1 -1
  33. package/dist/chunks/GapCursorPlugin-2iR6506y.mjs +2 -0
  34. package/dist/chunks/{GapCursorPlugin-DAxVzXRs.mjs.map → GapCursorPlugin-2iR6506y.mjs.map} +1 -1
  35. package/dist/chunks/{HardBreakPlugin-DlbSlrdq.mjs → HardBreakPlugin-vniSvTgq.mjs} +2 -2
  36. package/dist/chunks/{HardBreakPlugin-DlbSlrdq.mjs.map → HardBreakPlugin-vniSvTgq.mjs.map} +1 -1
  37. package/dist/chunks/{HeadingPlugin-uMAjPOk5.mjs → HeadingPlugin-DUKsLuMd.mjs} +2 -2
  38. package/dist/chunks/{HeadingPlugin-uMAjPOk5.mjs.map → HeadingPlugin-DUKsLuMd.mjs.map} +1 -1
  39. package/dist/chunks/{HighlightPlugin-Bj7FPkIQ.mjs → HighlightPlugin-DRTAE1N5.mjs} +2 -2
  40. package/dist/chunks/{HighlightPlugin-Bj7FPkIQ.mjs.map → HighlightPlugin-DRTAE1N5.mjs.map} +1 -1
  41. package/dist/chunks/HorizontalRulePlugin-B9OvwrKB.mjs +2 -0
  42. package/dist/chunks/{HorizontalRulePlugin-DUVmTQpX.mjs.map → HorizontalRulePlugin-B9OvwrKB.mjs.map} +1 -1
  43. package/dist/chunks/{ImagePlugin-FToCOjd5.mjs → ImagePlugin-CwxTRr6d.mjs} +2 -2
  44. package/dist/chunks/{ImagePlugin-FToCOjd5.mjs.map → ImagePlugin-CwxTRr6d.mjs.map} +1 -1
  45. package/dist/chunks/{InlineCodePlugin-pISIoGQE.mjs → InlineCodePlugin-uxgMUX_E.mjs} +2 -2
  46. package/dist/chunks/{InlineCodePlugin-pISIoGQE.mjs.map → InlineCodePlugin-uxgMUX_E.mjs.map} +1 -1
  47. package/dist/chunks/{LinkPlugin-Ct5Z180S.mjs → LinkPlugin-CvWHbSkb.mjs} +2 -2
  48. package/dist/chunks/{LinkPlugin-Ct5Z180S.mjs.map → LinkPlugin-CvWHbSkb.mjs.map} +1 -1
  49. package/dist/chunks/{ListPlugin-DAY5ezNs.mjs → ListPlugin-BchSFWVn.mjs} +2 -2
  50. package/dist/chunks/{ListPlugin-DAY5ezNs.mjs.map → ListPlugin-BchSFWVn.mjs.map} +1 -1
  51. package/dist/chunks/{MarkdownHTMLRegistry-CKEx7LkR.mjs → MarkdownHTMLRegistry-Q7l0d6Ma.mjs} +2 -2
  52. package/dist/chunks/{MarkdownHTMLRegistry-CKEx7LkR.mjs.map → MarkdownHTMLRegistry-Q7l0d6Ma.mjs.map} +1 -1
  53. package/dist/chunks/{MarkdownParser-CWt3M6jR.mjs → MarkdownParser-Dp62mfUq.mjs} +2 -2
  54. package/dist/chunks/{MarkdownParser-CWt3M6jR.mjs.map → MarkdownParser-Dp62mfUq.mjs.map} +1 -1
  55. package/dist/chunks/{MarkdownSerializer-J-i28out.mjs → MarkdownSerializer-DBELFAeo.mjs} +2 -2
  56. package/dist/chunks/{MarkdownSerializer-J-i28out.mjs.map → MarkdownSerializer-DBELFAeo.mjs.map} +1 -1
  57. package/dist/chunks/MathFont-BS8IwYh2.mjs +2 -0
  58. package/dist/chunks/MathFont-BS8IwYh2.mjs.map +1 -0
  59. package/dist/chunks/NodeSelectionCommands-WH5snxr_.mjs +2 -0
  60. package/dist/chunks/{NodeSelectionCommands-1PjwUDTJ.mjs.map → NodeSelectionCommands-WH5snxr_.mjs.map} +1 -1
  61. package/dist/chunks/PluginHelpers-KDuTlmXm.mjs +2 -0
  62. package/dist/chunks/{PluginHelpers-Dx_0hfDe.mjs.map → PluginHelpers-KDuTlmXm.mjs.map} +1 -1
  63. package/dist/chunks/{PopupManager-CT-fMZJn.mjs → PopupManager-Cj86uDEB.mjs} +2 -2
  64. package/dist/chunks/{PopupManager-CT-fMZJn.mjs.map → PopupManager-Cj86uDEB.mjs.map} +1 -1
  65. package/dist/chunks/PrintPlugin-D2javl_d.mjs +2 -0
  66. package/dist/chunks/{PrintPlugin-7zz9mhhU.mjs.map → PrintPlugin-D2javl_d.mjs.map} +1 -1
  67. package/dist/chunks/SimpleMark-gTQaSJcO.mjs +2 -0
  68. package/dist/chunks/{SimpleMark-7CQcA4RK.mjs.map → SimpleMark-gTQaSJcO.mjs.map} +1 -1
  69. package/dist/chunks/SmartPastePlugin-BvJQ-fOz.mjs +2 -0
  70. package/dist/chunks/SmartPastePlugin-BvJQ-fOz.mjs.map +1 -0
  71. package/dist/chunks/StarterFonts-BDQPg-cu.mjs +2 -0
  72. package/dist/chunks/StarterFonts-BDQPg-cu.mjs.map +1 -0
  73. package/dist/chunks/{StrikethroughPlugin-C2oWvGc3.mjs → StrikethroughPlugin-BdrG1TTY.mjs} +2 -2
  74. package/dist/chunks/{StrikethroughPlugin-C2oWvGc3.mjs.map → StrikethroughPlugin-BdrG1TTY.mjs.map} +1 -1
  75. package/dist/chunks/{SuperSubPlugin-D1xaKrSu.mjs → SuperSubPlugin-DTZB0Y3D.mjs} +2 -2
  76. package/dist/chunks/{SuperSubPlugin-D1xaKrSu.mjs.map → SuperSubPlugin-DTZB0Y3D.mjs.map} +1 -1
  77. package/dist/chunks/{TablePlugin-PJe3zwr-.mjs → TablePlugin-CPvg9YZS.mjs} +2 -2
  78. package/dist/chunks/{TablePlugin-PJe3zwr-.mjs.map → TablePlugin-CPvg9YZS.mjs.map} +1 -1
  79. package/dist/chunks/{TextColorPlugin-CTd9tfeG.mjs → TextColorPlugin-Ckg3KWvb.mjs} +2 -2
  80. package/dist/chunks/{TextColorPlugin-CTd9tfeG.mjs.map → TextColorPlugin-Ckg3KWvb.mjs.map} +1 -1
  81. package/dist/chunks/{TextDirectionAutoPlugin-CPnKVVuI.mjs → TextDirectionAutoPlugin-DRGbgTlx.mjs} +2 -2
  82. package/dist/chunks/{TextDirectionAutoPlugin-CPnKVVuI.mjs.map → TextDirectionAutoPlugin-DRGbgTlx.mjs.map} +1 -1
  83. package/dist/chunks/TextDirectionPlugin-BCeYyJHo.mjs +2 -0
  84. package/dist/chunks/{TextDirectionPlugin-Bns_03vL.mjs.map → TextDirectionPlugin-BCeYyJHo.mjs.map} +1 -1
  85. package/dist/chunks/TextDirectionService-OFOU6r_s.mjs +2 -0
  86. package/dist/chunks/{TextDirectionService-BcX07mw2.mjs.map → TextDirectionService-OFOU6r_s.mjs.map} +1 -1
  87. package/dist/chunks/TextFormattingPlugin-BhRxSC8q.mjs +2 -0
  88. package/dist/chunks/{TextFormattingPlugin-DBVlePqj.mjs.map → TextFormattingPlugin-BhRxSC8q.mjs.map} +1 -1
  89. package/dist/chunks/ThemeEngine-BUVo_zaT.mjs +3 -0
  90. package/dist/chunks/ThemeEngine-BUVo_zaT.mjs.map +1 -0
  91. package/dist/chunks/ToolbarPlugin-dmTj1jIz.mjs +2 -0
  92. package/dist/chunks/{ToolbarPlugin-DtfGTO_V.mjs.map → ToolbarPlugin-dmTj1jIz.mjs.map} +1 -1
  93. package/dist/chunks/{VideoPlugin-BrR8g6Rz.mjs → VideoPlugin-BugkI7-m.mjs} +2 -2
  94. package/dist/chunks/{VideoPlugin-BrR8g6Rz.mjs.map → VideoPlugin-BugkI7-m.mjs.map} +1 -1
  95. package/dist/chunks/XmlSupport-DIXH5on9.mjs +2 -0
  96. package/dist/chunks/XmlSupport-DIXH5on9.mjs.map +1 -0
  97. package/dist/chunks/full-JM0-SwWy.mjs +2 -0
  98. package/dist/chunks/{full-DSWM4cKQ.mjs.map → full-JM0-SwWy.mjs.map} +1 -1
  99. package/dist/chunks/minimal-DSlR2A27.mjs +2 -0
  100. package/dist/chunks/{minimal-CFkkPXef.mjs.map → minimal-DSlR2A27.mjs.map} +1 -1
  101. package/dist/chunks/register-BjsdJ3Aq.mjs +2 -0
  102. package/dist/chunks/register-BjsdJ3Aq.mjs.map +1 -0
  103. package/dist/chunks/src-5GKFQ2mQ.mjs +2 -0
  104. package/dist/chunks/src-5GKFQ2mQ.mjs.map +1 -0
  105. package/dist/chunks/xml-BsV44TrJ.mjs +2 -0
  106. package/dist/chunks/xml-BsV44TrJ.mjs.map +1 -0
  107. package/dist/editor/NotectlEditor.d.ts.map +1 -1
  108. package/dist/fonts/math.d.ts +3 -0
  109. package/dist/fonts/math.d.ts.map +1 -0
  110. package/dist/fonts/math.mjs +1 -0
  111. package/dist/fonts/starter.d.ts +3 -0
  112. package/dist/fonts/starter.d.ts.map +1 -0
  113. package/dist/fonts/starter.mjs +1 -0
  114. package/dist/fonts.d.ts +4 -4
  115. package/dist/fonts.mjs +1 -1
  116. package/dist/full.d.ts +1 -1
  117. package/dist/full.mjs +1 -1
  118. package/dist/index.d.ts +2 -1
  119. package/dist/index.d.ts.map +1 -1
  120. package/dist/markdown.mjs +1 -1
  121. package/dist/notectl-core.mjs +1 -1
  122. package/dist/notectl-core.umd.js +1 -1
  123. package/dist/notectl-core.umd.js.map +1 -1
  124. package/dist/plugins/alignment.mjs +1 -1
  125. package/dist/plugins/bidi-isolation.mjs +1 -1
  126. package/dist/plugins/blockquote.mjs +1 -1
  127. package/dist/plugins/caret-navigation.mjs +1 -1
  128. package/dist/plugins/code-block/CodeBlockHighlighting.d.ts.map +1 -1
  129. package/dist/plugins/code-block.mjs +1 -1
  130. package/dist/plugins/font-size.mjs +1 -1
  131. package/dist/plugins/font.mjs +1 -1
  132. package/dist/plugins/formula/FormulaTypes.d.ts +1 -1
  133. package/dist/plugins/formula.mjs +1 -1
  134. package/dist/plugins/gap-cursor.mjs +1 -1
  135. package/dist/plugins/hard-break.mjs +1 -1
  136. package/dist/plugins/heading.mjs +1 -1
  137. package/dist/plugins/highlight.mjs +1 -1
  138. package/dist/plugins/horizontal-rule.mjs +1 -1
  139. package/dist/plugins/image.mjs +1 -1
  140. package/dist/plugins/inline-code.mjs +1 -1
  141. package/dist/plugins/language.mjs +1 -1
  142. package/dist/plugins/link.mjs +1 -1
  143. package/dist/plugins/list.mjs +1 -1
  144. package/dist/plugins/print.mjs +1 -1
  145. package/dist/plugins/shared.mjs +1 -1
  146. package/dist/plugins/smart-paste/SmartPastePlugin.d.ts.map +1 -1
  147. package/dist/plugins/smart-paste.mjs +1 -1
  148. package/dist/plugins/strikethrough.mjs +1 -1
  149. package/dist/plugins/super-sub.mjs +1 -1
  150. package/dist/plugins/table.mjs +1 -1
  151. package/dist/plugins/text-color.mjs +1 -1
  152. package/dist/plugins/text-direction-auto.mjs +1 -1
  153. package/dist/plugins/text-direction.mjs +1 -1
  154. package/dist/plugins/text-formatting.mjs +1 -1
  155. package/dist/plugins/toolbar.mjs +1 -1
  156. package/dist/plugins/video.mjs +1 -1
  157. package/dist/presets/full.d.ts +1 -1
  158. package/dist/presets/full.mjs +1 -1
  159. package/dist/presets/minimal.d.ts +1 -1
  160. package/dist/presets/minimal.mjs +1 -1
  161. package/dist/presets.d.ts +1 -1
  162. package/dist/presets.mjs +1 -1
  163. package/dist/register.d.ts +3 -0
  164. package/dist/register.d.ts.map +1 -0
  165. package/dist/register.mjs +1 -0
  166. package/package.json +24 -223
  167. package/dist/chunks/CaretNavigationPlugin-CNsT0eb4.mjs +0 -2
  168. package/dist/chunks/CaretNavigationPlugin-CNsT0eb4.mjs.map +0 -1
  169. package/dist/chunks/CodeBlockPlugin-C1hrdbSZ.mjs +0 -2
  170. package/dist/chunks/ColorPickerPopup-DiA68Pzz.mjs +0 -2
  171. package/dist/chunks/Commands-1dFFldi7.mjs +0 -2
  172. package/dist/chunks/FormulaPlugin-By1befrR.mjs.map +0 -1
  173. package/dist/chunks/GapCursorNavigation-BuXngVu-.mjs +0 -2
  174. package/dist/chunks/GapCursorPlugin-DAxVzXRs.mjs +0 -2
  175. package/dist/chunks/HorizontalRulePlugin-DUVmTQpX.mjs +0 -2
  176. package/dist/chunks/NodeSelectionCommands-1PjwUDTJ.mjs +0 -2
  177. package/dist/chunks/PluginHelpers-Dx_0hfDe.mjs +0 -2
  178. package/dist/chunks/PrintPlugin-7zz9mhhU.mjs +0 -2
  179. package/dist/chunks/PrintTypes-CxU69qu3.mjs +0 -3
  180. package/dist/chunks/PrintTypes-CxU69qu3.mjs.map +0 -1
  181. package/dist/chunks/SimpleMark-7CQcA4RK.mjs +0 -2
  182. package/dist/chunks/SmartPastePlugin-CYa_nD9v.mjs +0 -2
  183. package/dist/chunks/SmartPastePlugin-CYa_nD9v.mjs.map +0 -1
  184. package/dist/chunks/TextDirectionPlugin-Bns_03vL.mjs +0 -2
  185. package/dist/chunks/TextDirectionService-BcX07mw2.mjs +0 -2
  186. package/dist/chunks/TextFormattingPlugin-DBVlePqj.mjs +0 -2
  187. package/dist/chunks/ToolbarPlugin-DtfGTO_V.mjs +0 -2
  188. package/dist/chunks/XmlDetector-D7TQpw-e.mjs +0 -2
  189. package/dist/chunks/XmlDetector-D7TQpw-e.mjs.map +0 -1
  190. package/dist/chunks/XmlSupport-BYiRwlkK.mjs +0 -2
  191. package/dist/chunks/XmlSupport-BYiRwlkK.mjs.map +0 -1
  192. package/dist/chunks/fonts-DQC6Uj4r.mjs +0 -2
  193. package/dist/chunks/fonts-DQC6Uj4r.mjs.map +0 -1
  194. package/dist/chunks/full-DSWM4cKQ.mjs +0 -2
  195. package/dist/chunks/minimal-CFkkPXef.mjs +0 -2
  196. package/dist/chunks/src-DiAOfuOT.mjs +0 -2
  197. package/dist/chunks/src-DiAOfuOT.mjs.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ListPlugin-DAY5ezNs.mjs","names":[],"sources":["../../src/editor/styles/list.ts","../../src/plugins/list/ListAttrsFactory.ts","../../src/plugins/list/ListItemContext.ts","../../src/plugins/list/ListCommands.ts","../../src/plugins/list/ListDefinitions.ts","../../src/plugins/list/ListInputRules.ts","../../src/plugins/list/ListKeyboardHandlers.ts","../../src/plugins/list/ListLocale.ts","../../src/plugins/list/ListMarker.ts","../../src/plugins/list/ListToolbarItems.ts","../../src/plugins/list/ListPlugin.ts"],"sourcesContent":["/** Width of the list marker / checkbox area in pixels. */\nexport const LIST_MARKER_WIDTH = 24;\n\n/** List styles — bullet, ordered, checklist items. */\nexport const LIST_CSS = `\n/* List Wrappers — suppress native markers, we use ::before pseudo-elements */\n.notectl-list {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n/* Ordered List — each <ol> wrapper resets the counter */\n.notectl-list--ordered {\n\tcounter-reset: notectl-ordered;\n}\n\n/* List Items */\n.notectl-list-item {\n\tmargin: 0;\n\tpadding: 2px 0;\n\tpadding-inline-start: ${LIST_MARKER_WIDTH}px;\n\tmin-height: 1.6em;\n\tposition: relative;\n}\n\n.notectl-list-item::before {\n\tposition: absolute;\n\tinset-inline-start: 0;\n\tdisplay: inline-block;\n\twidth: ${LIST_MARKER_WIDTH}px;\n\ttext-align: center;\n\t-webkit-user-select: none;\n\tuser-select: none;\n\tpointer-events: none;\n}\n\n/* Container items (#194): block children inherit the item's start padding.\n Trim the first/last child paragraph padding so the first text line sits on\n the marker's line and the item keeps the leaf item's vertical rhythm. */\n.notectl-list-item > p:first-of-type {\n\tpadding-top: 0;\n}\n\n.notectl-list-item > p:last-of-type {\n\tpadding-bottom: 0;\n}\n\n/* Bullet List */\n.notectl-list-item--bullet::before {\n\tcontent: '\\\\2022';\n\tcolor: var(--notectl-fg);\n}\n\n/* Ordered List — counter increment per item */\n.notectl-list-item--ordered {\n\tcounter-increment: notectl-ordered;\n}\n\n.notectl-list-item--ordered::before {\n\tcontent: counter(notectl-ordered) '.';\n\tcolor: var(--notectl-fg);\n\tfont-size: 14px;\n}\n\n/* Checklist — the marker is a real role=\"checkbox\" element (see ListMarker.ts)\n positioned over the reserved marker zone. inline-block keeps the parent's\n line-through (on checked items) from striking the glyph. */\n.notectl-checklist-marker {\n\tposition: absolute;\n\tinset-inline-start: 0;\n\tdisplay: inline-block;\n\twidth: ${LIST_MARKER_WIDTH}px;\n\ttext-align: center;\n\tfont-size: 16px;\n\tcolor: var(--notectl-fg-muted);\n\tcursor: pointer;\n\ttext-decoration: none;\n\t-webkit-user-select: none;\n\tuser-select: none;\n}\n\n.notectl-checklist-marker::before {\n\tcontent: '\\\\2610';\n}\n\n.notectl-list-item--checklist[data-checked=\"true\"] .notectl-checklist-marker {\n\tcolor: var(--notectl-success);\n}\n\n.notectl-list-item--checklist[data-checked=\"true\"] .notectl-checklist-marker::before {\n\tcontent: '\\\\2611';\n}\n\n.notectl-list-item--checklist[data-checked=\"true\"] {\n\tcolor: var(--notectl-fg-muted);\n\ttext-decoration: line-through;\n}\n`;\n","/**\n * Factory for building list item block attributes.\n * Centralizes attribute construction to avoid repetitive inline object literals.\n */\n\nimport type { BlockAttrs } from '../../model/Document.js';\nimport type { ListType } from './ListPlugin.js';\n\n/** Builds a `BlockAttrs` object for a list_item block. */\nexport function buildListItemAttrs(\n\tlistType: ListType,\n\tindent: number,\n\tchecked?: boolean,\n): BlockAttrs {\n\tif (listType === 'checklist') {\n\t\treturn { listType, indent, checked: checked ?? false };\n\t}\n\treturn { listType, indent };\n}\n","/**\n * Shared resolution helpers for container list items (#194).\n *\n * With `list_item` a hybrid leaf/container block, the caret may sit inside a\n * block child of an item. Commands and keyboard handlers resolve the owning\n * item through the ancestor chain and address structural edits through the\n * item's location (parent path + child index), mirroring the blockquote\n * container conventions.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { getBlockChildren } from '../../model/Document.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { TransactionBuilder } from '../../state/TransactionBuilder.js';\n\n/** A list item's structural address: its parent path and child index. */\nexport interface ListItemLocation {\n\treadonly item: BlockNode;\n\t/** Path from the document root to the item's parent ([] = root). */\n\treadonly parentPath: readonly BlockId[];\n\t/** The item's index among its parent's block children. */\n\treadonly index: number;\n}\n\n/**\n * Resolves the list item owning a block: the block itself when it is a\n * `list_item`, otherwise its nearest `list_item` ancestor.\n */\nexport function resolveListItem(state: EditorState, id: BlockId): BlockNode | undefined {\n\tconst block: BlockNode | undefined = state.getBlock(id);\n\tif (block?.type === 'list_item') return block;\n\tconst path: readonly BlockId[] | undefined = state.getNodePath(id);\n\tif (!path) return undefined;\n\tfor (let i = path.length - 2; i >= 0; i--) {\n\t\tconst ancestorId: BlockId | undefined = path[i];\n\t\tconst ancestor: BlockNode | undefined = ancestorId ? state.getBlock(ancestorId) : undefined;\n\t\tif (ancestor?.type === 'list_item') return ancestor;\n\t}\n\treturn undefined;\n}\n\n/** Locates a list item's structural address, or undefined if it is not found. */\nexport function locateListItem(state: EditorState, itemId: BlockId): ListItemLocation | undefined {\n\tconst item: BlockNode | undefined = state.getBlock(itemId);\n\tif (!item || item.type !== 'list_item') return undefined;\n\tconst path: readonly BlockId[] | undefined = state.getNodePath(itemId);\n\tif (!path) return undefined;\n\n\tconst parentPath: readonly BlockId[] = path.slice(0, -1);\n\tconst parentId: BlockId | undefined = parentPath[parentPath.length - 1];\n\tconst siblings: readonly BlockNode[] = parentId\n\t\t? getBlockChildren(state.getBlock(parentId) as BlockNode)\n\t\t: state.doc.children;\n\tconst index: number = siblings.findIndex((sibling) => sibling.id === itemId);\n\tif (index < 0) return undefined;\n\treturn { item, parentPath, index };\n}\n\n/**\n * Replaces a container list item with its block children in place. The\n * children keep their IDs, so a selection inside them survives the lift.\n * Leaf items must not be dissolved (their inline content is not a block);\n * convert those via `setBlockType` instead.\n */\nexport function dissolveListItem(builder: TransactionBuilder, location: ListItemLocation): void {\n\tbuilder.removeNode(location.parentPath, location.index);\n\tconst children: readonly BlockNode[] = getBlockChildren(location.item);\n\tchildren.forEach((child, offset) => {\n\t\tbuilder.insertNode(location.parentPath, location.index + offset, child);\n\t});\n}\n","/**\n * Command registration and implementations for list block types.\n * Handles toggle between list types and paragraph, indent/outdent,\n * and checklist toggle.\n */\n\nimport { forEachBlockIdInRange } from '../../commands/RangeIterator.js';\nimport { isNodeOfType } from '../../model/AttrRegistry.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport { isLeafBlock } from '../../model/Document.js';\nimport { isTextSelection, selectionRange } from '../../model/Selection.js';\nimport { type BlockId, nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { buildListItemAttrs } from './ListAttrsFactory.js';\nimport type { ListTypeDefinition } from './ListDefinitions.js';\nimport { dissolveListItem, locateListItem, resolveListItem } from './ListItemContext.js';\nimport type { ListLocale } from './ListLocale.js';\nimport type { ListConfig, ListType } from './ListPlugin.js';\n\n/** Registers all list commands (toggleList:*, indent, outdent, toggleChecklistItem). */\nexport function registerListCommands(\n\tcontext: PluginContext,\n\tconfig: ListConfig,\n\tenabledTypes: readonly ListTypeDefinition[],\n\tlocale: ListLocale,\n): void {\n\tfor (const def of enabledTypes) {\n\t\tcontext.registerCommand(`toggleList:${def.type}`, () => {\n\t\t\treturn toggleList(context, def.type);\n\t\t});\n\t}\n\n\tcontext.registerCommand('indentListItem', () => changeIndent(context, 1, config.maxIndent));\n\n\tcontext.registerCommand('outdentListItem', () => changeIndent(context, -1, config.maxIndent));\n\n\tif (config.types.includes('checklist')) {\n\t\tconst toggleChecklistItem = (): boolean =>\n\t\t\ttoggleChecked(context, { interactiveCheckboxes: config.interactiveCheckboxes, locale });\n\n\t\tcontext.registerCommand('toggleChecklistItem', toggleChecklistItem, {\n\t\t\treadonlyAllowed: true,\n\t\t});\n\n\t\t// Mod-Enter gives keyboard-only users a way to toggle a checklist item\n\t\t// (WCAG 2.1.1). The handler declines on non-checklist blocks, so it falls\n\t\t// through to other Mod-Enter bindings (e.g. code-block insert-after).\n\t\t// Registered at navigation priority so it stays reachable in read-only mode\n\t\t// when interactiveCheckboxes is enabled, matching the mouse handler.\n\t\tcontext.registerKeymap({ 'Mod-Enter': toggleChecklistItem }, { priority: 'navigation' });\n\t}\n\n\tcontext.registerKeymap({\n\t\tTab: () => changeIndent(context, 1, config.maxIndent),\n\t\t'Shift-Tab': () => changeIndent(context, -1, config.maxIndent),\n\t});\n}\n\n// --- Command Implementations ---\n\nfunction toggleList(context: PluginContext, listType: ListType): boolean {\n\tconst state: EditorState = context.getState();\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return false;\n\n\tif (sel.anchor.blockId !== sel.head.blockId) {\n\t\treturn toggleListRange(context, state, listType);\n\t}\n\treturn toggleListSingleBlock(context, state, listType);\n}\n\nfunction toggleListSingleBlock(\n\tcontext: PluginContext,\n\tstate: EditorState,\n\tlistType: ListType,\n): boolean {\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return false;\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return false;\n\n\t// The caret may sit inside a block child of a container item (#194):\n\t// toggling always targets the owning item, never the child.\n\tconst item: BlockNode | undefined = resolveListItem(state, sel.anchor.blockId);\n\tconst target: BlockNode = item ?? block;\n\n\tif (item && item.attrs?.listType === listType) {\n\t\tconst builder = state.transaction('command');\n\t\tif (isLeafBlock(item)) {\n\t\t\tbuilder.setBlockType(item.id, nodeType('paragraph'));\n\t\t} else {\n\t\t\t// A container item cannot become a paragraph (its children are\n\t\t\t// blocks) — dissolve it into those children instead.\n\t\t\tconst location = locateListItem(state, item.id);\n\t\t\tif (!location) return false;\n\t\t\tdissolveListItem(builder, location);\n\t\t}\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\tconst existingIndent: number = isNodeOfType(target, 'list_item') ? target.attrs.indent : 0;\n\tconst attrs = buildListItemAttrs(listType, existingIndent);\n\n\tconst tr = state\n\t\t.transaction('command')\n\t\t.setBlockType(target.id, nodeType('list_item'), attrs)\n\t\t.setSelection(sel)\n\t\t.build();\n\tcontext.dispatch(tr);\n\treturn true;\n}\n\nfunction toggleListRange(context: PluginContext, state: EditorState, listType: ListType): boolean {\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return false;\n\n\tconst range = selectionRange(sel, state.getBlockOrder());\n\tconst toggleOff: boolean = allBlocksMatchListType(state, range, listType);\n\tconst builder = state.transaction('command');\n\n\t// Children of a container item resolve to their owning item (#194), so a\n\t// range over its paragraphs toggles the item once, not each child.\n\tconst targets: BlockNode[] = collectToggleTargets(state, range);\n\n\t// Dissolving replaces one node with several, shifting later sibling\n\t// indices — process targets back-to-front so earlier addresses stay valid.\n\tfor (let i = targets.length - 1; i >= 0; i--) {\n\t\tconst target: BlockNode | undefined = targets[i];\n\t\tif (!target) continue;\n\n\t\tif (toggleOff) {\n\t\t\tif (isLeafBlock(target)) {\n\t\t\t\tbuilder.setBlockType(target.id, nodeType('paragraph'));\n\t\t\t} else {\n\t\t\t\tconst location = locateListItem(state, target.id);\n\t\t\t\tif (location) dissolveListItem(builder, location);\n\t\t\t}\n\t\t} else {\n\t\t\tconst existingIndent: number = isNodeOfType(target, 'list_item') ? target.attrs.indent : 0;\n\t\t\tconst existingChecked: boolean =\n\t\t\t\tisNodeOfType(target, 'list_item') &&\n\t\t\t\ttarget.attrs.listType === 'checklist' &&\n\t\t\t\ttarget.attrs.checked;\n\t\t\tbuilder.setBlockType(\n\t\t\t\ttarget.id,\n\t\t\t\tnodeType('list_item'),\n\t\t\t\tbuildListItemAttrs(listType, existingIndent, existingChecked),\n\t\t\t);\n\t\t}\n\t}\n\n\tbuilder.setSelection(sel);\n\tcontext.dispatch(builder.build());\n\treturn true;\n}\n\n/** Collects unique toggle targets: each leaf block or its owning list item. */\nfunction collectToggleTargets(\n\tstate: EditorState,\n\trange: ReturnType<typeof selectionRange>,\n): BlockNode[] {\n\tconst targets: BlockNode[] = [];\n\tconst seen = new Set<BlockId>();\n\tforEachBlockIdInRange(state, range, (bid: BlockId) => {\n\t\tconst block = state.getBlock(bid);\n\t\tif (!block) return;\n\t\tconst target: BlockNode = resolveListItem(state, bid) ?? block;\n\t\tif (seen.has(target.id)) return;\n\t\tseen.add(target.id);\n\t\ttargets.push(target);\n\t});\n\treturn targets;\n}\n\n// --- Indent / Outdent ---\n\nfunction changeIndent(context: PluginContext, delta: 1 | -1, maxIndent: number): boolean {\n\tconst state: EditorState = context.getState();\n\tif (!isTextSelection(state.selection)) return false;\n\n\tif (state.selection.anchor.blockId !== state.selection.head.blockId) {\n\t\treturn changeIndentRange(context, state, delta, maxIndent);\n\t}\n\n\tconst sel = state.selection;\n\tconst block = resolveListItem(state, sel.anchor.blockId);\n\tif (!block || !isNodeOfType(block, 'list_item')) return false;\n\n\tconst newIndent: number = block.attrs.indent + delta;\n\tif (newIndent < 0 || newIndent > maxIndent) return false;\n\n\tconst attrs = buildListItemAttrs(block.attrs.listType, newIndent, block.attrs.checked);\n\tconst tr = state\n\t\t.transaction('command')\n\t\t.setBlockType(block.id, nodeType('list_item'), attrs)\n\t\t.setSelection(sel)\n\t\t.build();\n\tcontext.dispatch(tr);\n\treturn true;\n}\n\nfunction changeIndentRange(\n\tcontext: PluginContext,\n\tstate: EditorState,\n\tdelta: 1 | -1,\n\tmaxIndent: number,\n): boolean {\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return false;\n\n\tconst range = selectionRange(sel, state.getBlockOrder());\n\tconst builder = state.transaction('command');\n\tlet changed = false;\n\tconst seen = new Set<BlockId>();\n\n\tforEachBlockIdInRange(state, range, (bid: BlockId) => {\n\t\tconst block = resolveListItem(state, bid);\n\t\tif (!block || !isNodeOfType(block, 'list_item')) return;\n\t\tif (seen.has(block.id)) return;\n\t\tseen.add(block.id);\n\n\t\tconst newIndent: number = block.attrs.indent + delta;\n\t\tif (newIndent < 0 || newIndent > maxIndent) return;\n\n\t\tbuilder.setBlockType(\n\t\t\tblock.id,\n\t\t\tnodeType('list_item'),\n\t\t\tbuildListItemAttrs(block.attrs.listType, newIndent, block.attrs.checked),\n\t\t);\n\t\tchanged = true;\n\t});\n\n\tif (!changed) return false;\n\n\tbuilder.setSelection(sel);\n\tcontext.dispatch(builder.build());\n\treturn true;\n}\n\n// --- Checklist Toggle ---\n\n/** Options for {@link toggleChecked}. */\nexport interface ToggleCheckedOptions {\n\t/** When true, the toggle is allowed even in read-only mode. */\n\treadonly interactiveCheckboxes?: boolean;\n\t/** Specific checklist item to toggle. Defaults to the selection's block. */\n\treadonly targetId?: BlockId;\n\t/** Locale used for the screen-reader announcement of the new state. */\n\treadonly locale: ListLocale;\n}\n\n/**\n * Toggles the checked state of a checklist item and announces the new state to\n * screen readers. Exported for use in the checkbox click handler.\n */\nexport function toggleChecked(context: PluginContext, options: ToggleCheckedOptions): boolean {\n\tconst { interactiveCheckboxes, targetId, locale } = options;\n\tif (context.isReadOnly() && !interactiveCheckboxes) return false;\n\n\tconst state: EditorState = context.getState();\n\tconst bid: BlockId | null =\n\t\ttargetId ?? (!isTextSelection(state.selection) ? null : state.selection.anchor.blockId);\n\tif (!bid) return false;\n\n\tconst block = resolveListItem(state, bid);\n\tif (!block || !isNodeOfType(block, 'list_item') || block.attrs.listType !== 'checklist') {\n\t\treturn false;\n\t}\n\n\tconst nextChecked: boolean = !block.attrs.checked;\n\tconst attrs = buildListItemAttrs(block.attrs.listType, block.attrs.indent, nextChecked);\n\n\tconst tr = state\n\t\t.transaction('command')\n\t\t.setBlockType(block.id, nodeType('list_item'), attrs)\n\t\t.setSelection(state.selection)\n\t\t.build();\n\tcontext.dispatch(tr);\n\n\t// The marker is not focused while editing, so the aria-checked change alone is\n\t// not spoken — announce the new state explicitly (WCAG 4.1.3).\n\tcontext.announce(nextChecked ? locale.checkedAnnouncement : locale.uncheckedAnnouncement);\n\treturn true;\n}\n\n// --- Helpers ---\n\n/**\n * Checks whether all blocks in a range belong to list items of the given type\n * (children of container items resolve to their owning item, #194). Exported\n * for toolbar active-state detection.\n */\nexport function allBlocksMatchListType(\n\tstate: EditorState,\n\trange: ReturnType<typeof selectionRange>,\n\tlistType: ListType,\n): boolean {\n\tlet allMatch = true;\n\tforEachBlockIdInRange(state, range, (bid: BlockId) => {\n\t\tconst block = resolveListItem(state, bid);\n\t\tif (!block || block.type !== 'list_item' || block.attrs?.listType !== listType) {\n\t\t\tallMatch = false;\n\t\t}\n\t});\n\treturn allMatch;\n}\n","/**\n * List type metadata: icons, patterns, and type definitions.\n * Pure data constants shared across list plugin modules.\n */\n\nimport type { ListType } from './ListPlugin.js';\n\n// --- List Type Metadata ---\n\nexport interface ListTypeDefinition {\n\treadonly type: ListType;\n\treadonly icon: string;\n\treadonly inputPattern: RegExp;\n\treadonly inputPrefix: string;\n}\n\nconst BULLET_LIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z\"/></svg>';\nconst NUMBERED_LIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z\"/></svg>';\nconst CHECKLIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M22 7h-9v2h9V7zm0 8h-9v2h9v-2zM5.54 11L2 7.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 11zm0 8L2 15.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 19z\"/></svg>';\n\nexport const LIST_TYPE_DEFINITIONS: readonly ListTypeDefinition[] = [\n\t{\n\t\ttype: 'bullet',\n\t\ticon: BULLET_LIST_ICON,\n\t\tinputPattern: /^[-*] $/,\n\t\tinputPrefix: '- ',\n\t},\n\t{\n\t\ttype: 'ordered',\n\t\ticon: NUMBERED_LIST_ICON,\n\t\tinputPattern: /^\\d+\\. $/,\n\t\tinputPrefix: '1. ',\n\t},\n\t{\n\t\ttype: 'checklist',\n\t\ticon: CHECKLIST_ICON,\n\t\tinputPattern: /^\\[[ x]] $/,\n\t\tinputPrefix: '[ ] ',\n\t},\n];\n","/**\n * Input rule registration for list block types.\n * Converts `- `, `* `, `1. `, `[ ] `, `[x] ` at the start of a paragraph into list items.\n */\n\nimport { createCollapsedSelection, isCollapsed, isTextSelection } from '../../model/Selection.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { buildListItemAttrs } from './ListAttrsFactory.js';\nimport type { ListTypeDefinition } from './ListDefinitions.js';\n\n/** Registers markdown-style input rules for configured list types. */\nexport function registerListInputRules(\n\tcontext: PluginContext,\n\tenabledTypes: readonly ListTypeDefinition[],\n): void {\n\tfor (const def of enabledTypes) {\n\t\tcontext.registerInputRule({\n\t\t\tpattern: def.inputPattern,\n\t\t\thandler: (state, match, start, _end) => {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\tif (!isTextSelection(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\t// Inside a container list item (#194) the rule must not fire: it\n\t\t\t\t// would nest a list_item into a list_item, which the schema forbids.\n\t\t\t\tconst parent = state.getParent(sel.anchor.blockId);\n\t\t\t\tif (parent?.type === 'list_item') return null;\n\n\t\t\t\tconst matchStr = match[0] ?? '';\n\t\t\t\tconst matchLen = matchStr.length;\n\t\t\t\tconst attrs = buildListItemAttrs(def.type, 0, matchStr.includes('[x]'));\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, start, start + matchLen)\n\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('list_item'), attrs)\n\t\t\t\t\t.setSelection(createCollapsedSelection(sel.anchor.blockId, 0))\n\t\t\t\t\t.build();\n\t\t\t},\n\t\t});\n\t}\n}\n","/**\n * Keyboard handlers for list block types.\n *\n * Leaf items: Enter splits into a new item (or exits an empty item),\n * Backspace at the start converts back to a paragraph.\n *\n * Container items (#194): the caret sits inside a block child. Enter on an\n * empty trailing child exits into a new sibling item (Enter-Enter continues\n * the list); Backspace at the start of the first child dissolves the item\n * into its children — both mirroring the blockquote container conventions.\n * Everything else falls through to the default split/merge behavior.\n */\n\nimport { isEmptyParagraph } from '../../commands/BlockInsertion.js';\nimport { isNodeOfType } from '../../model/AttrRegistry.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport { generateBlockId, getBlockChildren, getBlockText } from '../../model/Document.js';\nimport { createBlockNode, createTextNode } from '../../model/Document.js';\nimport { createCollapsedSelection, isCollapsed, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { buildListItemAttrs } from './ListAttrsFactory.js';\nimport { type ListItemLocation, dissolveListItem, locateListItem } from './ListItemContext.js';\n\n// --- Context Guard ---\n\ninterface ListContext {\n\treadonly state: EditorState;\n\t/** The list item owning the caret (the caret block itself for leaf items). */\n\treadonly item: BlockNode;\n\t/** The caret's block child of a container item; undefined for leaf items. */\n\treadonly child: BlockNode | undefined;\n\treadonly childIndex: number;\n\treadonly childCount: number;\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n}\n\n/**\n * Guards against NodeSelection, non-collapsed selections, and carets outside\n * list items. Resolves both leaf items (caret directly inside the item) and\n * container items (caret inside a direct block child of the item).\n */\nfunction withListContext(context: PluginContext, handler: (ctx: ListContext) => boolean): boolean {\n\tconst state: EditorState = context.getState();\n\tif (!isTextSelection(state.selection)) return false;\n\n\tconst sel = state.selection;\n\tif (!isCollapsed(sel)) return false;\n\n\tconst block: BlockNode | undefined = state.getBlock(sel.anchor.blockId);\n\tif (!block) return false;\n\n\tif (block.type === 'list_item') {\n\t\treturn handler({\n\t\t\tstate,\n\t\t\titem: block,\n\t\t\tchild: undefined,\n\t\t\tchildIndex: -1,\n\t\t\tchildCount: 0,\n\t\t\tblockId: sel.anchor.blockId,\n\t\t\toffset: sel.anchor.offset,\n\t\t});\n\t}\n\n\tconst parent: BlockNode | undefined = state.getParent(sel.anchor.blockId);\n\tif (!parent || parent.type !== 'list_item') return false;\n\tconst children: readonly BlockNode[] = getBlockChildren(parent);\n\tconst childIndex: number = children.findIndex((c) => c.id === block.id);\n\tif (childIndex < 0) return false;\n\n\treturn handler({\n\t\tstate,\n\t\titem: parent,\n\t\tchild: block,\n\t\tchildIndex,\n\t\tchildCount: children.length,\n\t\tblockId: sel.anchor.blockId,\n\t\toffset: sel.anchor.offset,\n\t});\n}\n\n/** Registers Enter and Backspace keymaps for list items. */\nexport function registerListKeymaps(context: PluginContext): void {\n\tcontext.registerKeymap({\n\t\tEnter: () => handleEnter(context),\n\t\tBackspace: () => handleBackspace(context),\n\t});\n}\n\n// --- Enter Handler ---\n\n/**\n * Handles Enter inside a list item.\n * Leaf items: empty → exit list (convert to paragraph); non-empty → split\n * into a new item of the same type.\n * Container items: an empty trailing child exits into a new sibling item;\n * a lone empty child dissolves the item. Everything else falls through to\n * the default split (which grows the item's children).\n */\nfunction handleEnter(context: PluginContext): boolean {\n\treturn withListContext(context, (ctx) => {\n\t\tif (ctx.child) return handleEnterInContainerChild(context, ctx, ctx.child);\n\n\t\tconst text: string = getBlockText(ctx.item);\n\n\t\tif (text === '') {\n\t\t\tconst tr = ctx.state\n\t\t\t\t.transaction('input')\n\t\t\t\t.setBlockType(ctx.blockId, nodeType('paragraph'))\n\t\t\t\t.setSelection(ctx.state.selection)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst newBlockId = generateBlockId();\n\t\tconst listType = isNodeOfType(ctx.item, 'list_item') ? ctx.item.attrs.listType : 'bullet';\n\t\tconst indent: number = isNodeOfType(ctx.item, 'list_item') ? ctx.item.attrs.indent : 0;\n\t\tconst attrs = buildListItemAttrs(listType, indent);\n\n\t\tconst tr = ctx.state\n\t\t\t.transaction('input')\n\t\t\t.splitBlock(ctx.blockId, ctx.offset, newBlockId)\n\t\t\t.setBlockType(newBlockId, nodeType('list_item'), attrs)\n\t\t\t.setSelection(createCollapsedSelection(newBlockId, 0))\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t});\n}\n\n/** Enter inside a container item's child: exit on an empty trailing child. */\nfunction handleEnterInContainerChild(\n\tcontext: PluginContext,\n\tctx: ListContext,\n\tchild: BlockNode,\n): boolean {\n\tif (!isEmptyParagraph(child)) return false;\n\tif (ctx.childIndex !== ctx.childCount - 1) return false;\n\n\tconst location: ListItemLocation | undefined = locateListItem(ctx.state, ctx.item.id);\n\tif (!location) return false;\n\n\tconst builder = ctx.state.transaction('input');\n\n\tif (ctx.childCount === 1) {\n\t\t// A lone empty child: the item has no content left — dissolve it and\n\t\t// keep the paragraph (same ID, so the caret stays put).\n\t\tdissolveListItem(builder, location);\n\t\tbuilder.setSelection(ctx.state.selection);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\t// Drop the empty trailing child and continue the list with a fresh item.\n\tconst listType = isNodeOfType(ctx.item, 'list_item') ? ctx.item.attrs.listType : 'bullet';\n\tconst indent: number = isNodeOfType(ctx.item, 'list_item') ? ctx.item.attrs.indent : 0;\n\tconst newItemId = generateBlockId();\n\tconst newItem: BlockNode = createBlockNode(\n\t\tnodeType('list_item'),\n\t\t[createTextNode('')],\n\t\tnewItemId,\n\t\tbuildListItemAttrs(listType, indent),\n\t);\n\n\tbuilder\n\t\t.removeNode([...location.parentPath, ctx.item.id], ctx.childIndex)\n\t\t.insertNode(location.parentPath, location.index + 1, newItem)\n\t\t.setSelection(createCollapsedSelection(newItemId, 0));\n\tcontext.dispatch(builder.build());\n\treturn true;\n}\n\n// --- Backspace Handler ---\n\n/**\n * Handles Backspace at the start of a list item.\n * Leaf items convert back to a paragraph. Container items dissolve into\n * their block children when the caret sits at the very start of the first\n * child (the un-list gesture); later children fall through to the default\n * sibling merge.\n */\nfunction handleBackspace(context: PluginContext): boolean {\n\treturn withListContext(context, (ctx) => {\n\t\tif (ctx.offset !== 0) return false;\n\n\t\tif (ctx.child) {\n\t\t\tif (ctx.childIndex !== 0) return false;\n\t\t\tconst location: ListItemLocation | undefined = locateListItem(ctx.state, ctx.item.id);\n\t\t\tif (!location) return false;\n\t\t\tconst builder = ctx.state.transaction('input');\n\t\t\tdissolveListItem(builder, location);\n\t\t\tbuilder.setSelection(ctx.state.selection);\n\t\t\tcontext.dispatch(builder.build());\n\t\t\treturn true;\n\t\t}\n\n\t\tconst tr = ctx.state\n\t\t\t.transaction('input')\n\t\t\t.setBlockType(ctx.blockId, nodeType('paragraph'))\n\t\t\t.setSelection(ctx.state.selection)\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t});\n}\n","/**\n * Locale interface and default English locale for the ListPlugin.\n */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface ListLocale {\n\treadonly bulletList: string;\n\treadonly numberedList: string;\n\treadonly checklist: string;\n\t/** Accessible name for the checklist item's checkbox marker (screen readers). */\n\treadonly checkboxLabel: string;\n\t/** Announced when a checklist item is toggled on. */\n\treadonly checkedAnnouncement: string;\n\t/** Announced when a checklist item is toggled off. */\n\treadonly uncheckedAnnouncement: string;\n}\n\n// --- Default English Locale ---\n\nexport const LIST_LOCALE_EN: ListLocale = {\n\tbulletList: 'Bullet List',\n\tnumberedList: 'Numbered List',\n\tchecklist: 'Checklist',\n\tcheckboxLabel: 'To-do item',\n\tcheckedAnnouncement: 'Checked',\n\tuncheckedAnnouncement: 'Unchecked',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<ListLocale> = import.meta.glob<{\n\tdefault: ListLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadListLocale(lang: string): Promise<ListLocale> {\n\treturn loadLocaleModule(localeModules, lang, LIST_LOCALE_EN);\n}\n","/**\n * Accessible checkbox marker for checklist items.\n *\n * The marker is a real `role=\"checkbox\"` element so assistive technology can\n * announce the item's checked state (WCAG 4.1.2 Name, Role, Value). It is\n * rendered `contenteditable=\"false\"` and flagged `data-widget` so the selection\n * layer treats it as zero-width view chrome, never as document content or a caret\n * position. The visible checkbox glyph is drawn in CSS.\n */\n\n/** CSS class identifying the checklist checkbox marker element. */\nexport const CHECKLIST_MARKER_CLASS = 'notectl-checklist-marker';\n\n/** Creates the accessible checkbox marker for a checklist item. */\nexport function createChecklistMarker(checked: boolean, label: string): HTMLElement {\n\tconst marker: HTMLElement = document.createElement('span');\n\tmarker.className = CHECKLIST_MARKER_CLASS;\n\tmarker.setAttribute('role', 'checkbox');\n\tmarker.setAttribute('aria-checked', String(checked));\n\tmarker.setAttribute('aria-label', label);\n\tmarker.setAttribute('contenteditable', 'false');\n\tmarker.setAttribute('data-widget', 'true');\n\treturn marker;\n}\n","/**\n * Toolbar item registration for list block types.\n * Registers bullet, ordered, and checklist toolbar buttons with active-state detection.\n */\n\nimport { isTextSelection, selectionRange } from '../../model/Selection.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { allBlocksMatchListType } from './ListCommands.js';\nimport type { ListTypeDefinition } from './ListDefinitions.js';\nimport { resolveListItem } from './ListItemContext.js';\nimport type { ListLocale } from './ListLocale.js';\nimport type { ListType } from './ListPlugin.js';\n\n/** Registers toolbar items for each enabled list type. */\nexport function registerListToolbarItems(\n\tcontext: PluginContext,\n\tenabledTypes: readonly ListTypeDefinition[],\n\tlocale: ListLocale,\n): void {\n\tfor (const def of enabledTypes) {\n\t\tcontext.registerToolbarItem({\n\t\t\tid: `list-${def.type}`,\n\t\t\tgroup: 'block',\n\t\t\ticon: def.icon,\n\t\t\tlabel: getListLabel(def.type, locale),\n\t\t\tcommand: `toggleList:${def.type}`,\n\t\t\tisActive: (state) => isListActive(state, def.type),\n\t\t});\n\t}\n}\n\n// --- Helpers ---\n\nfunction getListLabel(type: ListType, locale: ListLocale): string {\n\tconst labels: Record<ListType, string> = {\n\t\tbullet: locale.bulletList,\n\t\tordered: locale.numberedList,\n\t\tchecklist: locale.checklist,\n\t};\n\treturn labels[type];\n}\n\nfunction isListActive(state: EditorState, listType: ListType): boolean {\n\tif (!isTextSelection(state.selection)) return false;\n\n\tif (state.selection.anchor.blockId !== state.selection.head.blockId) {\n\t\tconst range = selectionRange(state.selection, state.getBlockOrder());\n\t\treturn allBlocksMatchListType(state, range, listType);\n\t}\n\n\t// Children of container items resolve to their owning item (#194).\n\tconst block = resolveListItem(state, state.selection.anchor.blockId);\n\treturn block?.type === 'list_item' && block.attrs?.listType === listType;\n}\n","/**\n * ListPlugin: registers ordered, unordered, and checklist block types\n * with NodeSpecs, toggle commands, indent/outdent (Tab/Shift-Tab),\n * input rules, and toolbar buttons.\n *\n * This file is a thin orchestrator — command logic, input rules, keyboard\n * handlers, and toolbar rendering are delegated to dedicated modules.\n *\n * Sibling structure is modeled flat: every item carries a `listType` and an\n * `indent` attribute, so nesting between items needs no deep tree. Item\n * content is hybrid (#194): a single-paragraph item is a leaf with inline\n * children, while a multi-block item (second paragraph, code block, quote,\n * heading) is a container whose children are blocks.\n */\n\nimport { LIST_CSS, LIST_MARKER_WIDTH } from '../../editor/styles/list.js';\nimport { blockId } from '../../model/TypeBrands.js';\nimport { setStyleProperty } from '../../style/StyleRuntime.js';\nimport { createBlockElement } from '../../view/DomUtils.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport { registerListCommands, toggleChecked } from './ListCommands.js';\nimport { LIST_TYPE_DEFINITIONS, type ListTypeDefinition } from './ListDefinitions.js';\nimport { registerListInputRules } from './ListInputRules.js';\nimport { registerListKeymaps } from './ListKeyboardHandlers.js';\nimport { LIST_LOCALE_EN, type ListLocale, loadListLocale } from './ListLocale.js';\nimport { CHECKLIST_MARKER_CLASS, createChecklistMarker } from './ListMarker.js';\nimport { registerListToolbarItems } from './ListToolbarItems.js';\n\n// --- Attribute Registry Augmentation ---\n\nexport type ListType = 'bullet' | 'ordered' | 'checklist';\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\tlist_item: { listType: ListType; indent: number; checked: boolean };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface ListConfig {\n\t/** Which list types to enable. Defaults to all. */\n\treadonly types: readonly ListType[];\n\t/** Maximum indent depth. Defaults to 4. */\n\treadonly maxIndent: number;\n\t/** Live Markdown shortcuts: `- `/`* ` (bullet), `1. ` (ordered), `[ ] ` (checklist). Default true. */\n\treadonly inputRule?: boolean;\n\t/**\n\t * When true, checklist checkboxes remain interactive even in read-only mode.\n\t * Defaults to false (checkboxes are fully read-only).\n\t */\n\treadonly interactiveCheckboxes?: boolean;\n\treadonly locale?: ListLocale;\n}\n\nconst DEFAULT_CONFIG: ListConfig = {\n\ttypes: ['bullet', 'ordered', 'checklist'],\n\tmaxIndent: 4,\n};\n\n// --- Plugin ---\n\nexport class ListPlugin implements Plugin {\n\treadonly id = 'list';\n\treadonly name = 'List';\n\treadonly priority = 35;\n\n\tprivate readonly config: ListConfig;\n\tprivate locale!: ListLocale;\n\tprivate context: PluginContext | null = null;\n\tprivate checkboxClickHandler: ((e: MouseEvent) => void) | null = null;\n\n\tconstructor(config?: Partial<ListConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.context = context;\n\t\tthis.locale = await resolveLocale(context, this.config.locale, LIST_LOCALE_EN, loadListLocale);\n\t\tconst enabledTypes = this.getEnabledTypes();\n\n\t\tcontext.registerStyleSheet(LIST_CSS);\n\t\tthis.registerNodeSpec(context);\n\t\tregisterListCommands(context, this.config, enabledTypes, this.locale);\n\t\tregisterListKeymaps(context);\n\t\tif (this.config.inputRule !== false) registerListInputRules(context, enabledTypes);\n\t\tregisterListToolbarItems(context, enabledTypes, this.locale);\n\t\tthis.registerCheckboxClickHandler(context);\n\t}\n\n\tdestroy(): void {\n\t\tif (this.checkboxClickHandler && this.context) {\n\t\t\tconst container: HTMLElement = this.context.getContainer();\n\t\t\tcontainer.removeEventListener('mousedown', this.checkboxClickHandler);\n\t\t}\n\t\tthis.checkboxClickHandler = null;\n\t\tthis.context = null;\n\t}\n\n\tprivate registerNodeSpec(context: PluginContext): void {\n\t\tconst checkboxLabel: string = this.locale.checkboxLabel;\n\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'list_item',\n\t\t\tgroup: 'block',\n\t\t\t// Hybrid content model (#194): the common single-paragraph item is a\n\t\t\t// leaf (inline text children); multi-block items are containers with\n\t\t\t// block children. Sibling nesting stays flat-with-indent, so list_item\n\t\t\t// itself is deliberately not an allowed child.\n\t\t\tcontent: {\n\t\t\t\tallow: ['text', 'paragraph', 'heading', 'code_block', 'blockquote', 'horizontal_rule'],\n\t\t\t},\n\t\t\tattrs: {\n\t\t\t\tlistType: { default: 'bullet' },\n\t\t\t\tindent: { default: 0 },\n\t\t\t\tchecked: { default: false },\n\t\t\t},\n\t\t\ttoDOM(node) {\n\t\t\t\tconst listType = node.attrs?.listType ?? 'bullet';\n\t\t\t\tconst indent = node.attrs?.indent ?? 0;\n\t\t\t\tconst checked = node.attrs?.checked ?? false;\n\n\t\t\t\tconst li = createBlockElement('li', node.id);\n\t\t\t\tli.setAttribute('role', 'listitem');\n\t\t\t\tli.setAttribute('data-list-type', listType);\n\t\t\t\tli.setAttribute('data-indent', String(indent));\n\t\t\t\tli.className = `notectl-list-item notectl-list-item--${listType}`;\n\n\t\t\t\tif (indent > 0) {\n\t\t\t\t\tsetStyleProperty(li, 'marginLeft', `${indent * LIST_MARKER_WIDTH}px`);\n\t\t\t\t}\n\n\t\t\t\tif (listType === 'checklist') {\n\t\t\t\t\t// `data-checked` drives the CSS glyph; the checked state is exposed to\n\t\t\t\t\t// assistive technology via the marker's own role=\"checkbox\", not via an\n\t\t\t\t\t// (invalid) aria-checked on the listitem. The marker is the first child\n\t\t\t\t\t// so reconciled inline content is appended after it.\n\t\t\t\t\tli.setAttribute('data-checked', String(checked));\n\t\t\t\t\tli.appendChild(createChecklistMarker(checked, checkboxLabel));\n\t\t\t\t}\n\t\t\t\tli.setAttribute('aria-level', String(indent + 1));\n\n\t\t\t\treturn li;\n\t\t\t},\n\t\t\twrapper(node) {\n\t\t\t\tconst listType = node.attrs?.listType ?? 'bullet';\n\t\t\t\tconst tag = listType === 'ordered' ? 'ol' : 'ul';\n\t\t\t\treturn {\n\t\t\t\t\ttag,\n\t\t\t\t\tkey: `list-${listType}`,\n\t\t\t\t\tclassName: `notectl-list notectl-list--${listType}`,\n\t\t\t\t\tattrs: { role: 'list' },\n\t\t\t\t};\n\t\t\t},\n\t\t\ttoHTML(node, content) {\n\t\t\t\tconst listType: string = (node.attrs?.listType as string) ?? 'bullet';\n\t\t\t\tconst checked: boolean = (node.attrs?.checked as boolean) ?? false;\n\n\t\t\t\tif (listType === 'checklist') {\n\t\t\t\t\tconst checkedAttr: string = checked ? ' checked' : '';\n\t\t\t\t\tconst ariaChecked: string = String(checked);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t`<li role=\"checkbox\" aria-checked=\"${ariaChecked}\">` +\n\t\t\t\t\t\t`<input type=\"checkbox\" disabled${checkedAttr}>` +\n\t\t\t\t\t\t`${content || '<br>'}</li>`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn `<li>${content || '<br>'}</li>`;\n\t\t\t},\n\t\t\tparseHTML: [{ tag: 'li' }],\n\t\t\tsanitize: {\n\t\t\t\ttags: ['ul', 'ol', 'li', 'input'],\n\t\t\t\tattrs: ['type', 'disabled', 'checked', 'role', 'aria-checked'],\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerCheckboxClickHandler(context: PluginContext): void {\n\t\tif (!this.config.types.includes('checklist')) return;\n\n\t\tthis.checkboxClickHandler = (e: MouseEvent) => {\n\t\t\tif (context.isReadOnly() && !this.config.interactiveCheckboxes) return;\n\n\t\t\tconst target: EventTarget | null = e.target;\n\t\t\tif (!(target instanceof HTMLElement)) return;\n\n\t\t\t// Toggle only when the checkbox marker itself is clicked. The marker is a\n\t\t\t// real element, so this is precise — no geometry/RTL math needed.\n\t\t\tconst marker: Element | null = target.closest(`.${CHECKLIST_MARKER_CLASS}`);\n\t\t\tif (!marker) return;\n\n\t\t\tconst li: Element | null = marker.closest('.notectl-list-item--checklist');\n\t\t\tif (!li) return;\n\n\t\t\te.preventDefault();\n\n\t\t\tconst bid: string | null = li.getAttribute('data-block-id');\n\t\t\tif (!bid) return;\n\n\t\t\ttoggleChecked(context, {\n\t\t\t\tinteractiveCheckboxes: this.config.interactiveCheckboxes,\n\t\t\t\ttargetId: blockId(bid),\n\t\t\t\tlocale: this.locale,\n\t\t\t});\n\t\t};\n\n\t\tconst container: HTMLElement = context.getContainer();\n\t\tcontainer.addEventListener('mousedown', this.checkboxClickHandler);\n\t}\n\n\tprivate getEnabledTypes(): readonly ListTypeDefinition[] {\n\t\treturn LIST_TYPE_DEFINITIONS.filter((def) => this.config.types.includes(def.type));\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ListPlugin-BchSFWVn.mjs","names":[],"sources":["../../src/editor/styles/list.ts","../../src/plugins/list/ListAttrsFactory.ts","../../src/plugins/list/ListItemContext.ts","../../src/plugins/list/ListCommands.ts","../../src/plugins/list/ListDefinitions.ts","../../src/plugins/list/ListInputRules.ts","../../src/plugins/list/ListKeyboardHandlers.ts","../../src/plugins/list/ListLocale.ts","../../src/plugins/list/ListMarker.ts","../../src/plugins/list/ListToolbarItems.ts","../../src/plugins/list/ListPlugin.ts"],"sourcesContent":["/** Width of the list marker / checkbox area in pixels. */\nexport const LIST_MARKER_WIDTH = 24;\n\n/** List styles — bullet, ordered, checklist items. */\nexport const LIST_CSS = `\n/* List Wrappers — suppress native markers, we use ::before pseudo-elements */\n.notectl-list {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n/* Ordered List — each <ol> wrapper resets the counter */\n.notectl-list--ordered {\n\tcounter-reset: notectl-ordered;\n}\n\n/* List Items */\n.notectl-list-item {\n\tmargin: 0;\n\tpadding: 2px 0;\n\tpadding-inline-start: ${LIST_MARKER_WIDTH}px;\n\tmin-height: 1.6em;\n\tposition: relative;\n}\n\n.notectl-list-item::before {\n\tposition: absolute;\n\tinset-inline-start: 0;\n\tdisplay: inline-block;\n\twidth: ${LIST_MARKER_WIDTH}px;\n\ttext-align: center;\n\t-webkit-user-select: none;\n\tuser-select: none;\n\tpointer-events: none;\n}\n\n/* Container items (#194): block children inherit the item's start padding.\n Trim the first/last child paragraph padding so the first text line sits on\n the marker's line and the item keeps the leaf item's vertical rhythm. */\n.notectl-list-item > p:first-of-type {\n\tpadding-top: 0;\n}\n\n.notectl-list-item > p:last-of-type {\n\tpadding-bottom: 0;\n}\n\n/* Bullet List */\n.notectl-list-item--bullet::before {\n\tcontent: '\\\\2022';\n\tcolor: var(--notectl-fg);\n}\n\n/* Ordered List — counter increment per item */\n.notectl-list-item--ordered {\n\tcounter-increment: notectl-ordered;\n}\n\n.notectl-list-item--ordered::before {\n\tcontent: counter(notectl-ordered) '.';\n\tcolor: var(--notectl-fg);\n\tfont-size: 14px;\n}\n\n/* Checklist — the marker is a real role=\"checkbox\" element (see ListMarker.ts)\n positioned over the reserved marker zone. inline-block keeps the parent's\n line-through (on checked items) from striking the glyph. */\n.notectl-checklist-marker {\n\tposition: absolute;\n\tinset-inline-start: 0;\n\tdisplay: inline-block;\n\twidth: ${LIST_MARKER_WIDTH}px;\n\ttext-align: center;\n\tfont-size: 16px;\n\tcolor: var(--notectl-fg-muted);\n\tcursor: pointer;\n\ttext-decoration: none;\n\t-webkit-user-select: none;\n\tuser-select: none;\n}\n\n.notectl-checklist-marker::before {\n\tcontent: '\\\\2610';\n}\n\n.notectl-list-item--checklist[data-checked=\"true\"] .notectl-checklist-marker {\n\tcolor: var(--notectl-success);\n}\n\n.notectl-list-item--checklist[data-checked=\"true\"] .notectl-checklist-marker::before {\n\tcontent: '\\\\2611';\n}\n\n.notectl-list-item--checklist[data-checked=\"true\"] {\n\tcolor: var(--notectl-fg-muted);\n\ttext-decoration: line-through;\n}\n`;\n","/**\n * Factory for building list item block attributes.\n * Centralizes attribute construction to avoid repetitive inline object literals.\n */\n\nimport type { BlockAttrs } from '../../model/Document.js';\nimport type { ListType } from './ListPlugin.js';\n\n/** Builds a `BlockAttrs` object for a list_item block. */\nexport function buildListItemAttrs(\n\tlistType: ListType,\n\tindent: number,\n\tchecked?: boolean,\n): BlockAttrs {\n\tif (listType === 'checklist') {\n\t\treturn { listType, indent, checked: checked ?? false };\n\t}\n\treturn { listType, indent };\n}\n","/**\n * Shared resolution helpers for container list items (#194).\n *\n * With `list_item` a hybrid leaf/container block, the caret may sit inside a\n * block child of an item. Commands and keyboard handlers resolve the owning\n * item through the ancestor chain and address structural edits through the\n * item's location (parent path + child index), mirroring the blockquote\n * container conventions.\n */\n\nimport type { BlockNode } from '../../model/Document.js';\nimport { getBlockChildren } from '../../model/Document.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { TransactionBuilder } from '../../state/TransactionBuilder.js';\n\n/** A list item's structural address: its parent path and child index. */\nexport interface ListItemLocation {\n\treadonly item: BlockNode;\n\t/** Path from the document root to the item's parent ([] = root). */\n\treadonly parentPath: readonly BlockId[];\n\t/** The item's index among its parent's block children. */\n\treadonly index: number;\n}\n\n/**\n * Resolves the list item owning a block: the block itself when it is a\n * `list_item`, otherwise its nearest `list_item` ancestor.\n */\nexport function resolveListItem(state: EditorState, id: BlockId): BlockNode | undefined {\n\tconst block: BlockNode | undefined = state.getBlock(id);\n\tif (block?.type === 'list_item') return block;\n\tconst path: readonly BlockId[] | undefined = state.getNodePath(id);\n\tif (!path) return undefined;\n\tfor (let i = path.length - 2; i >= 0; i--) {\n\t\tconst ancestorId: BlockId | undefined = path[i];\n\t\tconst ancestor: BlockNode | undefined = ancestorId ? state.getBlock(ancestorId) : undefined;\n\t\tif (ancestor?.type === 'list_item') return ancestor;\n\t}\n\treturn undefined;\n}\n\n/** Locates a list item's structural address, or undefined if it is not found. */\nexport function locateListItem(state: EditorState, itemId: BlockId): ListItemLocation | undefined {\n\tconst item: BlockNode | undefined = state.getBlock(itemId);\n\tif (!item || item.type !== 'list_item') return undefined;\n\tconst path: readonly BlockId[] | undefined = state.getNodePath(itemId);\n\tif (!path) return undefined;\n\n\tconst parentPath: readonly BlockId[] = path.slice(0, -1);\n\tconst parentId: BlockId | undefined = parentPath[parentPath.length - 1];\n\tconst siblings: readonly BlockNode[] = parentId\n\t\t? getBlockChildren(state.getBlock(parentId) as BlockNode)\n\t\t: state.doc.children;\n\tconst index: number = siblings.findIndex((sibling) => sibling.id === itemId);\n\tif (index < 0) return undefined;\n\treturn { item, parentPath, index };\n}\n\n/**\n * Replaces a container list item with its block children in place. The\n * children keep their IDs, so a selection inside them survives the lift.\n * Leaf items must not be dissolved (their inline content is not a block);\n * convert those via `setBlockType` instead.\n */\nexport function dissolveListItem(builder: TransactionBuilder, location: ListItemLocation): void {\n\tbuilder.removeNode(location.parentPath, location.index);\n\tconst children: readonly BlockNode[] = getBlockChildren(location.item);\n\tchildren.forEach((child, offset) => {\n\t\tbuilder.insertNode(location.parentPath, location.index + offset, child);\n\t});\n}\n","/**\n * Command registration and implementations for list block types.\n * Handles toggle between list types and paragraph, indent/outdent,\n * and checklist toggle.\n */\n\nimport { forEachBlockIdInRange } from '../../commands/RangeIterator.js';\nimport { isNodeOfType } from '../../model/AttrRegistry.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport { isLeafBlock } from '../../model/Document.js';\nimport { isTextSelection, selectionRange } from '../../model/Selection.js';\nimport { type BlockId, nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { buildListItemAttrs } from './ListAttrsFactory.js';\nimport type { ListTypeDefinition } from './ListDefinitions.js';\nimport { dissolveListItem, locateListItem, resolveListItem } from './ListItemContext.js';\nimport type { ListLocale } from './ListLocale.js';\nimport type { ListConfig, ListType } from './ListPlugin.js';\n\n/** Registers all list commands (toggleList:*, indent, outdent, toggleChecklistItem). */\nexport function registerListCommands(\n\tcontext: PluginContext,\n\tconfig: ListConfig,\n\tenabledTypes: readonly ListTypeDefinition[],\n\tlocale: ListLocale,\n): void {\n\tfor (const def of enabledTypes) {\n\t\tcontext.registerCommand(`toggleList:${def.type}`, () => {\n\t\t\treturn toggleList(context, def.type);\n\t\t});\n\t}\n\n\tcontext.registerCommand('indentListItem', () => changeIndent(context, 1, config.maxIndent));\n\n\tcontext.registerCommand('outdentListItem', () => changeIndent(context, -1, config.maxIndent));\n\n\tif (config.types.includes('checklist')) {\n\t\tconst toggleChecklistItem = (): boolean =>\n\t\t\ttoggleChecked(context, { interactiveCheckboxes: config.interactiveCheckboxes, locale });\n\n\t\tcontext.registerCommand('toggleChecklistItem', toggleChecklistItem, {\n\t\t\treadonlyAllowed: true,\n\t\t});\n\n\t\t// Mod-Enter gives keyboard-only users a way to toggle a checklist item\n\t\t// (WCAG 2.1.1). The handler declines on non-checklist blocks, so it falls\n\t\t// through to other Mod-Enter bindings (e.g. code-block insert-after).\n\t\t// Registered at navigation priority so it stays reachable in read-only mode\n\t\t// when interactiveCheckboxes is enabled, matching the mouse handler.\n\t\tcontext.registerKeymap({ 'Mod-Enter': toggleChecklistItem }, { priority: 'navigation' });\n\t}\n\n\tcontext.registerKeymap({\n\t\tTab: () => changeIndent(context, 1, config.maxIndent),\n\t\t'Shift-Tab': () => changeIndent(context, -1, config.maxIndent),\n\t});\n}\n\n// --- Command Implementations ---\n\nfunction toggleList(context: PluginContext, listType: ListType): boolean {\n\tconst state: EditorState = context.getState();\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return false;\n\n\tif (sel.anchor.blockId !== sel.head.blockId) {\n\t\treturn toggleListRange(context, state, listType);\n\t}\n\treturn toggleListSingleBlock(context, state, listType);\n}\n\nfunction toggleListSingleBlock(\n\tcontext: PluginContext,\n\tstate: EditorState,\n\tlistType: ListType,\n): boolean {\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return false;\n\tconst block = state.getBlock(sel.anchor.blockId);\n\tif (!block) return false;\n\n\t// The caret may sit inside a block child of a container item (#194):\n\t// toggling always targets the owning item, never the child.\n\tconst item: BlockNode | undefined = resolveListItem(state, sel.anchor.blockId);\n\tconst target: BlockNode = item ?? block;\n\n\tif (item && item.attrs?.listType === listType) {\n\t\tconst builder = state.transaction('command');\n\t\tif (isLeafBlock(item)) {\n\t\t\tbuilder.setBlockType(item.id, nodeType('paragraph'));\n\t\t} else {\n\t\t\t// A container item cannot become a paragraph (its children are\n\t\t\t// blocks) — dissolve it into those children instead.\n\t\t\tconst location = locateListItem(state, item.id);\n\t\t\tif (!location) return false;\n\t\t\tdissolveListItem(builder, location);\n\t\t}\n\t\tbuilder.setSelection(sel);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\tconst existingIndent: number = isNodeOfType(target, 'list_item') ? target.attrs.indent : 0;\n\tconst attrs = buildListItemAttrs(listType, existingIndent);\n\n\tconst tr = state\n\t\t.transaction('command')\n\t\t.setBlockType(target.id, nodeType('list_item'), attrs)\n\t\t.setSelection(sel)\n\t\t.build();\n\tcontext.dispatch(tr);\n\treturn true;\n}\n\nfunction toggleListRange(context: PluginContext, state: EditorState, listType: ListType): boolean {\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return false;\n\n\tconst range = selectionRange(sel, state.getBlockOrder());\n\tconst toggleOff: boolean = allBlocksMatchListType(state, range, listType);\n\tconst builder = state.transaction('command');\n\n\t// Children of a container item resolve to their owning item (#194), so a\n\t// range over its paragraphs toggles the item once, not each child.\n\tconst targets: BlockNode[] = collectToggleTargets(state, range);\n\n\t// Dissolving replaces one node with several, shifting later sibling\n\t// indices — process targets back-to-front so earlier addresses stay valid.\n\tfor (let i = targets.length - 1; i >= 0; i--) {\n\t\tconst target: BlockNode | undefined = targets[i];\n\t\tif (!target) continue;\n\n\t\tif (toggleOff) {\n\t\t\tif (isLeafBlock(target)) {\n\t\t\t\tbuilder.setBlockType(target.id, nodeType('paragraph'));\n\t\t\t} else {\n\t\t\t\tconst location = locateListItem(state, target.id);\n\t\t\t\tif (location) dissolveListItem(builder, location);\n\t\t\t}\n\t\t} else {\n\t\t\tconst existingIndent: number = isNodeOfType(target, 'list_item') ? target.attrs.indent : 0;\n\t\t\tconst existingChecked: boolean =\n\t\t\t\tisNodeOfType(target, 'list_item') &&\n\t\t\t\ttarget.attrs.listType === 'checklist' &&\n\t\t\t\ttarget.attrs.checked;\n\t\t\tbuilder.setBlockType(\n\t\t\t\ttarget.id,\n\t\t\t\tnodeType('list_item'),\n\t\t\t\tbuildListItemAttrs(listType, existingIndent, existingChecked),\n\t\t\t);\n\t\t}\n\t}\n\n\tbuilder.setSelection(sel);\n\tcontext.dispatch(builder.build());\n\treturn true;\n}\n\n/** Collects unique toggle targets: each leaf block or its owning list item. */\nfunction collectToggleTargets(\n\tstate: EditorState,\n\trange: ReturnType<typeof selectionRange>,\n): BlockNode[] {\n\tconst targets: BlockNode[] = [];\n\tconst seen = new Set<BlockId>();\n\tforEachBlockIdInRange(state, range, (bid: BlockId) => {\n\t\tconst block = state.getBlock(bid);\n\t\tif (!block) return;\n\t\tconst target: BlockNode = resolveListItem(state, bid) ?? block;\n\t\tif (seen.has(target.id)) return;\n\t\tseen.add(target.id);\n\t\ttargets.push(target);\n\t});\n\treturn targets;\n}\n\n// --- Indent / Outdent ---\n\nfunction changeIndent(context: PluginContext, delta: 1 | -1, maxIndent: number): boolean {\n\tconst state: EditorState = context.getState();\n\tif (!isTextSelection(state.selection)) return false;\n\n\tif (state.selection.anchor.blockId !== state.selection.head.blockId) {\n\t\treturn changeIndentRange(context, state, delta, maxIndent);\n\t}\n\n\tconst sel = state.selection;\n\tconst block = resolveListItem(state, sel.anchor.blockId);\n\tif (!block || !isNodeOfType(block, 'list_item')) return false;\n\n\tconst newIndent: number = block.attrs.indent + delta;\n\tif (newIndent < 0 || newIndent > maxIndent) return false;\n\n\tconst attrs = buildListItemAttrs(block.attrs.listType, newIndent, block.attrs.checked);\n\tconst tr = state\n\t\t.transaction('command')\n\t\t.setBlockType(block.id, nodeType('list_item'), attrs)\n\t\t.setSelection(sel)\n\t\t.build();\n\tcontext.dispatch(tr);\n\treturn true;\n}\n\nfunction changeIndentRange(\n\tcontext: PluginContext,\n\tstate: EditorState,\n\tdelta: 1 | -1,\n\tmaxIndent: number,\n): boolean {\n\tconst sel = state.selection;\n\tif (!isTextSelection(sel)) return false;\n\n\tconst range = selectionRange(sel, state.getBlockOrder());\n\tconst builder = state.transaction('command');\n\tlet changed = false;\n\tconst seen = new Set<BlockId>();\n\n\tforEachBlockIdInRange(state, range, (bid: BlockId) => {\n\t\tconst block = resolveListItem(state, bid);\n\t\tif (!block || !isNodeOfType(block, 'list_item')) return;\n\t\tif (seen.has(block.id)) return;\n\t\tseen.add(block.id);\n\n\t\tconst newIndent: number = block.attrs.indent + delta;\n\t\tif (newIndent < 0 || newIndent > maxIndent) return;\n\n\t\tbuilder.setBlockType(\n\t\t\tblock.id,\n\t\t\tnodeType('list_item'),\n\t\t\tbuildListItemAttrs(block.attrs.listType, newIndent, block.attrs.checked),\n\t\t);\n\t\tchanged = true;\n\t});\n\n\tif (!changed) return false;\n\n\tbuilder.setSelection(sel);\n\tcontext.dispatch(builder.build());\n\treturn true;\n}\n\n// --- Checklist Toggle ---\n\n/** Options for {@link toggleChecked}. */\nexport interface ToggleCheckedOptions {\n\t/** When true, the toggle is allowed even in read-only mode. */\n\treadonly interactiveCheckboxes?: boolean;\n\t/** Specific checklist item to toggle. Defaults to the selection's block. */\n\treadonly targetId?: BlockId;\n\t/** Locale used for the screen-reader announcement of the new state. */\n\treadonly locale: ListLocale;\n}\n\n/**\n * Toggles the checked state of a checklist item and announces the new state to\n * screen readers. Exported for use in the checkbox click handler.\n */\nexport function toggleChecked(context: PluginContext, options: ToggleCheckedOptions): boolean {\n\tconst { interactiveCheckboxes, targetId, locale } = options;\n\tif (context.isReadOnly() && !interactiveCheckboxes) return false;\n\n\tconst state: EditorState = context.getState();\n\tconst bid: BlockId | null =\n\t\ttargetId ?? (!isTextSelection(state.selection) ? null : state.selection.anchor.blockId);\n\tif (!bid) return false;\n\n\tconst block = resolveListItem(state, bid);\n\tif (!block || !isNodeOfType(block, 'list_item') || block.attrs.listType !== 'checklist') {\n\t\treturn false;\n\t}\n\n\tconst nextChecked: boolean = !block.attrs.checked;\n\tconst attrs = buildListItemAttrs(block.attrs.listType, block.attrs.indent, nextChecked);\n\n\tconst tr = state\n\t\t.transaction('command')\n\t\t.setBlockType(block.id, nodeType('list_item'), attrs)\n\t\t.setSelection(state.selection)\n\t\t.build();\n\tcontext.dispatch(tr);\n\n\t// The marker is not focused while editing, so the aria-checked change alone is\n\t// not spoken — announce the new state explicitly (WCAG 4.1.3).\n\tcontext.announce(nextChecked ? locale.checkedAnnouncement : locale.uncheckedAnnouncement);\n\treturn true;\n}\n\n// --- Helpers ---\n\n/**\n * Checks whether all blocks in a range belong to list items of the given type\n * (children of container items resolve to their owning item, #194). Exported\n * for toolbar active-state detection.\n */\nexport function allBlocksMatchListType(\n\tstate: EditorState,\n\trange: ReturnType<typeof selectionRange>,\n\tlistType: ListType,\n): boolean {\n\tlet allMatch = true;\n\tforEachBlockIdInRange(state, range, (bid: BlockId) => {\n\t\tconst block = resolveListItem(state, bid);\n\t\tif (!block || block.type !== 'list_item' || block.attrs?.listType !== listType) {\n\t\t\tallMatch = false;\n\t\t}\n\t});\n\treturn allMatch;\n}\n","/**\n * List type metadata: icons, patterns, and type definitions.\n * Pure data constants shared across list plugin modules.\n */\n\nimport type { ListType } from './ListPlugin.js';\n\n// --- List Type Metadata ---\n\nexport interface ListTypeDefinition {\n\treadonly type: ListType;\n\treadonly icon: string;\n\treadonly inputPattern: RegExp;\n\treadonly inputPrefix: string;\n}\n\nconst BULLET_LIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5 1.5-.67 1.5-1.5-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5 5.5 6.83 5.5 6 4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5 1.5-.68 1.5-1.5-.67-1.5-1.5-1.5zM7 19h14v-2H7v2zm0-6h14v-2H7v2zm0-8v2h14V5H7z\"/></svg>';\nconst NUMBERED_LIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M2 17h2v.5H3v1h1v.5H2v1h3v-4H2v1zm1-9h1V4H2v1h1v3zm-1 3h1.8L2 13.1v.9h3v-1H3.2L5 10.9V10H2v1zm5-6v2h14V5H7zm0 14h14v-2H7v2zm0-6h14v-2H7v2z\"/></svg>';\nconst CHECKLIST_ICON =\n\t'<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path d=\"M22 7h-9v2h9V7zm0 8h-9v2h9v-2zM5.54 11L2 7.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 11zm0 8L2 15.46l1.41-1.41 2.12 2.12 4.24-4.24 1.41 1.41L5.54 19z\"/></svg>';\n\nexport const LIST_TYPE_DEFINITIONS: readonly ListTypeDefinition[] = [\n\t{\n\t\ttype: 'bullet',\n\t\ticon: BULLET_LIST_ICON,\n\t\tinputPattern: /^[-*] $/,\n\t\tinputPrefix: '- ',\n\t},\n\t{\n\t\ttype: 'ordered',\n\t\ticon: NUMBERED_LIST_ICON,\n\t\tinputPattern: /^\\d+\\. $/,\n\t\tinputPrefix: '1. ',\n\t},\n\t{\n\t\ttype: 'checklist',\n\t\ticon: CHECKLIST_ICON,\n\t\tinputPattern: /^\\[[ x]] $/,\n\t\tinputPrefix: '[ ] ',\n\t},\n];\n","/**\n * Input rule registration for list block types.\n * Converts `- `, `* `, `1. `, `[ ] `, `[x] ` at the start of a paragraph into list items.\n */\n\nimport { createCollapsedSelection, isCollapsed, isTextSelection } from '../../model/Selection.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { buildListItemAttrs } from './ListAttrsFactory.js';\nimport type { ListTypeDefinition } from './ListDefinitions.js';\n\n/** Registers markdown-style input rules for configured list types. */\nexport function registerListInputRules(\n\tcontext: PluginContext,\n\tenabledTypes: readonly ListTypeDefinition[],\n): void {\n\tfor (const def of enabledTypes) {\n\t\tcontext.registerInputRule({\n\t\t\tpattern: def.inputPattern,\n\t\t\thandler: (state, match, start, _end) => {\n\t\t\t\tconst sel = state.selection;\n\t\t\t\tif (!isTextSelection(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\t// Inside a container list item (#194) the rule must not fire: it\n\t\t\t\t// would nest a list_item into a list_item, which the schema forbids.\n\t\t\t\tconst parent = state.getParent(sel.anchor.blockId);\n\t\t\t\tif (parent?.type === 'list_item') return null;\n\n\t\t\t\tconst matchStr = match[0] ?? '';\n\t\t\t\tconst matchLen = matchStr.length;\n\t\t\t\tconst attrs = buildListItemAttrs(def.type, 0, matchStr.includes('[x]'));\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, start, start + matchLen)\n\t\t\t\t\t.setBlockType(sel.anchor.blockId, nodeType('list_item'), attrs)\n\t\t\t\t\t.setSelection(createCollapsedSelection(sel.anchor.blockId, 0))\n\t\t\t\t\t.build();\n\t\t\t},\n\t\t});\n\t}\n}\n","/**\n * Keyboard handlers for list block types.\n *\n * Leaf items: Enter splits into a new item (or exits an empty item),\n * Backspace at the start converts back to a paragraph.\n *\n * Container items (#194): the caret sits inside a block child. Enter on an\n * empty trailing child exits into a new sibling item (Enter-Enter continues\n * the list); Backspace at the start of the first child dissolves the item\n * into its children — both mirroring the blockquote container conventions.\n * Everything else falls through to the default split/merge behavior.\n */\n\nimport { isEmptyParagraph } from '../../commands/BlockInsertion.js';\nimport { isNodeOfType } from '../../model/AttrRegistry.js';\nimport type { BlockNode } from '../../model/Document.js';\nimport { generateBlockId, getBlockChildren, getBlockText } from '../../model/Document.js';\nimport { createBlockNode, createTextNode } from '../../model/Document.js';\nimport { createCollapsedSelection, isCollapsed, isTextSelection } from '../../model/Selection.js';\nimport type { BlockId } from '../../model/TypeBrands.js';\nimport { nodeType } from '../../model/TypeBrands.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { buildListItemAttrs } from './ListAttrsFactory.js';\nimport { type ListItemLocation, dissolveListItem, locateListItem } from './ListItemContext.js';\n\n// --- Context Guard ---\n\ninterface ListContext {\n\treadonly state: EditorState;\n\t/** The list item owning the caret (the caret block itself for leaf items). */\n\treadonly item: BlockNode;\n\t/** The caret's block child of a container item; undefined for leaf items. */\n\treadonly child: BlockNode | undefined;\n\treadonly childIndex: number;\n\treadonly childCount: number;\n\treadonly blockId: BlockId;\n\treadonly offset: number;\n}\n\n/**\n * Guards against NodeSelection, non-collapsed selections, and carets outside\n * list items. Resolves both leaf items (caret directly inside the item) and\n * container items (caret inside a direct block child of the item).\n */\nfunction withListContext(context: PluginContext, handler: (ctx: ListContext) => boolean): boolean {\n\tconst state: EditorState = context.getState();\n\tif (!isTextSelection(state.selection)) return false;\n\n\tconst sel = state.selection;\n\tif (!isCollapsed(sel)) return false;\n\n\tconst block: BlockNode | undefined = state.getBlock(sel.anchor.blockId);\n\tif (!block) return false;\n\n\tif (block.type === 'list_item') {\n\t\treturn handler({\n\t\t\tstate,\n\t\t\titem: block,\n\t\t\tchild: undefined,\n\t\t\tchildIndex: -1,\n\t\t\tchildCount: 0,\n\t\t\tblockId: sel.anchor.blockId,\n\t\t\toffset: sel.anchor.offset,\n\t\t});\n\t}\n\n\tconst parent: BlockNode | undefined = state.getParent(sel.anchor.blockId);\n\tif (!parent || parent.type !== 'list_item') return false;\n\tconst children: readonly BlockNode[] = getBlockChildren(parent);\n\tconst childIndex: number = children.findIndex((c) => c.id === block.id);\n\tif (childIndex < 0) return false;\n\n\treturn handler({\n\t\tstate,\n\t\titem: parent,\n\t\tchild: block,\n\t\tchildIndex,\n\t\tchildCount: children.length,\n\t\tblockId: sel.anchor.blockId,\n\t\toffset: sel.anchor.offset,\n\t});\n}\n\n/** Registers Enter and Backspace keymaps for list items. */\nexport function registerListKeymaps(context: PluginContext): void {\n\tcontext.registerKeymap({\n\t\tEnter: () => handleEnter(context),\n\t\tBackspace: () => handleBackspace(context),\n\t});\n}\n\n// --- Enter Handler ---\n\n/**\n * Handles Enter inside a list item.\n * Leaf items: empty → exit list (convert to paragraph); non-empty → split\n * into a new item of the same type.\n * Container items: an empty trailing child exits into a new sibling item;\n * a lone empty child dissolves the item. Everything else falls through to\n * the default split (which grows the item's children).\n */\nfunction handleEnter(context: PluginContext): boolean {\n\treturn withListContext(context, (ctx) => {\n\t\tif (ctx.child) return handleEnterInContainerChild(context, ctx, ctx.child);\n\n\t\tconst text: string = getBlockText(ctx.item);\n\n\t\tif (text === '') {\n\t\t\tconst tr = ctx.state\n\t\t\t\t.transaction('input')\n\t\t\t\t.setBlockType(ctx.blockId, nodeType('paragraph'))\n\t\t\t\t.setSelection(ctx.state.selection)\n\t\t\t\t.build();\n\t\t\tcontext.dispatch(tr);\n\t\t\treturn true;\n\t\t}\n\n\t\tconst newBlockId = generateBlockId();\n\t\tconst listType = isNodeOfType(ctx.item, 'list_item') ? ctx.item.attrs.listType : 'bullet';\n\t\tconst indent: number = isNodeOfType(ctx.item, 'list_item') ? ctx.item.attrs.indent : 0;\n\t\tconst attrs = buildListItemAttrs(listType, indent);\n\n\t\tconst tr = ctx.state\n\t\t\t.transaction('input')\n\t\t\t.splitBlock(ctx.blockId, ctx.offset, newBlockId)\n\t\t\t.setBlockType(newBlockId, nodeType('list_item'), attrs)\n\t\t\t.setSelection(createCollapsedSelection(newBlockId, 0))\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t});\n}\n\n/** Enter inside a container item's child: exit on an empty trailing child. */\nfunction handleEnterInContainerChild(\n\tcontext: PluginContext,\n\tctx: ListContext,\n\tchild: BlockNode,\n): boolean {\n\tif (!isEmptyParagraph(child)) return false;\n\tif (ctx.childIndex !== ctx.childCount - 1) return false;\n\n\tconst location: ListItemLocation | undefined = locateListItem(ctx.state, ctx.item.id);\n\tif (!location) return false;\n\n\tconst builder = ctx.state.transaction('input');\n\n\tif (ctx.childCount === 1) {\n\t\t// A lone empty child: the item has no content left — dissolve it and\n\t\t// keep the paragraph (same ID, so the caret stays put).\n\t\tdissolveListItem(builder, location);\n\t\tbuilder.setSelection(ctx.state.selection);\n\t\tcontext.dispatch(builder.build());\n\t\treturn true;\n\t}\n\n\t// Drop the empty trailing child and continue the list with a fresh item.\n\tconst listType = isNodeOfType(ctx.item, 'list_item') ? ctx.item.attrs.listType : 'bullet';\n\tconst indent: number = isNodeOfType(ctx.item, 'list_item') ? ctx.item.attrs.indent : 0;\n\tconst newItemId = generateBlockId();\n\tconst newItem: BlockNode = createBlockNode(\n\t\tnodeType('list_item'),\n\t\t[createTextNode('')],\n\t\tnewItemId,\n\t\tbuildListItemAttrs(listType, indent),\n\t);\n\n\tbuilder\n\t\t.removeNode([...location.parentPath, ctx.item.id], ctx.childIndex)\n\t\t.insertNode(location.parentPath, location.index + 1, newItem)\n\t\t.setSelection(createCollapsedSelection(newItemId, 0));\n\tcontext.dispatch(builder.build());\n\treturn true;\n}\n\n// --- Backspace Handler ---\n\n/**\n * Handles Backspace at the start of a list item.\n * Leaf items convert back to a paragraph. Container items dissolve into\n * their block children when the caret sits at the very start of the first\n * child (the un-list gesture); later children fall through to the default\n * sibling merge.\n */\nfunction handleBackspace(context: PluginContext): boolean {\n\treturn withListContext(context, (ctx) => {\n\t\tif (ctx.offset !== 0) return false;\n\n\t\tif (ctx.child) {\n\t\t\tif (ctx.childIndex !== 0) return false;\n\t\t\tconst location: ListItemLocation | undefined = locateListItem(ctx.state, ctx.item.id);\n\t\t\tif (!location) return false;\n\t\t\tconst builder = ctx.state.transaction('input');\n\t\t\tdissolveListItem(builder, location);\n\t\t\tbuilder.setSelection(ctx.state.selection);\n\t\t\tcontext.dispatch(builder.build());\n\t\t\treturn true;\n\t\t}\n\n\t\tconst tr = ctx.state\n\t\t\t.transaction('input')\n\t\t\t.setBlockType(ctx.blockId, nodeType('paragraph'))\n\t\t\t.setSelection(ctx.state.selection)\n\t\t\t.build();\n\t\tcontext.dispatch(tr);\n\t\treturn true;\n\t});\n}\n","/**\n * Locale interface and default English locale for the ListPlugin.\n */\n\nimport { type LocaleModuleMap, loadLocaleModule } from '../shared/LocaleLoader.js';\n\n// --- Locale Interface ---\n\nexport interface ListLocale {\n\treadonly bulletList: string;\n\treadonly numberedList: string;\n\treadonly checklist: string;\n\t/** Accessible name for the checklist item's checkbox marker (screen readers). */\n\treadonly checkboxLabel: string;\n\t/** Announced when a checklist item is toggled on. */\n\treadonly checkedAnnouncement: string;\n\t/** Announced when a checklist item is toggled off. */\n\treadonly uncheckedAnnouncement: string;\n}\n\n// --- Default English Locale ---\n\nexport const LIST_LOCALE_EN: ListLocale = {\n\tbulletList: 'Bullet List',\n\tnumberedList: 'Numbered List',\n\tchecklist: 'Checklist',\n\tcheckboxLabel: 'To-do item',\n\tcheckedAnnouncement: 'Checked',\n\tuncheckedAnnouncement: 'Unchecked',\n};\n\n// --- Lazy Locale Loader ---\n\nconst localeModules: LocaleModuleMap<ListLocale> = import.meta.glob<{\n\tdefault: ListLocale;\n}>('./locales/*.ts', { eager: false });\n\nexport async function loadListLocale(lang: string): Promise<ListLocale> {\n\treturn loadLocaleModule(localeModules, lang, LIST_LOCALE_EN);\n}\n","/**\n * Accessible checkbox marker for checklist items.\n *\n * The marker is a real `role=\"checkbox\"` element so assistive technology can\n * announce the item's checked state (WCAG 4.1.2 Name, Role, Value). It is\n * rendered `contenteditable=\"false\"` and flagged `data-widget` so the selection\n * layer treats it as zero-width view chrome, never as document content or a caret\n * position. The visible checkbox glyph is drawn in CSS.\n */\n\n/** CSS class identifying the checklist checkbox marker element. */\nexport const CHECKLIST_MARKER_CLASS = 'notectl-checklist-marker';\n\n/** Creates the accessible checkbox marker for a checklist item. */\nexport function createChecklistMarker(checked: boolean, label: string): HTMLElement {\n\tconst marker: HTMLElement = document.createElement('span');\n\tmarker.className = CHECKLIST_MARKER_CLASS;\n\tmarker.setAttribute('role', 'checkbox');\n\tmarker.setAttribute('aria-checked', String(checked));\n\tmarker.setAttribute('aria-label', label);\n\tmarker.setAttribute('contenteditable', 'false');\n\tmarker.setAttribute('data-widget', 'true');\n\treturn marker;\n}\n","/**\n * Toolbar item registration for list block types.\n * Registers bullet, ordered, and checklist toolbar buttons with active-state detection.\n */\n\nimport { isTextSelection, selectionRange } from '../../model/Selection.js';\nimport type { EditorState } from '../../state/EditorState.js';\nimport type { PluginContext } from '../Plugin.js';\nimport { allBlocksMatchListType } from './ListCommands.js';\nimport type { ListTypeDefinition } from './ListDefinitions.js';\nimport { resolveListItem } from './ListItemContext.js';\nimport type { ListLocale } from './ListLocale.js';\nimport type { ListType } from './ListPlugin.js';\n\n/** Registers toolbar items for each enabled list type. */\nexport function registerListToolbarItems(\n\tcontext: PluginContext,\n\tenabledTypes: readonly ListTypeDefinition[],\n\tlocale: ListLocale,\n): void {\n\tfor (const def of enabledTypes) {\n\t\tcontext.registerToolbarItem({\n\t\t\tid: `list-${def.type}`,\n\t\t\tgroup: 'block',\n\t\t\ticon: def.icon,\n\t\t\tlabel: getListLabel(def.type, locale),\n\t\t\tcommand: `toggleList:${def.type}`,\n\t\t\tisActive: (state) => isListActive(state, def.type),\n\t\t});\n\t}\n}\n\n// --- Helpers ---\n\nfunction getListLabel(type: ListType, locale: ListLocale): string {\n\tconst labels: Record<ListType, string> = {\n\t\tbullet: locale.bulletList,\n\t\tordered: locale.numberedList,\n\t\tchecklist: locale.checklist,\n\t};\n\treturn labels[type];\n}\n\nfunction isListActive(state: EditorState, listType: ListType): boolean {\n\tif (!isTextSelection(state.selection)) return false;\n\n\tif (state.selection.anchor.blockId !== state.selection.head.blockId) {\n\t\tconst range = selectionRange(state.selection, state.getBlockOrder());\n\t\treturn allBlocksMatchListType(state, range, listType);\n\t}\n\n\t// Children of container items resolve to their owning item (#194).\n\tconst block = resolveListItem(state, state.selection.anchor.blockId);\n\treturn block?.type === 'list_item' && block.attrs?.listType === listType;\n}\n","/**\n * ListPlugin: registers ordered, unordered, and checklist block types\n * with NodeSpecs, toggle commands, indent/outdent (Tab/Shift-Tab),\n * input rules, and toolbar buttons.\n *\n * This file is a thin orchestrator — command logic, input rules, keyboard\n * handlers, and toolbar rendering are delegated to dedicated modules.\n *\n * Sibling structure is modeled flat: every item carries a `listType` and an\n * `indent` attribute, so nesting between items needs no deep tree. Item\n * content is hybrid (#194): a single-paragraph item is a leaf with inline\n * children, while a multi-block item (second paragraph, code block, quote,\n * heading) is a container whose children are blocks.\n */\n\nimport { LIST_CSS, LIST_MARKER_WIDTH } from '../../editor/styles/list.js';\nimport { blockId } from '../../model/TypeBrands.js';\nimport { setStyleProperty } from '../../style/StyleRuntime.js';\nimport { createBlockElement } from '../../view/DomUtils.js';\nimport type { Plugin, PluginContext } from '../Plugin.js';\nimport { resolveLocale } from '../shared/PluginHelpers.js';\nimport { registerListCommands, toggleChecked } from './ListCommands.js';\nimport { LIST_TYPE_DEFINITIONS, type ListTypeDefinition } from './ListDefinitions.js';\nimport { registerListInputRules } from './ListInputRules.js';\nimport { registerListKeymaps } from './ListKeyboardHandlers.js';\nimport { LIST_LOCALE_EN, type ListLocale, loadListLocale } from './ListLocale.js';\nimport { CHECKLIST_MARKER_CLASS, createChecklistMarker } from './ListMarker.js';\nimport { registerListToolbarItems } from './ListToolbarItems.js';\n\n// --- Attribute Registry Augmentation ---\n\nexport type ListType = 'bullet' | 'ordered' | 'checklist';\n\ndeclare module '../../model/AttrRegistry.js' {\n\tinterface NodeAttrRegistry {\n\t\tlist_item: { listType: ListType; indent: number; checked: boolean };\n\t}\n}\n\n// --- Configuration ---\n\nexport interface ListConfig {\n\t/** Which list types to enable. Defaults to all. */\n\treadonly types: readonly ListType[];\n\t/** Maximum indent depth. Defaults to 4. */\n\treadonly maxIndent: number;\n\t/** Live Markdown shortcuts: `- `/`* ` (bullet), `1. ` (ordered), `[ ] ` (checklist). Default true. */\n\treadonly inputRule?: boolean;\n\t/**\n\t * When true, checklist checkboxes remain interactive even in read-only mode.\n\t * Defaults to false (checkboxes are fully read-only).\n\t */\n\treadonly interactiveCheckboxes?: boolean;\n\treadonly locale?: ListLocale;\n}\n\nconst DEFAULT_CONFIG: ListConfig = {\n\ttypes: ['bullet', 'ordered', 'checklist'],\n\tmaxIndent: 4,\n};\n\n// --- Plugin ---\n\nexport class ListPlugin implements Plugin {\n\treadonly id = 'list';\n\treadonly name = 'List';\n\treadonly priority = 35;\n\n\tprivate readonly config: ListConfig;\n\tprivate locale!: ListLocale;\n\tprivate context: PluginContext | null = null;\n\tprivate checkboxClickHandler: ((e: MouseEvent) => void) | null = null;\n\n\tconstructor(config?: Partial<ListConfig>) {\n\t\tthis.config = { ...DEFAULT_CONFIG, ...config };\n\t}\n\n\tasync init(context: PluginContext): Promise<void> {\n\t\tthis.context = context;\n\t\tthis.locale = await resolveLocale(context, this.config.locale, LIST_LOCALE_EN, loadListLocale);\n\t\tconst enabledTypes = this.getEnabledTypes();\n\n\t\tcontext.registerStyleSheet(LIST_CSS);\n\t\tthis.registerNodeSpec(context);\n\t\tregisterListCommands(context, this.config, enabledTypes, this.locale);\n\t\tregisterListKeymaps(context);\n\t\tif (this.config.inputRule !== false) registerListInputRules(context, enabledTypes);\n\t\tregisterListToolbarItems(context, enabledTypes, this.locale);\n\t\tthis.registerCheckboxClickHandler(context);\n\t}\n\n\tdestroy(): void {\n\t\tif (this.checkboxClickHandler && this.context) {\n\t\t\tconst container: HTMLElement = this.context.getContainer();\n\t\t\tcontainer.removeEventListener('mousedown', this.checkboxClickHandler);\n\t\t}\n\t\tthis.checkboxClickHandler = null;\n\t\tthis.context = null;\n\t}\n\n\tprivate registerNodeSpec(context: PluginContext): void {\n\t\tconst checkboxLabel: string = this.locale.checkboxLabel;\n\n\t\tcontext.registerNodeSpec({\n\t\t\ttype: 'list_item',\n\t\t\tgroup: 'block',\n\t\t\t// Hybrid content model (#194): the common single-paragraph item is a\n\t\t\t// leaf (inline text children); multi-block items are containers with\n\t\t\t// block children. Sibling nesting stays flat-with-indent, so list_item\n\t\t\t// itself is deliberately not an allowed child.\n\t\t\tcontent: {\n\t\t\t\tallow: ['text', 'paragraph', 'heading', 'code_block', 'blockquote', 'horizontal_rule'],\n\t\t\t},\n\t\t\tattrs: {\n\t\t\t\tlistType: { default: 'bullet' },\n\t\t\t\tindent: { default: 0 },\n\t\t\t\tchecked: { default: false },\n\t\t\t},\n\t\t\ttoDOM(node) {\n\t\t\t\tconst listType = node.attrs?.listType ?? 'bullet';\n\t\t\t\tconst indent = node.attrs?.indent ?? 0;\n\t\t\t\tconst checked = node.attrs?.checked ?? false;\n\n\t\t\t\tconst li = createBlockElement('li', node.id);\n\t\t\t\tli.setAttribute('role', 'listitem');\n\t\t\t\tli.setAttribute('data-list-type', listType);\n\t\t\t\tli.setAttribute('data-indent', String(indent));\n\t\t\t\tli.className = `notectl-list-item notectl-list-item--${listType}`;\n\n\t\t\t\tif (indent > 0) {\n\t\t\t\t\tsetStyleProperty(li, 'marginLeft', `${indent * LIST_MARKER_WIDTH}px`);\n\t\t\t\t}\n\n\t\t\t\tif (listType === 'checklist') {\n\t\t\t\t\t// `data-checked` drives the CSS glyph; the checked state is exposed to\n\t\t\t\t\t// assistive technology via the marker's own role=\"checkbox\", not via an\n\t\t\t\t\t// (invalid) aria-checked on the listitem. The marker is the first child\n\t\t\t\t\t// so reconciled inline content is appended after it.\n\t\t\t\t\tli.setAttribute('data-checked', String(checked));\n\t\t\t\t\tli.appendChild(createChecklistMarker(checked, checkboxLabel));\n\t\t\t\t}\n\t\t\t\tli.setAttribute('aria-level', String(indent + 1));\n\n\t\t\t\treturn li;\n\t\t\t},\n\t\t\twrapper(node) {\n\t\t\t\tconst listType = node.attrs?.listType ?? 'bullet';\n\t\t\t\tconst tag = listType === 'ordered' ? 'ol' : 'ul';\n\t\t\t\treturn {\n\t\t\t\t\ttag,\n\t\t\t\t\tkey: `list-${listType}`,\n\t\t\t\t\tclassName: `notectl-list notectl-list--${listType}`,\n\t\t\t\t\tattrs: { role: 'list' },\n\t\t\t\t};\n\t\t\t},\n\t\t\ttoHTML(node, content) {\n\t\t\t\tconst listType: string = (node.attrs?.listType as string) ?? 'bullet';\n\t\t\t\tconst checked: boolean = (node.attrs?.checked as boolean) ?? false;\n\n\t\t\t\tif (listType === 'checklist') {\n\t\t\t\t\tconst checkedAttr: string = checked ? ' checked' : '';\n\t\t\t\t\tconst ariaChecked: string = String(checked);\n\t\t\t\t\treturn (\n\t\t\t\t\t\t`<li role=\"checkbox\" aria-checked=\"${ariaChecked}\">` +\n\t\t\t\t\t\t`<input type=\"checkbox\" disabled${checkedAttr}>` +\n\t\t\t\t\t\t`${content || '<br>'}</li>`\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn `<li>${content || '<br>'}</li>`;\n\t\t\t},\n\t\t\tparseHTML: [{ tag: 'li' }],\n\t\t\tsanitize: {\n\t\t\t\ttags: ['ul', 'ol', 'li', 'input'],\n\t\t\t\tattrs: ['type', 'disabled', 'checked', 'role', 'aria-checked'],\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate registerCheckboxClickHandler(context: PluginContext): void {\n\t\tif (!this.config.types.includes('checklist')) return;\n\n\t\tthis.checkboxClickHandler = (e: MouseEvent) => {\n\t\t\tif (context.isReadOnly() && !this.config.interactiveCheckboxes) return;\n\n\t\t\tconst target: EventTarget | null = e.target;\n\t\t\tif (!(target instanceof HTMLElement)) return;\n\n\t\t\t// Toggle only when the checkbox marker itself is clicked. The marker is a\n\t\t\t// real element, so this is precise — no geometry/RTL math needed.\n\t\t\tconst marker: Element | null = target.closest(`.${CHECKLIST_MARKER_CLASS}`);\n\t\t\tif (!marker) return;\n\n\t\t\tconst li: Element | null = marker.closest('.notectl-list-item--checklist');\n\t\t\tif (!li) return;\n\n\t\t\te.preventDefault();\n\n\t\t\tconst bid: string | null = li.getAttribute('data-block-id');\n\t\t\tif (!bid) return;\n\n\t\t\ttoggleChecked(context, {\n\t\t\t\tinteractiveCheckboxes: this.config.interactiveCheckboxes,\n\t\t\t\ttargetId: blockId(bid),\n\t\t\t\tlocale: this.locale,\n\t\t\t});\n\t\t};\n\n\t\tconst container: HTMLElement = context.getContainer();\n\t\tcontainer.addEventListener('mousedown', this.checkboxClickHandler);\n\t}\n\n\tprivate getEnabledTypes(): readonly ListTypeDefinition[] {\n\t\treturn LIST_TYPE_DEFINITIONS.filter((def) => this.config.types.includes(def.type));\n\t}\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{n as t,s as e}from"./HTMLUtils-Bhg3_P8B.mjs";import{t as n}from"./SchemaRegistry-CkBN-1yW.mjs";import{l as r,n as i,o as s,r as o}from"./TableDimensions-BBhjHNjQ.mjs";var a=/^\s*\|?\s*:?-+:?\s*(\|\s*:?-+:?\s*)*\|?\s*$/;function c(t){let e=t.trim();e.startsWith("|")&&(e=e.slice(1)),e.endsWith("|")&&!e.endsWith("\\|")&&(e=e.slice(0,-1));const n=[];let r="";for(let i=0;i<e.length;i++){const t=e[i]??"";"\\"!==t||"|"!==e[i+1]?"|"!==t?r+=t:(n.push(r.trim()),r=""):(r+="|",i++)}return n.push(r.trim()),n}function l(t){const e=t.trim(),n=e.startsWith(":"),r=e.endsWith(":");return n&&r?"center":r?"end":n?"start":null}function u(t,e,n){const r=t[e]??"",i=t[e+1]??"";if(!r.includes("|"))return null;if(!a.test(i))return null;const s=c(r),o=c(i).map(l);if(o.length!==s.length)return null;const u=[];let g=e+2;for(;g<t.length;){const e=t[g]??"";if(""===e.trim())break;if(!e.includes("|")&&(!n||n(e)))break;u.push(c(e)),g++}return{aligns:o,header:s,rows:u,linesConsumed:g-e}}var g=/[!-/:-@[-`{-~]/,h=/&(#[xX][0-9a-fA-F]{1,6}|#[0-9]{1,7}|[a-zA-Z][a-zA-Z0-9]{1,31});/y,f={amp:"&",lt:"<",gt:">",quot:'"',apos:"'",nbsp:" ",copy:"©",reg:"®",hellip:"…",mdash:"—",ndash:"–"};function p(t){if("#"===t[0]){const e="x"===t[1]||"X"===t[1],n=Number.parseInt(t.slice(e?2:1),e?16:10);if(!Number.isFinite(n)||n<0||n>1114111)return`&${t};`;if(0===n)return"�";try{const t=String.fromCodePoint(n);return"\n"===t||"\r"===t?" ":t}catch{return"�"}}return f[t]??function(t){if("undefined"==typeof document)return null;const e=m.get(t);if(void 0!==e)return e;const n=document.createElement("div");n.innerHTML=`&${t};`;const r=n.textContent??"",i=""!==r&&r!==`&${t};`?r:null;return m.set(t,i),i}(t)??`&${t};`}function d(t,e){return h.lastIndex=e,h.exec(t)}var m=/* @__PURE__ */new Map;function b(t){let e="",n=0;for(;n<t.length;){const r=t[n]??"";if("\\"===r&&g.test(t[n+1]??""))e+=t[n+1],n+=2;else{if("&"===r){const r=d(t,n);if(r?.[1]){e+=p(r[1]),n+=r[0].length;continue}}e+=r,n++}}return e}function $(t){let e="",n=0;for(;n<t.length;){const r=t[n]??"";if("&"===r){const r=d(t,n);if(r?.[1]){e+=p(r[1]),n+=r[0].length;continue}}e+=r,n++}return e}var y,k=new Set(["address","article","aside","blockquote","details","div","dl","dd","dt","figure","figcaption","footer","form","h1","h2","h3","h4","h5","h6","header","hr","iframe","main","nav","ol","p","pre","section","table","tbody","td","tfoot","th","thead","tr","ul","video"]),M=/^ {0,3}(#{1,6})(?:[ \t]+(.*?))?(?:[ \t]+#+)?[ \t]*$/,T=/^ {0,3}(`{3,}|~{3,})[ \t]*(.*)$/,S=/^ {0,3}([-*_])[ \t]*(?:\1[ \t]*){2,}$/,x=/^ {0,3}>[ ]?/,L=/^([ \t]*)([-*+])(?:([ \t]+)(.*))?$/,H=/^([ \t]*)(\d{1,9})([.)])(?:([ \t]+)(.*))?$/,w=/^\[([ xX])\][ \t]+(.*)$/,N=/^ {0,3}=+[ \t]*$/,z=/^ {0,3}-+[ \t]*$/,A=/^ {0,3}<(\/?)([a-zA-Z][a-zA-Z0-9-]*)|^ {0,3}<!--/;function v(t){return""===t.trim()}function D(t){const e=t.match(T);return e?"`"===(e[1]??"")[0]&&(e[2]??"").includes("`")?null:e:null}function O(t,e=!0,n=[]){return _(t.replace(/\r\n?/g,"\n").replace(/\n$/,"").split("\n"),e,n)}function _(t,e,n,r=0){const i=[];let s=0;for(;s<t.length;){const o=t[s]??"";if(v(o)){s++;continue}const a=P(n,t,s,i);if(a>0){s+=a;continue}if(e){const e=u(t,s,J);if(e){i.push({type:"table",aligns:e.aligns,header:e.header,rows:e.rows}),s+=e.linesConsumed;continue}}const c=D(o);if(c){s=C(t,s,c,i);continue}const l=o.match(M);if(l){const t=(l[2]??"").trim(),e=/^#+$/.test(t)?"":t;i.push({type:"heading",level:(l[1]??"#").length,text:e}),s++;continue}if(S.test(o)){i.push({type:"hr"}),s++;continue}if(x.test(o)){if(r>=32){s=K(t,s,i);continue}s=R(t,s,i,e,n,r);continue}const g=r<32?X(o):null;s=g?V(t,s,g,i,e,n,r):j(o)?I(t,s,i):U(o)?G(t,s,i):K(t,s,i)}return i}function C(t,e,n,r){const i=n[1]??"```",s=i[0]??"`",o=b((n[2]??"").trim().split(/\s+/)[0]??""),a=new RegExp(`^ {0,3}\\${s}{${i.length},}[ \\t]*$`),c=t[e]??"",l=c.length-c.trimStart().length,u=[];let g=e+1;for(;g<t.length;){const e=t[g]??"";if(a.test(e)){g++;break}u.push(q(e,l)),g++}return r.push({type:"code_block",language:o,code:u.join("\n")}),g}function q(t,e){let n=0;for(;n<e&&" "===t[n];)n++;return t.slice(n)}function j(t){return W(t)>=4}function W(t){let e=0;for(const n of t)if(" "===n)e++;else{if("\t"!==n)break;e+=4-e%4}return e}function E(t,e){let n=0,r=0;for(;r<t.length;){const e=t[r]??"";if(" "===e)n++;else{if("\t"!==e)break;n+=4-n%4}r++}return" ".repeat(Math.max(0,n-e))+t.slice(r)}function F(t,e){let n=0,r=0;for(;r<t.length&&n<e;){const i=t[r]??"";if(" "===i)n++,r++;else{if("\t"!==i)break;{const i=n+4-n%4;if(i>e)return" ".repeat(i-e)+t.slice(r+1);n=i,r++}}}return t.slice(r)}function I(t,e,n){const r=[],i=[];let s=e;for(;s<t.length;){const e=t[s]??"";if(v(e))i.push(F(e,4)),s++;else{if(W(e)<4)break;for(;i.length>0;)r.push(i.shift()??"");r.push(F(e,4)),s++}}return n.push({type:"code_block",language:"",code:r.join("\n")}),s-i.length}function P(t,e,n,r){for(const i of t){const t=i.matchBlock?.(e,n);if(t&&t.linesConsumed>0)return r.push({type:"extension_block",nodeType:t.type,attrs:t.attrs}),t.linesConsumed}return 0}function R(t,e,n,r,i,s){const o=[];let a=e,c=!1;for(;a<t.length;){const e=t[a]??"";if(x.test(e)){const t=e.replace(x,"");o.push(t),c=Z(t),a++;continue}if(!c||v(e)||J(e)||r&&u(t,a,J))break;o.push(e),a++}return n.push({type:"blockquote",children:_(o,r,i,s+1)}),a}function Z(t){let e=t;for(;;){if(x.test(e)){e=e.replace(x,"");continue}const t=X(e);if(!t||""===t.firstText)break;e=t.firstText}return""!==e.trim()&&!J(e)&&W(e)<4}function X(t){const e=t.match(L),n=e?null:t.match(H),r=e??n;if(!r)return null;const i=W(r[1]??"");if(i>3)return null;const s=i+((e?r[2]:`${r[2]}${r[3]}`)??"-").length,o=function(t,e){let n=t;for(const r of e)if(" "===r)n++;else{if("\t"!==r)break;n+=4-n%4}return n-t}(s,(e?r[3]:r[4])??""),a=(e?r[4]:r[5])??"",c=n?Number.parseInt(r[2]??"1",10):1;let l,u;""===a.trim()?(l=s+1,u=""):o>=5?(l=s+1,u=" ".repeat(o-1)+a):(l=s+o,u=a);const g=u.match(w);return g?{listType:"checklist",checked:"x"===(g[1]??" ").toLowerCase(),contentColumn:l,firstText:g[2]??"",startNumber:c}:{listType:n?"ordered":"bullet",checked:!1,contentColumn:l,firstText:u,startNumber:c}}function V(t,e,n,r,i,s,o){const a=[],c=function(){let t=null;return(e,n)=>{if(t)return t.test(e)&&(t=null),!1;const r=D(e);if(r){const e=r[1]??"```",n=e[0]??"`";return t=new RegExp(`^ {0,3}\\${n}{${e.length},}[ \\t]*$`),!1}return!v(e)&&(x.test(e)||X(e)?Z(e):W(e)>=4?n:!J(e))}}();let l=n.firstText,g=""!==l&&c(l,!1),h=0,f=e+1;for(;f<t.length;){const e=t[f]??"";if(v(e)){if(""===l&&0===a.length)break;h++,g=!1,f++;continue}if(W(e)>=n.contentColumn){for(;h>0;)a.push(""),h--;const t=E(e,n.contentColumn);a.push(t),g=c(t,g),f++;continue}if(X(e))break;if(!g)break;if(J(e))break;if(i&&u(t,f,J))break;const r=e.trimStart(),s=a[a.length-1];void 0!==s?a[a.length-1]=`${s}\n${r}`:l=""===l?r:`${l}\n${r}`,g=c(r,g),f++}return function(t,e,n,r,i,s,o){const a=""===e?[...n]:[e,...n],c=0===a.length?[]:_(a,i,s,o+1),l=[],u=[];for(const h of c)"list_item"===h.type?l.push({...h,indent:h.indent+1}):u.push(h);const g=u[0];1===u.length&&"paragraph"===g?.type?r.push(B(t,g.text)):0===u.length?r.push(B(t,"")):r.push(B(t,"",u)),r.push(...l)}(n,l,a,r,i,s,o),f}function B(t,e,n){const r={type:"list_item",listType:t.listType,indent:0,checked:t.checked,text:e};return n?{...r,children:n}:r}function U(t){const e=t.match(A);if(!e)return!1;if(t.trimStart().startsWith("\x3c!--"))return!0;const n=(e[2]??"").toLowerCase();return k.has(n)}function G(t,e,n){const r=[];let i=e;for(;i<t.length;){const e=t[i]??"";if(v(e))break;r.push(e),i++}return n.push({type:"html",html:r.join("\n")}),i}function J(t){return!!(v(t)||M.test(t)||D(t)||S.test(t)||x.test(t)||function(t){const e=X(t);return!!e&&""!==e.firstText.trim()&&("ordered"!==e.listType||1===e.startNumber)}(t)||U(t))}function K(t,e,n){const r=[t[e]??""];let i=e+1;for(;i<t.length;){const e=t[i]??"";if(N.test(e))return n.push({type:"heading",level:1,text:Y(r)}),i+1;if(z.test(e))return n.push({type:"heading",level:2,text:Y(r)}),i+1;if(J(e))break;r.push(e),i++}return n.push({type:"paragraph",text:Q(r)}),i}function Q(t){return t.map((e,n)=>n===t.length-1?e.trim():e.trimStart()).join("\n")}function Y(t){return t.map(t=>t.trim()).join(" ").trim()}function tt(a){return a||(y??=function(){const a=new n;return function(e){e.registerNodeSpec({type:"paragraph",toDOM:et,toHTML:(t,e)=>`<p>${e||"<br>"}</p>`,parseHTML:[{tag:"p"},{tag:"div",priority:10}],sanitize:{tags:["p"]}}),e.registerNodeSpec({type:"heading",toDOM:et,toHTML(t,e){const n=t.attrs?.level,r="number"==typeof n&&Number.isFinite(n)?Math.max(1,Math.min(6,Math.floor(n))):1;return`<h${r}>${e||"<br>"}</h${r}>`},parseHTML:[1,2,3,4,5,6].map(t=>({tag:`h${t}`,getAttrs:()=>({level:t})})),sanitize:{tags:["h1","h2","h3","h4","h5","h6"]}}),e.registerNodeSpec({type:"list_item",toDOM:et,toHTML(t,e){if("checklist"!==t.attrs?.listType)return`<li>${e||"<br>"}</li>`;const n=!0===t.attrs.checked;return`<li role="checkbox" aria-checked="${String(n)}"><input type="checkbox" disabled${n?" checked":""}>${e||"<br>"}</li>`},parseHTML:[{tag:"li"}],sanitize:{tags:["ul","ol","li","input"],attrs:["type","disabled","checked","role","aria-checked"]}}),e.registerNodeSpec({type:"blockquote",toDOM:et,toHTML:(t,e)=>`<blockquote>${e||"<br>"}</blockquote>`,parseHTML:[{tag:"blockquote"}],sanitize:{tags:["blockquote"]}}),e.registerNodeSpec({type:"code_block",toDOM:et,toHTML(e,n){const r=String(e.attrs?.language??"");return`<pre><code${r?` class="language-${t(r)}"`:""}>${n}</code></pre>`},parseHTML:[{tag:"pre",getAttrs:t=>({language:t.querySelector("code")?.className.match(/(?:^|\s)language-(\S+)/)?.[1]??""})}],sanitize:{tags:["pre","code"],attrs:["class"]}}),e.registerNodeSpec({type:"horizontal_rule",isVoid:!0,toDOM:et,toHTML:()=>"<hr>",parseHTML:[{tag:"hr"}],sanitize:{tags:["hr"]}}),e.registerNodeSpec({type:"image",isVoid:!0,attrs:{src:{default:""},alt:{default:""},title:{default:""},align:{default:"center"}},toDOM:et,toHTML(e){const n=t(String(e.attrs?.src??"")),r=t(String(e.attrs?.alt??"")),i=String(e.attrs?.title??""),s=(t,e)=>"number"==typeof e&&Number.isFinite(e)&&e>0?` ${t}="${String(e)}"`:"";return`<figure><img src="${n}" alt="${r}"${i?` title="${t(i)}"`:""}${s("width",e.attrs?.width)}${s("height",e.attrs?.height)}></figure>`},parseHTML:[{tag:"figure",getAttrs(t){const e=t.querySelector("img");return!!e&&nt(e)}},{tag:"img",getAttrs:t=>nt(t)}],sanitize:{tags:["figure","img"],attrs:["src","alt","title","width","height"]}}),e.registerNodeSpec({type:"table",toDOM:et,toHTML(t,e,n){const o=s(t.attrs?.columnWidthsPx),a=o?`<colgroup>${o.map(t=>`<col${r(i,"width",t,n)}>`).join("")}</colgroup>`:"";return`<table${o?function(t,e){const n=t.reduce((t,e)=>t+(e??60),0),r=t.every(t=>null!==t)?`width: ${String(n)}px; min-width: ${String(n)}px; table-layout: fixed`:`width: 100%; min-width: ${String(n)}px; table-layout: fixed`;return e?.styleAttr(r)??` style="${r}"`}(o,n):""}>${a}<tbody>${e}</tbody></table>`},sanitize:{tags:["table","colgroup","col","thead","tbody","tfoot"],attrs:["span","width",i]}}),e.registerNodeSpec({type:"table_row",toDOM:et,toHTML:(t,e,n)=>`<tr${r(o,"height",t.attrs?.minHeightPx,n)}>${e}</tr>`,sanitize:{tags:["tr"],attrs:["height",o]}}),e.registerNodeSpec({type:"table_cell",toDOM:et,toHTML(t,e){const n=(t,e)=>"number"==typeof e&&Number.isInteger(e)&&e>1?` ${t}="${String(e)}"`:"";return`<td${n("colspan",t.attrs?.colspan)}${n("rowspan",t.attrs?.rowspan)}>${e}</td>`},sanitize:{tags:["td","th"],attrs:["colspan","rowspan"]}})}(a),function(n){for(const t of[{type:"bold",rank:0,tag:"strong",parseTags:["strong","b"]},{type:"italic",rank:1,tag:"em",parseTags:["em","i"]},{type:"underline",rank:2,tag:"u",parseTags:["u"]},{type:"code",rank:3,tag:"code",parseTags:["code"]},{type:"strikethrough",rank:4,tag:"s",parseTags:["s","strike","del"]}])n.registerMarkSpec({type:t.type,rank:t.rank,toDOM:et,toHTMLString:(e,n)=>`<${t.tag}>${n}</${t.tag}>`,parseHTML:t.parseTags.map(t=>({tag:t,getAttrs:"code"===t?t=>"PRE"!==t.parentElement?.tagName&&{}:void 0})),sanitize:{tags:t.parseTags}});n.registerMarkSpec({type:"link",rank:10,toDOM:et,toHTMLString(n,r){const i=t(e(String(n.attrs?.href??""))),s=String(n.attrs?.title??"");return`<a href="${i}"${s?` title="${t(s)}"`:""}>${r}</a>`},parseHTML:[{tag:"a",getAttrs(t){const n=e(t.getAttribute("href")??""),r=t.getAttribute("title");return r?{href:n,title:r}:{href:n}}}],sanitize:{tags:["a"],attrs:["href","title"]}})}(a),function(e){e.registerInlineNodeSpec({type:"hard_break",toDOM:et,toHTMLString:()=>"<br>",parseHTML:[{tag:"br"}],sanitize:{tags:["br"]}}),e.registerInlineNodeSpec({type:"image_inline",toDOM:et,toHTMLString(e){const n=t(String(e.attrs.src??"")),r=t(String(e.attrs.alt??"")),i=String(e.attrs.title??"");return`<img src="${n}" alt="${r}"${i?` title="${t(i)}"`:""}>`},parseHTML:[{tag:"img",getAttrs:t=>rt(t)}],sanitize:{tags:["img"],attrs:["src","alt","title"]}})}(a),a}(),y)}function et(){throw new Error("The Markdown HTML registry cannot render editor DOM.")}function nt(t){const e={...rt(t),align:"center"};for(const n of["width","height"]){const r=Number.parseFloat(t.getAttribute(n)??"");Number.isFinite(r)&&r>0&&(e[n]=r)}return e}function rt(t){const e={src:t.getAttribute("src")??"",alt:t.getAttribute("alt")??""},n=t.getAttribute("title");return n&&(e.title=n),e}export{z as a,O as c,b as d,d as f,N as i,$ as l,M as n,S as o,T as r,D as s,tt as t,p as u};
2
- //# sourceMappingURL=MarkdownHTMLRegistry-CKEx7LkR.mjs.map
1
+ import{n as t,s as e}from"./HTMLUtils-Bhg3_P8B.mjs";import{l as n,n as r,o as i,r as s}from"./TableDimensions-BBhjHNjQ.mjs";import{t as o}from"./SchemaRegistry-CkBN-1yW.mjs";var a=/^\s*\|?\s*:?-+:?\s*(\|\s*:?-+:?\s*)*\|?\s*$/;function c(t){let e=t.trim();e.startsWith("|")&&(e=e.slice(1)),e.endsWith("|")&&!e.endsWith("\\|")&&(e=e.slice(0,-1));const n=[];let r="";for(let i=0;i<e.length;i++){const t=e[i]??"";"\\"!==t||"|"!==e[i+1]?"|"!==t?r+=t:(n.push(r.trim()),r=""):(r+="|",i++)}return n.push(r.trim()),n}function l(t){const e=t.trim(),n=e.startsWith(":"),r=e.endsWith(":");return n&&r?"center":r?"end":n?"start":null}function u(t,e,n){const r=t[e]??"",i=t[e+1]??"";if(!r.includes("|"))return null;if(!a.test(i))return null;const s=c(r),o=c(i).map(l);if(o.length!==s.length)return null;const u=[];let g=e+2;for(;g<t.length;){const e=t[g]??"";if(""===e.trim())break;if(!e.includes("|")&&(!n||n(e)))break;u.push(c(e)),g++}return{aligns:o,header:s,rows:u,linesConsumed:g-e}}var g=/[!-/:-@[-`{-~]/,h=/&(#[xX][0-9a-fA-F]{1,6}|#[0-9]{1,7}|[a-zA-Z][a-zA-Z0-9]{1,31});/y,f={amp:"&",lt:"<",gt:">",quot:'"',apos:"'",nbsp:" ",copy:"©",reg:"®",hellip:"…",mdash:"—",ndash:"–"};function p(t){if("#"===t[0]){const e="x"===t[1]||"X"===t[1],n=Number.parseInt(t.slice(e?2:1),e?16:10);if(!Number.isFinite(n)||n<0||n>1114111)return`&${t};`;if(0===n)return"�";try{const t=String.fromCodePoint(n);return"\n"===t||"\r"===t?" ":t}catch{return"�"}}return f[t]??function(t){if("undefined"==typeof document)return null;const e=m.get(t);if(void 0!==e)return e;const n=document.createElement("div");n.innerHTML=`&${t};`;const r=n.textContent??"",i=""!==r&&r!==`&${t};`?r:null;return m.set(t,i),i}(t)??`&${t};`}function d(t,e){return h.lastIndex=e,h.exec(t)}var m=/* @__PURE__ */new Map;function b(t){let e="",n=0;for(;n<t.length;){const r=t[n]??"";if("\\"===r&&g.test(t[n+1]??""))e+=t[n+1],n+=2;else{if("&"===r){const r=d(t,n);if(r?.[1]){e+=p(r[1]),n+=r[0].length;continue}}e+=r,n++}}return e}function $(t){let e="",n=0;for(;n<t.length;){const r=t[n]??"";if("&"===r){const r=d(t,n);if(r?.[1]){e+=p(r[1]),n+=r[0].length;continue}}e+=r,n++}return e}var y,k=new Set(["address","article","aside","blockquote","details","div","dl","dd","dt","figure","figcaption","footer","form","h1","h2","h3","h4","h5","h6","header","hr","iframe","main","nav","ol","p","pre","section","table","tbody","td","tfoot","th","thead","tr","ul","video"]),M=/^ {0,3}(#{1,6})(?:[ \t]+(.*?))?(?:[ \t]+#+)?[ \t]*$/,T=/^ {0,3}(`{3,}|~{3,})[ \t]*(.*)$/,S=/^ {0,3}([-*_])[ \t]*(?:\1[ \t]*){2,}$/,x=/^ {0,3}>[ ]?/,L=/^([ \t]*)([-*+])(?:([ \t]+)(.*))?$/,H=/^([ \t]*)(\d{1,9})([.)])(?:([ \t]+)(.*))?$/,w=/^\[([ xX])\][ \t]+(.*)$/,N=/^ {0,3}=+[ \t]*$/,z=/^ {0,3}-+[ \t]*$/,A=/^ {0,3}<(\/?)([a-zA-Z][a-zA-Z0-9-]*)|^ {0,3}<!--/;function v(t){return""===t.trim()}function D(t){const e=t.match(T);return e?"`"===(e[1]??"")[0]&&(e[2]??"").includes("`")?null:e:null}function O(t,e=!0,n=[]){return _(t.replace(/\r\n?/g,"\n").replace(/\n$/,"").split("\n"),e,n)}function _(t,e,n,r=0){const i=[];let s=0;for(;s<t.length;){const o=t[s]??"";if(v(o)){s++;continue}const a=P(n,t,s,i);if(a>0){s+=a;continue}if(e){const e=u(t,s,J);if(e){i.push({type:"table",aligns:e.aligns,header:e.header,rows:e.rows}),s+=e.linesConsumed;continue}}const c=D(o);if(c){s=C(t,s,c,i);continue}const l=o.match(M);if(l){const t=(l[2]??"").trim(),e=/^#+$/.test(t)?"":t;i.push({type:"heading",level:(l[1]??"#").length,text:e}),s++;continue}if(S.test(o)){i.push({type:"hr"}),s++;continue}if(x.test(o)){if(r>=32){s=K(t,s,i);continue}s=R(t,s,i,e,n,r);continue}const g=r<32?X(o):null;s=g?V(t,s,g,i,e,n,r):j(o)?I(t,s,i):U(o)?G(t,s,i):K(t,s,i)}return i}function C(t,e,n,r){const i=n[1]??"```",s=i[0]??"`",o=b((n[2]??"").trim().split(/\s+/)[0]??""),a=new RegExp(`^ {0,3}\\${s}{${i.length},}[ \\t]*$`),c=t[e]??"",l=c.length-c.trimStart().length,u=[];let g=e+1;for(;g<t.length;){const e=t[g]??"";if(a.test(e)){g++;break}u.push(q(e,l)),g++}return r.push({type:"code_block",language:o,code:u.join("\n")}),g}function q(t,e){let n=0;for(;n<e&&" "===t[n];)n++;return t.slice(n)}function j(t){return W(t)>=4}function W(t){let e=0;for(const n of t)if(" "===n)e++;else{if("\t"!==n)break;e+=4-e%4}return e}function E(t,e){let n=0,r=0;for(;r<t.length;){const e=t[r]??"";if(" "===e)n++;else{if("\t"!==e)break;n+=4-n%4}r++}return" ".repeat(Math.max(0,n-e))+t.slice(r)}function F(t,e){let n=0,r=0;for(;r<t.length&&n<e;){const i=t[r]??"";if(" "===i)n++,r++;else{if("\t"!==i)break;{const i=n+4-n%4;if(i>e)return" ".repeat(i-e)+t.slice(r+1);n=i,r++}}}return t.slice(r)}function I(t,e,n){const r=[],i=[];let s=e;for(;s<t.length;){const e=t[s]??"";if(v(e))i.push(F(e,4)),s++;else{if(W(e)<4)break;for(;i.length>0;)r.push(i.shift()??"");r.push(F(e,4)),s++}}return n.push({type:"code_block",language:"",code:r.join("\n")}),s-i.length}function P(t,e,n,r){for(const i of t){const t=i.matchBlock?.(e,n);if(t&&t.linesConsumed>0)return r.push({type:"extension_block",nodeType:t.type,attrs:t.attrs}),t.linesConsumed}return 0}function R(t,e,n,r,i,s){const o=[];let a=e,c=!1;for(;a<t.length;){const e=t[a]??"";if(x.test(e)){const t=e.replace(x,"");o.push(t),c=Z(t),a++;continue}if(!c||v(e)||J(e)||r&&u(t,a,J))break;o.push(e),a++}return n.push({type:"blockquote",children:_(o,r,i,s+1)}),a}function Z(t){let e=t;for(;;){if(x.test(e)){e=e.replace(x,"");continue}const t=X(e);if(!t||""===t.firstText)break;e=t.firstText}return""!==e.trim()&&!J(e)&&W(e)<4}function X(t){const e=t.match(L),n=e?null:t.match(H),r=e??n;if(!r)return null;const i=W(r[1]??"");if(i>3)return null;const s=i+((e?r[2]:`${r[2]}${r[3]}`)??"-").length,o=function(t,e){let n=t;for(const r of e)if(" "===r)n++;else{if("\t"!==r)break;n+=4-n%4}return n-t}(s,(e?r[3]:r[4])??""),a=(e?r[4]:r[5])??"",c=n?Number.parseInt(r[2]??"1",10):1;let l,u;""===a.trim()?(l=s+1,u=""):o>=5?(l=s+1,u=" ".repeat(o-1)+a):(l=s+o,u=a);const g=u.match(w);return g?{listType:"checklist",checked:"x"===(g[1]??" ").toLowerCase(),contentColumn:l,firstText:g[2]??"",startNumber:c}:{listType:n?"ordered":"bullet",checked:!1,contentColumn:l,firstText:u,startNumber:c}}function V(t,e,n,r,i,s,o){const a=[],c=function(){let t=null;return(e,n)=>{if(t)return t.test(e)&&(t=null),!1;const r=D(e);if(r){const e=r[1]??"```",n=e[0]??"`";return t=new RegExp(`^ {0,3}\\${n}{${e.length},}[ \\t]*$`),!1}return!v(e)&&(x.test(e)||X(e)?Z(e):W(e)>=4?n:!J(e))}}();let l=n.firstText,g=""!==l&&c(l,!1),h=0,f=e+1;for(;f<t.length;){const e=t[f]??"";if(v(e)){if(""===l&&0===a.length)break;h++,g=!1,f++;continue}if(W(e)>=n.contentColumn){for(;h>0;)a.push(""),h--;const t=E(e,n.contentColumn);a.push(t),g=c(t,g),f++;continue}if(X(e))break;if(!g)break;if(J(e))break;if(i&&u(t,f,J))break;const r=e.trimStart(),s=a[a.length-1];void 0!==s?a[a.length-1]=`${s}\n${r}`:l=""===l?r:`${l}\n${r}`,g=c(r,g),f++}return function(t,e,n,r,i,s,o){const a=""===e?[...n]:[e,...n],c=0===a.length?[]:_(a,i,s,o+1),l=[],u=[];for(const h of c)"list_item"===h.type?l.push({...h,indent:h.indent+1}):u.push(h);const g=u[0];1===u.length&&"paragraph"===g?.type?r.push(B(t,g.text)):0===u.length?r.push(B(t,"")):r.push(B(t,"",u)),r.push(...l)}(n,l,a,r,i,s,o),f}function B(t,e,n){const r={type:"list_item",listType:t.listType,indent:0,checked:t.checked,text:e};return n?{...r,children:n}:r}function U(t){const e=t.match(A);if(!e)return!1;if(t.trimStart().startsWith("\x3c!--"))return!0;const n=(e[2]??"").toLowerCase();return k.has(n)}function G(t,e,n){const r=[];let i=e;for(;i<t.length;){const e=t[i]??"";if(v(e))break;r.push(e),i++}return n.push({type:"html",html:r.join("\n")}),i}function J(t){return!!(v(t)||M.test(t)||D(t)||S.test(t)||x.test(t)||function(t){const e=X(t);return!!e&&""!==e.firstText.trim()&&("ordered"!==e.listType||1===e.startNumber)}(t)||U(t))}function K(t,e,n){const r=[t[e]??""];let i=e+1;for(;i<t.length;){const e=t[i]??"";if(N.test(e))return n.push({type:"heading",level:1,text:Y(r)}),i+1;if(z.test(e))return n.push({type:"heading",level:2,text:Y(r)}),i+1;if(J(e))break;r.push(e),i++}return n.push({type:"paragraph",text:Q(r)}),i}function Q(t){return t.map((e,n)=>n===t.length-1?e.trim():e.trimStart()).join("\n")}function Y(t){return t.map(t=>t.trim()).join(" ").trim()}function tt(a){return a||(y??=function(){const a=new o;return function(e){e.registerNodeSpec({type:"paragraph",toDOM:et,toHTML:(t,e)=>`<p>${e||"<br>"}</p>`,parseHTML:[{tag:"p"},{tag:"div",priority:10}],sanitize:{tags:["p"]}}),e.registerNodeSpec({type:"heading",toDOM:et,toHTML(t,e){const n=t.attrs?.level,r="number"==typeof n&&Number.isFinite(n)?Math.max(1,Math.min(6,Math.floor(n))):1;return`<h${r}>${e||"<br>"}</h${r}>`},parseHTML:[1,2,3,4,5,6].map(t=>({tag:`h${t}`,getAttrs:()=>({level:t})})),sanitize:{tags:["h1","h2","h3","h4","h5","h6"]}}),e.registerNodeSpec({type:"list_item",toDOM:et,toHTML(t,e){if("checklist"!==t.attrs?.listType)return`<li>${e||"<br>"}</li>`;const n=!0===t.attrs.checked;return`<li role="checkbox" aria-checked="${String(n)}"><input type="checkbox" disabled${n?" checked":""}>${e||"<br>"}</li>`},parseHTML:[{tag:"li"}],sanitize:{tags:["ul","ol","li","input"],attrs:["type","disabled","checked","role","aria-checked"]}}),e.registerNodeSpec({type:"blockquote",toDOM:et,toHTML:(t,e)=>`<blockquote>${e||"<br>"}</blockquote>`,parseHTML:[{tag:"blockquote"}],sanitize:{tags:["blockquote"]}}),e.registerNodeSpec({type:"code_block",toDOM:et,toHTML(e,n){const r=String(e.attrs?.language??"");return`<pre><code${r?` class="language-${t(r)}"`:""}>${n}</code></pre>`},parseHTML:[{tag:"pre",getAttrs:t=>({language:t.querySelector("code")?.className.match(/(?:^|\s)language-(\S+)/)?.[1]??""})}],sanitize:{tags:["pre","code"],attrs:["class"]}}),e.registerNodeSpec({type:"horizontal_rule",isVoid:!0,toDOM:et,toHTML:()=>"<hr>",parseHTML:[{tag:"hr"}],sanitize:{tags:["hr"]}}),e.registerNodeSpec({type:"image",isVoid:!0,attrs:{src:{default:""},alt:{default:""},title:{default:""},align:{default:"center"}},toDOM:et,toHTML(e){const n=t(String(e.attrs?.src??"")),r=t(String(e.attrs?.alt??"")),i=String(e.attrs?.title??""),s=(t,e)=>"number"==typeof e&&Number.isFinite(e)&&e>0?` ${t}="${String(e)}"`:"";return`<figure><img src="${n}" alt="${r}"${i?` title="${t(i)}"`:""}${s("width",e.attrs?.width)}${s("height",e.attrs?.height)}></figure>`},parseHTML:[{tag:"figure",getAttrs(t){const e=t.querySelector("img");return!!e&&nt(e)}},{tag:"img",getAttrs:t=>nt(t)}],sanitize:{tags:["figure","img"],attrs:["src","alt","title","width","height"]}}),e.registerNodeSpec({type:"table",toDOM:et,toHTML(t,e,s){const o=i(t.attrs?.columnWidthsPx),a=o?`<colgroup>${o.map(t=>`<col${n(r,"width",t,s)}>`).join("")}</colgroup>`:"";return`<table${o?function(t,e){const n=t.reduce((t,e)=>t+(e??60),0),r=t.every(t=>null!==t)?`width: ${String(n)}px; min-width: ${String(n)}px; table-layout: fixed`:`width: 100%; min-width: ${String(n)}px; table-layout: fixed`;return e?.styleAttr(r)??` style="${r}"`}(o,s):""}>${a}<tbody>${e}</tbody></table>`},sanitize:{tags:["table","colgroup","col","thead","tbody","tfoot"],attrs:["span","width",r]}}),e.registerNodeSpec({type:"table_row",toDOM:et,toHTML:(t,e,r)=>`<tr${n(s,"height",t.attrs?.minHeightPx,r)}>${e}</tr>`,sanitize:{tags:["tr"],attrs:["height",s]}}),e.registerNodeSpec({type:"table_cell",toDOM:et,toHTML(t,e){const n=(t,e)=>"number"==typeof e&&Number.isInteger(e)&&e>1?` ${t}="${String(e)}"`:"";return`<td${n("colspan",t.attrs?.colspan)}${n("rowspan",t.attrs?.rowspan)}>${e}</td>`},sanitize:{tags:["td","th"],attrs:["colspan","rowspan"]}})}(a),function(n){for(const t of[{type:"bold",rank:0,tag:"strong",parseTags:["strong","b"]},{type:"italic",rank:1,tag:"em",parseTags:["em","i"]},{type:"underline",rank:2,tag:"u",parseTags:["u"]},{type:"code",rank:3,tag:"code",parseTags:["code"]},{type:"strikethrough",rank:4,tag:"s",parseTags:["s","strike","del"]}])n.registerMarkSpec({type:t.type,rank:t.rank,toDOM:et,toHTMLString:(e,n)=>`<${t.tag}>${n}</${t.tag}>`,parseHTML:t.parseTags.map(t=>({tag:t,getAttrs:"code"===t?t=>"PRE"!==t.parentElement?.tagName&&{}:void 0})),sanitize:{tags:t.parseTags}});n.registerMarkSpec({type:"link",rank:10,toDOM:et,toHTMLString(n,r){const i=t(e(String(n.attrs?.href??""))),s=String(n.attrs?.title??"");return`<a href="${i}"${s?` title="${t(s)}"`:""}>${r}</a>`},parseHTML:[{tag:"a",getAttrs(t){const n=e(t.getAttribute("href")??""),r=t.getAttribute("title");return r?{href:n,title:r}:{href:n}}}],sanitize:{tags:["a"],attrs:["href","title"]}})}(a),function(e){e.registerInlineNodeSpec({type:"hard_break",toDOM:et,toHTMLString:()=>"<br>",parseHTML:[{tag:"br"}],sanitize:{tags:["br"]}}),e.registerInlineNodeSpec({type:"image_inline",toDOM:et,toHTMLString(e){const n=t(String(e.attrs.src??"")),r=t(String(e.attrs.alt??"")),i=String(e.attrs.title??"");return`<img src="${n}" alt="${r}"${i?` title="${t(i)}"`:""}>`},parseHTML:[{tag:"img",getAttrs:t=>rt(t)}],sanitize:{tags:["img"],attrs:["src","alt","title"]}})}(a),a}(),y)}function et(){throw new Error("The Markdown HTML registry cannot render editor DOM.")}function nt(t){const e={...rt(t),align:"center"};for(const n of["width","height"]){const r=Number.parseFloat(t.getAttribute(n)??"");Number.isFinite(r)&&r>0&&(e[n]=r)}return e}function rt(t){const e={src:t.getAttribute("src")??"",alt:t.getAttribute("alt")??""},n=t.getAttribute("title");return n&&(e.title=n),e}export{z as a,O as c,b as d,d as f,N as i,$ as l,M as n,S as o,T as r,D as s,tt as t,p as u};
2
+ //# sourceMappingURL=MarkdownHTMLRegistry-Q7l0d6Ma.mjs.map