@panphora/clayjs 1.17.0 → 1.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (467) hide show
  1. package/dist/all.js +1 -1
  2. package/dist/clay-dom.js +1 -1
  3. package/dist/clay-events.js +1 -1
  4. package/dist/clay-internals.js +1 -1
  5. package/dist/clay-options.js +1 -1
  6. package/dist/clay-router.js +1 -1
  7. package/dist/clay-ui.js +1 -1
  8. package/dist/clay-utils.js +1 -1
  9. package/dist/clay.js +1 -1
  10. package/dist/clay.standalone.js +72474 -62090
  11. package/dist/m/attrs/{save-freeze-MYNVXREN.js → save-freeze-LWGF6XUN.js} +1 -1
  12. package/dist/m/c-2GRUM77Q.js +30 -0
  13. package/dist/m/c-2KIEGNC4.js +1 -0
  14. package/dist/m/{c-AMSNPOCX.js → c-2KL3BD52.js} +1 -1
  15. package/dist/m/c-2ZZBC45O.js +1 -0
  16. package/dist/m/c-372N6H3B.js +1 -0
  17. package/dist/m/{c-4WKFKEKF.js → c-3G2DGZUP.js} +1 -1
  18. package/dist/m/c-3LDGIBMN.js +1 -0
  19. package/dist/m/c-3O7OBDCM.js +1 -0
  20. package/dist/m/c-4ASQPRQL.js +1 -0
  21. package/dist/m/c-4TXNLX4K.js +6 -0
  22. package/dist/m/c-4YU3BR4D.js +6 -0
  23. package/dist/m/c-5734MF2P.js +1 -0
  24. package/dist/m/c-57XDY6HC.js +1 -0
  25. package/dist/m/{c-KAU6E43D.js → c-5B4YBZXC.js} +1 -1
  26. package/dist/m/c-5ONTYIUI.js +1 -0
  27. package/dist/m/c-5OOVFCJM.js +1 -0
  28. package/dist/m/{c-3XIRD4NU.js → c-5T6NZHNM.js} +1 -1
  29. package/dist/m/{c-74MGYWZF.js → c-5ZQV7KC4.js} +1 -1
  30. package/dist/m/{c-7OLLJPWP.js → c-6DB2OLRJ.js} +1 -1
  31. package/dist/m/c-6DNRCPNM.js +1 -0
  32. package/dist/m/c-6UGWFMQC.js +2 -0
  33. package/dist/m/c-7K4SCQB7.js +1 -0
  34. package/dist/m/c-7MG5RU63.js +1 -0
  35. package/dist/m/c-7PRJCA3E.js +1 -0
  36. package/dist/m/c-A6L3FMUS.js +1 -0
  37. package/dist/m/c-AMU3BPPR.js +4 -0
  38. package/dist/m/{c-Y5HBBIQ4.js → c-AMYEFA2E.js} +1 -1
  39. package/dist/m/c-AQYCG7QW.js +1 -0
  40. package/dist/m/c-ATKAOH23.js +1 -0
  41. package/dist/m/c-B5CS55WR.js +1 -0
  42. package/dist/m/c-B5UJQT7W.js +1 -0
  43. package/dist/m/c-B7J4K2AE.js +3 -0
  44. package/dist/m/c-BHZYSHW4.js +1 -0
  45. package/dist/m/{c-VHM5XQHK.js → c-BIJALSRD.js} +1 -1
  46. package/dist/m/c-BJ7YQ5QZ.js +1 -0
  47. package/dist/m/{c-KIPQJX4B.js → c-BRLCTNMC.js} +1 -1
  48. package/dist/m/{c-VE6ZMYMC.js → c-BUAYFEV5.js} +1 -1
  49. package/dist/m/c-C6IPRG34.js +1 -0
  50. package/dist/m/{c-KU3ZFADW.js → c-CAS3NND4.js} +1 -1
  51. package/dist/m/{c-PS5ARVWR.js → c-CCQ25GFY.js} +1 -1
  52. package/dist/m/c-CJFDLD43.js +1 -0
  53. package/dist/m/c-COPTL5WB.js +1 -0
  54. package/dist/m/c-D3E4WJ4M.js +166 -0
  55. package/dist/m/c-D5IKEKXW.js +7 -0
  56. package/dist/m/c-DHBRA6DL.js +1 -0
  57. package/dist/m/c-DKLS74XB.js +72 -0
  58. package/dist/m/c-DVYGFTSK.js +3 -0
  59. package/dist/m/c-E3ZXARWA.js +1 -0
  60. package/dist/m/c-EK63G3CG.js +1 -0
  61. package/dist/m/c-ERQSNR6K.js +13 -0
  62. package/dist/m/c-EVYAISP3.js +1 -0
  63. package/dist/m/c-EXKHPOVC.js +3 -0
  64. package/dist/m/{c-QJ4OM3G6.js → c-FWKHM4E7.js} +1 -1
  65. package/dist/m/{c-4Q2XTQ2N.js → c-GBKB5WDL.js} +1 -1
  66. package/dist/m/c-GNDL3TKB.js +1 -0
  67. package/dist/m/c-GRWMD6O5.js +1 -0
  68. package/dist/m/c-GRXHHFPO.js +1 -0
  69. package/dist/m/c-HG2C77BM.js +4 -0
  70. package/dist/m/c-HHGJBU4D.js +1 -0
  71. package/dist/m/c-HMV6P4RX.js +1 -0
  72. package/dist/m/c-HMYWIHFG.js +1 -0
  73. package/dist/m/c-HT2DKBV2.js +1 -0
  74. package/dist/m/c-I2SCCUEW.js +1 -0
  75. package/dist/m/{c-TJ6WOJL3.js → c-ICJYHABF.js} +2 -2
  76. package/dist/m/c-IMZCWYHR.js +7 -0
  77. package/dist/m/c-IVMD3FEM.js +1 -0
  78. package/dist/m/{c-WDC5GVKU.js → c-IVTRVENZ.js} +1 -1
  79. package/dist/m/c-JKZJIUIP.js +1 -0
  80. package/dist/m/{c-UDUUJPFZ.js → c-JNLX3RJB.js} +1 -1
  81. package/dist/m/c-K3ADYNLU.js +1 -0
  82. package/dist/m/c-KGHVFRR3.js +1 -0
  83. package/dist/m/{c-5QWQ7A5L.js → c-KJJPV77R.js} +1 -1
  84. package/dist/m/{c-CZUSOB7V.js → c-KNPDOMDY.js} +1 -1
  85. package/dist/m/{c-EZU56NQV.js → c-KP64LT2A.js} +2 -2
  86. package/dist/m/c-KQ7E3PYY.js +1 -0
  87. package/dist/m/c-L3F5ZLIV.js +1 -0
  88. package/dist/m/{c-3RUU4TPX.js → c-L42OLXWM.js} +3 -2
  89. package/dist/m/c-L5VFATT6.js +1 -0
  90. package/dist/m/c-L7JL5TL3.js +3 -0
  91. package/dist/m/c-LKSL4AUJ.js +1 -0
  92. package/dist/m/c-M6FNQCTQ.js +1 -0
  93. package/dist/m/c-MCOOHCSG.js +1 -0
  94. package/dist/m/c-MHI3GYKF.js +1 -0
  95. package/dist/m/c-MWXFLW4J.js +1 -0
  96. package/dist/m/{c-5RJFTLSF.js → c-NEL7HQW3.js} +1 -1
  97. package/dist/m/{c-DCXOXBF3.js → c-NQJRVJ56.js} +1 -1
  98. package/dist/m/c-NWX3MFT4.js +1 -0
  99. package/dist/m/{c-HPURYVZS.js → c-OJYM642Q.js} +1 -1
  100. package/dist/m/c-OKXI52N7.js +1 -0
  101. package/dist/m/{c-R3L7ZJGB.js → c-OPLUZR3A.js} +1 -1
  102. package/dist/m/{c-GSFIGKOP.js → c-OTMKN2OO.js} +1 -1
  103. package/dist/m/{c-6NC5I2TV.js → c-OYRZ7XG2.js} +1 -1
  104. package/dist/m/{c-EVCQ3BKA.js → c-P3OFYUMA.js} +1 -1
  105. package/dist/m/c-PLN76GF3.js +6 -0
  106. package/dist/m/c-PLP4JKFC.js +1 -0
  107. package/dist/m/c-Q26MME6N.js +1 -0
  108. package/dist/m/{c-S7H2DRCB.js → c-Q3XOWZEV.js} +1 -1
  109. package/dist/m/{c-FRLHSY7E.js → c-QIKT6SKM.js} +1 -1
  110. package/dist/m/c-QIXT3Q7C.js +28 -0
  111. package/dist/m/c-QO4HNGCQ.js +1 -0
  112. package/dist/m/{c-JU3NK25H.js → c-R27DWQKX.js} +1 -1
  113. package/dist/m/{c-RSMOODDU.js → c-R2XUODVY.js} +1 -1
  114. package/dist/m/{c-QNKREOL6.js → c-R7LBFMF5.js} +1 -1
  115. package/dist/m/c-RND3G2S2.js +1 -0
  116. package/dist/m/{c-Q622NS2Y.js → c-S2U6NJU4.js} +1 -1
  117. package/dist/m/c-SPZPGD3R.js +1 -0
  118. package/dist/m/c-SW4YEG2D.js +8 -0
  119. package/dist/m/c-T637T7SN.js +1 -0
  120. package/dist/m/c-TJAXGIRV.js +1 -0
  121. package/dist/m/{c-RYUXUUBX.js → c-TNEM3RNM.js} +1 -1
  122. package/dist/m/c-TTB5EK4S.js +32 -0
  123. package/dist/m/c-U7SHNWDH.js +1 -0
  124. package/dist/m/c-UDHIVLYH.js +20 -0
  125. package/dist/m/{c-BBVGTQG7.js → c-UGNV5MFB.js} +1 -1
  126. package/dist/m/{c-QICP2YR5.js → c-UORXLSD3.js} +1 -1
  127. package/dist/m/c-UPD33ZPE.js +1 -0
  128. package/dist/m/c-URSMSFCB.js +1 -0
  129. package/dist/m/c-UY4QX42B.js +1 -0
  130. package/dist/m/c-V44KWI2L.js +4 -0
  131. package/dist/m/c-VILENZTD.js +1 -0
  132. package/dist/m/{c-HDDEEL77.js → c-VJYEVRYK.js} +1 -1
  133. package/dist/m/{c-SMBZG5X4.js → c-VR2BJ4AN.js} +1 -1
  134. package/dist/m/c-W4JCVLAB.js +1 -0
  135. package/dist/m/c-W6DQSHXI.js +135 -0
  136. package/dist/m/c-WBGWGOM7.js +1 -0
  137. package/dist/m/{c-4L3BTFRK.js → c-WCXLG3MV.js} +1 -1
  138. package/dist/m/c-WGW764WX.js +1 -0
  139. package/dist/m/c-WMRJKQ2V.js +5 -0
  140. package/dist/m/c-WNTYKCDG.js +1 -0
  141. package/dist/m/c-WQWIRWO3.js +72 -0
  142. package/dist/m/c-X5LNHET5.js +1 -0
  143. package/dist/m/{c-I2ZATQCD.js → c-X5TSXZYJ.js} +2 -2
  144. package/dist/m/c-XGH4GS2T.js +1 -0
  145. package/dist/m/c-Y6F2FORL.js +1 -0
  146. package/dist/m/c-YBKHUAK7.js +10 -0
  147. package/dist/m/c-YBSS55KU.js +20 -0
  148. package/dist/m/c-YCLU4UNT.js +2 -0
  149. package/dist/m/c-YVZ2L7CE.js +1 -0
  150. package/dist/m/c-ZK4GIZH2.js +1 -0
  151. package/dist/m/c-ZRXJD4G6.js +1 -0
  152. package/dist/m/c-ZWBI4HYK.js +1 -0
  153. package/dist/m/core/{admin-attrs-QHOKPJ7W.js → admin-attrs-YY7T5FGU.js} +1 -1
  154. package/dist/m/core/autosave-S6OMNDCK.js +1 -0
  155. package/dist/m/core/conflict-notice-IWHMHH43.js +1 -0
  156. package/dist/m/core/{host-permission-FNXVEFNE.js → host-permission-6EVJGNPL.js} +1 -1
  157. package/dist/m/core/is-edit-mode-GCX6767E.js +1 -0
  158. package/dist/m/core/{persist-JFYRHMRJ.js → persist-UKXV5KLA.js} +1 -1
  159. package/dist/m/core/recovery-DRFZRJED.js +1 -0
  160. package/dist/m/core/save-LYY7K6U7.js +1 -0
  161. package/dist/m/core/save-core-MKRPSEEO.js +1 -0
  162. package/dist/m/core/snapshot-NU3YM6GR.js +1 -0
  163. package/dist/m/core/unsaved-warning-7QTKEN7Z.js +1 -0
  164. package/dist/m/internals/{index-PVXGPUDA.js → index-TGLQINN3.js} +1 -1
  165. package/dist/m/loader-3BBNZZGM.js +1 -0
  166. package/dist/m/manifest-26C55578.js +1 -0
  167. package/dist/m/manifest-edit-4396A009.js +1 -0
  168. package/dist/m/manifest.json +2111 -1573
  169. package/dist/m/page/{editor-NNJA4OKD.js → editor-6LRB3GE4.js} +123 -21
  170. package/dist/m/plugins/ai-edit-UTV7YO2I.js +6 -0
  171. package/dist/m/plugins/{cms-HP3LSTPN.js → cms-LRAOZHT7.js} +9 -9
  172. package/dist/m/plugins/{demo-RM5IR6AO.js → demo-OYO5GCAO.js} +1 -1
  173. package/dist/m/plugins/{derive-UAAA4V4S.js → derive-FRE5JJQE.js} +1 -1
  174. package/dist/m/plugins/indicator-4VDXWYTD.js +1 -0
  175. package/dist/m/plugins/live-AD4H6XSL.js +1 -0
  176. package/dist/m/plugins/menu-M5WW7DBF.js +1 -0
  177. package/dist/m/plugins/page-MD3T2ZX3.js +2 -0
  178. package/dist/m/plugins/page-view-PAWVZNFY.js +1 -0
  179. package/dist/m/plugins/{people-SGPJKANK.js → people-JCHVPF7P.js} +1 -1
  180. package/dist/m/plugins/quickcrop-BQ5YYFCH.js +26 -0
  181. package/dist/m/plugins/{richclay-NRQDSWX6.js → richclay-KLGETK77.js} +2 -2
  182. package/dist/m/plugins/sortable-4S6SQC3D.js +1 -0
  183. package/dist/m/plugins/source-TJXOIOYY.js +1 -0
  184. package/dist/m/plugins/undo-NLPGCJQY.js +1 -0
  185. package/dist/m/plugins/{unsent-HJFLQJ2O.js → unsent-OA4RGBUT.js} +1 -1
  186. package/dist/m/plugins/upgrade-HSUNDNJD.js +1 -0
  187. package/dist/m/plugins/{upload-WLYKK6TL.js → upload-NHGJXZK2.js} +1 -1
  188. package/dist/m/plugins/visitor-drafts-BW43DGY3.js +20 -0
  189. package/dist/m/plugins/visitor-drafts-owner-7ODQG7JX.js +1 -0
  190. package/dist/m/plugins/{wire-4N6GYAF6.js → wire-VBWXEXU2.js} +1 -1
  191. package/dist/m/reader-core-4W2KYEWQ.js +77 -0
  192. package/dist/m/route/route-62CHXL5B.js +1 -0
  193. package/dist/m/sync/live-sync-MO5DH33W.js +1 -0
  194. package/dist/m/ui/index-IVWN2QC4.js +1 -0
  195. package/dist/m/vendor/sap-core.vendor-RN4ZVY4X.js +6 -0
  196. package/dist/offline-manifest.json +1367 -930
  197. package/dist/page/themes/light-1.css +8 -7
  198. package/dist/server/core.cjs +1440 -288
  199. package/dist/server/offline-runtime.cjs +63 -63
  200. package/dist/server/offline-runtime.mjs +63 -63
  201. package/dist/server/page-compaction-worker.cjs +3710 -0
  202. package/dist/server/rooms.mjs +5 -0
  203. package/docs/guide.md +653 -101
  204. package/entries/sap.js +5 -5
  205. package/package.json +1 -1
  206. package/src/core/admin-contenteditable.js +5 -2
  207. package/src/core/admin-inputs.js +1 -0
  208. package/src/core/admin-onclick.js +2 -1
  209. package/src/core/conflict-notice-ui.js +4 -7
  210. package/src/core/download.js +2 -2
  211. package/src/core/host-meta.js +38 -0
  212. package/src/core/is-edit-mode.js +17 -1
  213. package/src/core/mode-key.js +125 -19
  214. package/src/core/mode-support.js +5 -0
  215. package/src/core/mode-transition.js +20 -6
  216. package/src/core/preserve-authored.js +4 -4
  217. package/src/core/recovery.js +121 -33
  218. package/src/core/save-accepted.js +33 -0
  219. package/src/core/save-core.js +106 -31
  220. package/src/core/save-job.js +108 -0
  221. package/src/core/save-prepare.js +53 -0
  222. package/src/core/save-size-notice.js +3 -1
  223. package/src/core/save-slices.js +15 -0
  224. package/src/core/save.js +557 -127
  225. package/src/core/serialize-steps.js +109 -0
  226. package/src/core/snapshot.js +170 -39
  227. package/src/core/source-map.js +83 -38
  228. package/src/core/stale-host-notice.js +1 -0
  229. package/src/core/upgrade-run.js +59 -8
  230. package/src/dom/active-element.js +5 -0
  231. package/src/lib/assets.js +1 -0
  232. package/src/lib/slice.js +65 -0
  233. package/src/lib/uimotion.js +774 -0
  234. package/src/lib/unsaved-state.js +2 -2
  235. package/src/live/fast-lane.js +10 -3
  236. package/src/live/local-lane.js +202 -11
  237. package/src/live/ops.js +16 -0
  238. package/src/live/page-compaction.js +162 -0
  239. package/src/live/server-lane.js +1 -0
  240. package/src/live/store.js +11 -3
  241. package/src/loader-logic.js +3 -1
  242. package/src/loader.js +14 -4
  243. package/src/page/adopt-boot.js +2 -1
  244. package/src/page/awareness.js +33 -2
  245. package/src/page/blocks.js +89 -27
  246. package/src/page/boot-pack.js +1 -1
  247. package/src/page/chart-tables.js +21 -3
  248. package/src/page/chart.js +406 -63
  249. package/src/page/checklist.js +10 -135
  250. package/src/page/checkpoint-proof.js +7 -1
  251. package/src/page/chrome.js +250 -51
  252. package/src/page/clipboard-shape.js +126 -0
  253. package/src/page/drag.js +33 -3
  254. package/src/page/editor.js +136 -25
  255. package/src/page/export-assets.js +357 -0
  256. package/src/page/export-html.js +209 -0
  257. package/src/page/export-markdown.js +361 -0
  258. package/src/page/features/checklist.js +428 -0
  259. package/src/page/features/export-html.js +189 -0
  260. package/src/page/features/export-markdown.js +169 -0
  261. package/src/page/features/import-markdown.js +349 -0
  262. package/src/page/features/media.js +61 -5
  263. package/src/page/features/registry.js +18 -0
  264. package/src/page/features/table.js +373 -83
  265. package/src/page/features/title-cover.js +331 -0
  266. package/src/page/features/title-icon.js +213 -0
  267. package/src/page/features/toc.js +87 -0
  268. package/src/page/format-command.js +25 -1
  269. package/src/page/format-gate.js +68 -18
  270. package/src/page/format-host.js +17 -0
  271. package/src/page/format-native-commands.js +21 -5
  272. package/src/page/image-actions.js +64 -0
  273. package/src/page/import-markdown.js +262 -0
  274. package/src/page/items.js +135 -17
  275. package/src/page/markdown.js +6 -2
  276. package/src/page/media.js +35 -119
  277. package/src/page/placeholder.js +14 -1
  278. package/src/page/projection.js +98 -10
  279. package/src/page/recover.js +10 -12
  280. package/src/page/recovery-ui.js +464 -0
  281. package/src/page/rich/chart.js +63 -7
  282. package/src/page/save-projection.js +28 -0
  283. package/src/page/save-states.js +13 -3
  284. package/src/page/schema.js +19 -3
  285. package/src/page/table-paste.js +3 -1
  286. package/src/page/table-style.js +4 -4
  287. package/src/page/table.js +44 -2
  288. package/src/page/themes/light-1.css +8 -7
  289. package/src/page/themes/light-1.source.css +8 -7
  290. package/src/page/toc-link.js +31 -0
  291. package/src/page/toc.js +5 -0
  292. package/src/page/view-hooks.js +38 -12
  293. package/src/page/view.js +13 -0
  294. package/src/page/ybind/binding.js +88 -5
  295. package/src/page/ybind/bridge.js +187 -20
  296. package/src/page/ybind/containment.js +162 -0
  297. package/src/page/ybind/doc.js +17 -9
  298. package/src/page/ybind/file-debt.js +63 -0
  299. package/src/page/ybind/layout.js +7 -2
  300. package/src/page/ybind/marks.js +1 -1
  301. package/src/page/ybind/moves.js +5 -4
  302. package/src/page/ybind/origins.js +106 -4
  303. package/src/page/ybind/parts.js +8 -1
  304. package/src/page/ybind/provider.js +113 -17
  305. package/src/page/ybind/recovery-proof.js +32 -9
  306. package/src/page/ybind/recovery-replay.js +558 -15
  307. package/src/page/ybind/recovery.js +174 -45
  308. package/src/page/ybind/table.js +67 -11
  309. package/src/page/ybind/walk-delta.js +258 -0
  310. package/src/page/ybind/walk.js +54 -29
  311. package/src/page/ybind/writer.js +1 -1
  312. package/src/plugins/ai-edit.js +13 -9
  313. package/src/plugins/indicator-chip.js +91 -0
  314. package/src/plugins/indicator.js +13 -80
  315. package/src/plugins/live.js +89 -14
  316. package/src/plugins/menu/actions.js +196 -0
  317. package/src/plugins/menu/people.js +279 -0
  318. package/src/plugins/menu/placement.js +121 -0
  319. package/src/plugins/menu/preferences.js +9 -0
  320. package/src/plugins/menu/seo.js +316 -397
  321. package/src/plugins/menu/style.js +171 -0
  322. package/src/plugins/menu/variants.js +296 -0
  323. package/src/plugins/menu.js +186 -183
  324. package/src/plugins/page-view.js +3 -2
  325. package/src/plugins/page.js +249 -44
  326. package/src/plugins/sortable.js +8 -1
  327. package/src/plugins/source.js +6 -0
  328. package/src/plugins/upgrade.js +51 -17
  329. package/src/plugins/upload-ui.js +12 -17
  330. package/src/plugins/visitor-drafts/bottom-ui.js +12 -4
  331. package/src/plugins/visitor-drafts/intro-style.js +7 -2
  332. package/src/plugins/visitor-drafts/intro.js +5 -3
  333. package/src/plugins/visitor-drafts/owner-chip.js +8 -12
  334. package/src/plugins/visitor-drafts/prompt.js +11 -9
  335. package/src/plugins/visitor-drafts/source.js +4 -3
  336. package/src/plugins/visitor-drafts/store.js +138 -9
  337. package/src/plugins/visitor-drafts/ui-memory.js +2 -2
  338. package/src/plugins/visitor-drafts-owner.js +4 -6
  339. package/src/plugins/visitor-drafts.js +5 -3
  340. package/src/recovery/store.js +1 -1
  341. package/src/route/route.js +4 -0
  342. package/src/server/rooms/index.js +5 -1
  343. package/src/server/rooms/live-data-rooms.js +302 -50
  344. package/src/server/rooms/page-compaction-worker.js +12 -0
  345. package/src/server/rooms/page-compactor.js +92 -0
  346. package/src/server/rooms/page-room-conformance.js +461 -0
  347. package/src/source/parse-steps.js +94 -0
  348. package/src/source/session.js +233 -57
  349. package/src/sync/editing-sender.js +12 -0
  350. package/src/sync/live-sync-edit.js +22 -2
  351. package/src/sync/live-sync.js +150 -23
  352. package/src/sync/page-relay.js +52 -0
  353. package/src/sync/presence-store.js +44 -4
  354. package/src/sync/presence.js +6 -3
  355. package/src/sync/saved-stream.js +11 -6
  356. package/src/ui/bevel-controls.js +1 -0
  357. package/src/ui/bevel-dialog.js +5 -2
  358. package/src/ui/editor-ui.js +77 -0
  359. package/src/ui/page-colour.js +281 -0
  360. package/src/ui/toast.js +16 -7
  361. package/src/vendor/hyper-html-api-upgrade.vendor.js +2 -2
  362. package/src/vendor/hyper-undo.vendor.js +1 -1
  363. package/src/vendor/hypercms.vendor.js +9 -9
  364. package/src/vendor/parse5.vendor.js +2 -2
  365. package/src/vendor/sap-core.vendor.js +5 -5
  366. package/dist/m/c-2SPVQSHC.js +0 -1
  367. package/dist/m/c-336SGU5W.js +0 -1
  368. package/dist/m/c-3H6BZDNJ.js +0 -6
  369. package/dist/m/c-4DFEJ2PO.js +0 -3
  370. package/dist/m/c-56QRZTZH.js +0 -1
  371. package/dist/m/c-5J4E7O4Y.js +0 -4
  372. package/dist/m/c-5LKDWQTL.js +0 -19
  373. package/dist/m/c-5V3MOVJT.js +0 -1
  374. package/dist/m/c-6AZOGAPE.js +0 -1
  375. package/dist/m/c-6CRUUXOX.js +0 -5
  376. package/dist/m/c-6HMB24EV.js +0 -1
  377. package/dist/m/c-6KEVEQ7L.js +0 -1
  378. package/dist/m/c-A3E3NIMC.js +0 -1
  379. package/dist/m/c-BQ6LOBEE.js +0 -1
  380. package/dist/m/c-BTDI4Y23.js +0 -1
  381. package/dist/m/c-CJ3A7ZKE.js +0 -1
  382. package/dist/m/c-CQHPGKX2.js +0 -1
  383. package/dist/m/c-DFS4XZJV.js +0 -2
  384. package/dist/m/c-DNENWY4O.js +0 -1
  385. package/dist/m/c-E4LIR5X5.js +0 -1
  386. package/dist/m/c-FDNHHZY5.js +0 -1
  387. package/dist/m/c-FROJUZMV.js +0 -1
  388. package/dist/m/c-G2JPKCTP.js +0 -1
  389. package/dist/m/c-GB6TU7WV.js +0 -1
  390. package/dist/m/c-GFJJEBTU.js +0 -1
  391. package/dist/m/c-GJAEGGXY.js +0 -1
  392. package/dist/m/c-GOWBDM6J.js +0 -1
  393. package/dist/m/c-HFKUVACH.js +0 -1
  394. package/dist/m/c-HHDFCNHV.js +0 -1
  395. package/dist/m/c-IEM4NTCS.js +0 -1
  396. package/dist/m/c-JDCX26UP.js +0 -25
  397. package/dist/m/c-KGVGROZT.js +0 -1
  398. package/dist/m/c-KQ6TYJAP.js +0 -135
  399. package/dist/m/c-LFPHCXY3.js +0 -1
  400. package/dist/m/c-LRPUO2MX.js +0 -1
  401. package/dist/m/c-LWLBHLVC.js +0 -3
  402. package/dist/m/c-M2L47S2X.js +0 -7
  403. package/dist/m/c-MFP2ZWD4.js +0 -1
  404. package/dist/m/c-MKSQ4Y57.js +0 -1
  405. package/dist/m/c-NUFFJVVJ.js +0 -1
  406. package/dist/m/c-NUHSPT5P.js +0 -1
  407. package/dist/m/c-O72HVYSA.js +0 -1
  408. package/dist/m/c-OIBUTDXI.js +0 -1
  409. package/dist/m/c-OW5QIGG3.js +0 -1
  410. package/dist/m/c-PGRCK73F.js +0 -1
  411. package/dist/m/c-Q7NQD65V.js +0 -1
  412. package/dist/m/c-QH63LQOS.js +0 -1
  413. package/dist/m/c-R7IWVINQ.js +0 -1
  414. package/dist/m/c-RM7J7BV2.js +0 -1
  415. package/dist/m/c-S4ZEH46B.js +0 -9
  416. package/dist/m/c-SDAXDM2D.js +0 -1
  417. package/dist/m/c-SMGU7RT3.js +0 -235
  418. package/dist/m/c-SPIORRYS.js +0 -1
  419. package/dist/m/c-SWLRT66R.js +0 -1
  420. package/dist/m/c-TCJTVAFN.js +0 -1
  421. package/dist/m/c-TQEMVJCS.js +0 -1
  422. package/dist/m/c-TYLXX4NF.js +0 -21
  423. package/dist/m/c-U62OB4BT.js +0 -1
  424. package/dist/m/c-U6YWUAR3.js +0 -8
  425. package/dist/m/c-UDCSU5G5.js +0 -2
  426. package/dist/m/c-VI5RMSVY.js +0 -1
  427. package/dist/m/c-VRZN56XY.js +0 -1
  428. package/dist/m/c-W5MCHEGA.js +0 -1
  429. package/dist/m/c-WNYBLIOZ.js +0 -1
  430. package/dist/m/c-WWXIDH4O.js +0 -28
  431. package/dist/m/c-XCNTK76U.js +0 -1
  432. package/dist/m/c-XMS6DPBR.js +0 -1
  433. package/dist/m/c-ZUCOKOHT.js +0 -1
  434. package/dist/m/c-ZVPVXTJF.js +0 -4
  435. package/dist/m/c-ZVRKXKM7.js +0 -1
  436. package/dist/m/core/autosave-HRYGUWV6.js +0 -1
  437. package/dist/m/core/conflict-notice-6MROJN2L.js +0 -1
  438. package/dist/m/core/is-edit-mode-KTWA3O5N.js +0 -1
  439. package/dist/m/core/recovery-FLTCC2OC.js +0 -1
  440. package/dist/m/core/save-HQZ4S667.js +0 -1
  441. package/dist/m/core/save-core-KGQWFUNH.js +0 -1
  442. package/dist/m/core/snapshot-EGQZNT45.js +0 -1
  443. package/dist/m/core/unsaved-warning-IDJLD66H.js +0 -1
  444. package/dist/m/loader-S4I7GKXR.js +0 -1
  445. package/dist/m/manifest-4C419D67.js +0 -1
  446. package/dist/m/manifest-edit-B077F288.js +0 -1
  447. package/dist/m/plugins/ai-edit-QN4PMMNL.js +0 -6
  448. package/dist/m/plugins/indicator-URDBBOQO.js +0 -1
  449. package/dist/m/plugins/live-HFWD4OIH.js +0 -1
  450. package/dist/m/plugins/menu-3HIEQSI6.js +0 -138
  451. package/dist/m/plugins/page-JOKB6XPR.js +0 -2
  452. package/dist/m/plugins/page-view-NXOJHNW6.js +0 -1
  453. package/dist/m/plugins/quickcrop-QNY3PKLD.js +0 -26
  454. package/dist/m/plugins/sortable-GWT4PWDV.js +0 -1
  455. package/dist/m/plugins/source-4ZRSAIYM.js +0 -1
  456. package/dist/m/plugins/undo-VDA5P7FH.js +0 -1
  457. package/dist/m/plugins/upgrade-W7FG5VFG.js +0 -1
  458. package/dist/m/plugins/visitor-drafts-LIDY7NH6.js +0 -21
  459. package/dist/m/plugins/visitor-drafts-owner-ZXCKBZE7.js +0 -1
  460. package/dist/m/reader-core-DXYCURFF.js +0 -68
  461. package/dist/m/route/route-KOCZSEGN.js +0 -1
  462. package/dist/m/sync/live-sync-J7VMYTKS.js +0 -1
  463. package/dist/m/ui/index-3JLVI27O.js +0 -1
  464. package/dist/m/vendor/sap-core.vendor-A7BMUYZT.js +0 -6
  465. /package/dist/m/{c-FILLTJA7.js → c-QTTJYJMA.js} +0 -0
  466. /package/dist/m/plugins/{quickcrop-QNY3PKLD.js.LEGAL.txt → quickcrop-BQ5YYFCH.js.LEGAL.txt} +0 -0
  467. /package/dist/m/plugins/{richclay-NRQDSWX6.js.LEGAL.txt → richclay-KLGETK77.js.LEGAL.txt} +0 -0
@@ -12,6 +12,7 @@ import { chartModel, renderChartSvg } from "./rich/chart.js";
12
12
  import { cellText } from "./rich/cell.js";
13
13
  import { bounded, descriptors, entriesOf, keyOf, normalizeEntries } from "./format-codec.js";
14
14
  import { nativeAttrs } from "./format-native.js";
15
+ import { safeSrc } from "./address.js";
15
16
 
16
17
  export const ATOM = "";
17
18
  export const BREAK = '@{"type":"hard_break"}';
@@ -41,13 +42,14 @@ const knownType = (t) => Object.hasOwn(DEFAULTS, t);
41
42
  // Mirrors schema.js attrs minus id and pos (a test pins the two together).
42
43
  export const DEFAULTS = {
43
44
  paragraph: { parent: null },
44
- heading: { parent: null, level: 2 },
45
+ heading: { parent: null, level: 2, pageIcon: null, pageCoverSrc: null, pageCoverAlt: "", pageCoverX: 50, pageCoverY: 50 },
45
46
  list_item: { parent: null, kind: "bullet", indent: 0, checked: false, owner: null, due: null },
46
47
  callout: { parent: null },
47
48
  quote: { parent: null },
48
49
  code_block: { parent: null, lang: "" },
49
- toggle: { parent: null, open: false },
50
+ toggle: { parent: null, open: false, level: null },
50
51
  divider: { parent: null },
52
+ toc: { parent: null, maxLevel: null },
51
53
  image: { parent: null, src: "", alt: "", caption: "", width: null, align: null },
52
54
  file: { parent: null, src: "", name: "", size: null, mime: null },
53
55
  table: { parent: null, cols: {}, sort: null },
@@ -57,6 +59,43 @@ export const DEFAULTS = {
57
59
  preserved: { parent: null, html: "" },
58
60
  };
59
61
  const TEXT = new Set(["paragraph", "heading", "list_item", "callout", "quote", "code_block", "toggle"]);
62
+ export const TOC_LABEL = "Table of contents";
63
+ export const TOC_ANCHOR = "page-block-";
64
+ export const blockAnchor = (id) => `${TOC_ANCHOR}${b64url(String(id ?? ""))}`;
65
+ const TOC_MAX_LEVEL = 3;
66
+ const tocLevel = (item) => (item.t === "heading"
67
+ ? Math.min(6, Math.max(1, Number.isInteger(item.level) ? item.level : 2))
68
+ : item.t === "toggle" && (item.level === 1 || item.level === 2 || item.level === 3) ? item.level : 0);
69
+ const tocTitle = (item) => item.t === "heading" && (item.level ?? 2) === 1 && (item.parent ?? null) === null;
70
+ const tocMax = (value) => (Number.isInteger(value) && value >= 1 && value <= 6 ? value : TOC_MAX_LEVEL);
71
+ const tocText = (item) => String(item.c ?? "").replace(/[\s\uFFFC]+/gu, " ").trim() || "Untitled";
72
+
73
+ export function tocEntries(model, maxLevel = TOC_MAX_LEVEL) {
74
+ const max = tocMax(maxLevel);
75
+ const title = model.find(tocTitle) ?? null;
76
+ const out = [];
77
+ for (const item of model) {
78
+ const level = tocLevel(item);
79
+ if (!item.id || !level || level > max || item === title) continue;
80
+ out.push({ id: item.id, level, text: tocText(item) });
81
+ }
82
+ return out;
83
+ }
84
+
85
+ export function tocHtml(item, model) {
86
+ const entries = tocEntries(model, item.maxLevel);
87
+ const root = { level: 0, children: [] };
88
+ const stack = [root];
89
+ for (const entry of entries) {
90
+ while (stack.length > 1 && stack[stack.length - 1].level >= entry.level) stack.pop();
91
+ const node = { ...entry, children: [] };
92
+ stack[stack.length - 1].children.push(node);
93
+ stack.push(node);
94
+ }
95
+ const list = (nodes) => `<ul>${nodes.map((node) => `<li><a href="#${blockAnchor(node.id)}">${escText(node.text)}</a>${node.children.length ? list(node.children) : ""}</li>`).join("")}</ul>`;
96
+ const level = item.maxLevel == null ? "" : ` data-max-level="${escAttr(item.maxLevel)}"`;
97
+ return `<nav aria-label="${TOC_LABEL}" data-type="toc" data-id="${escAttr(item.id ?? "")}"${level}>${entries.length ? list(root.children) : ""}</nav>`;
98
+ }
60
99
 
61
100
  const same = (a, b) => canon(a) === canon(b);
62
101
 
@@ -293,6 +332,8 @@ const omitDefaults = (t, fields) => {
293
332
  return out;
294
333
  };
295
334
 
335
+ const focal = (v) => Math.min(100, Math.max(0, Number.isFinite(+v) && v !== null && v !== "" ? +v : 50));
336
+
296
337
  const columnWidth = (value) => (typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.round(value) : null);
297
338
 
298
339
  function cellModel(value) {
@@ -340,9 +381,12 @@ const recordOfItem = (item) => {
340
381
 
341
382
  // The fields of a known block the runtime has no schema attribute for. They are
342
383
  // merged back only when serialized, inside the inert payload.
384
+ // Fields the renderer writes as visible markup, which the reader rebuilds from it.
385
+ const VISIBLE = { table: new Set(["rows"]) };
386
+
343
387
  const extrasOfItem = (item) => {
344
388
  const out = {};
345
- for (const [k, v] of Object.entries(item)) if (!STRUCTURAL.has(k) && !(knownType(item.t) && Object.hasOwn(DEFAULTS[item.t], k))) out[k] = v;
389
+ for (const [k, v] of Object.entries(item)) if (!STRUCTURAL.has(k) && !VISIBLE[item.t]?.has(k) && !(knownType(item.t) && Object.hasOwn(DEFAULTS[item.t], k))) out[k] = v;
346
390
  return Object.keys(out).length ? envelopeOf(out) : "";
347
391
  };
348
392
 
@@ -371,7 +415,8 @@ function projectOne({ id, b, t, parent, indent }) {
371
415
  for (const k of Object.keys(extras)) delete attrs[k];
372
416
  const fields = { ...attrs, parent };
373
417
  if (t === "list_item") fields.indent = indent;
374
- if (t === "heading") fields.level = clampLevel(attrs.level ?? 2);
418
+ if (t === "heading") Object.assign(fields, { level: clampLevel(attrs.level ?? 2), pageCoverSrc: safeSrc(fields.pageCoverSrc ?? null), pageCoverX: focal(fields.pageCoverX), pageCoverY: focal(fields.pageCoverY) });
419
+ if (t === "toggle") fields.level = toggleLevel(attrs.level);
375
420
  if (t === "image" && fields.width != null) fields.width = widthOf(String(fields.width));
376
421
  if (t === "image") fields.align = alignOf(fields.align);
377
422
  if (t === "image" && typeof fields.caption === "string") fields.caption = normalizeText(fields.caption, null).c;
@@ -394,7 +439,23 @@ function projectOne({ id, b, t, parent, indent }) {
394
439
  return item;
395
440
  }
396
441
 
442
+ // A record a newer writer left in an older writer's envelope, for a block type this
443
+ // build knows: the same projection a peer's record gets, without the fields this
444
+ // type does not declare.
445
+ function knownRecordItem(id, record, parent) {
446
+ const { t } = record;
447
+ const malformed = new SyntaxError(`page: an envelope names the known block type ${t}`);
448
+ if (TEXT.has(t) ? record.c != null && typeof record.c !== "string" : record.c != null || record.m != null) throw malformed;
449
+ let item;
450
+ try { item = projectOne({ id, b: record, t, parent, indent: 0 }); }
451
+ catch { throw malformed; }
452
+ const fields = DEFAULTS[t];
453
+ return Object.fromEntries(Object.entries(item).filter(([k]) => k === "id" || k === "t" || STRUCTURAL.has(k) || k === "rows" || Object.hasOwn(fields, k)));
454
+ }
455
+
397
456
  const clampLevel = (l) => Math.min(6, Math.max(1, Number.isInteger(l) ? l : 2));
457
+ // A toggle heading is level 1 to 3; anything else is a plain toggle.
458
+ export const toggleLevel = (l) => (l === 1 || l === 2 || l === 3 ? l : null);
398
459
  const widthOf = (s) => (/^\d+$/.test(s) ? Number(s) : s);
399
460
  export const alignOf = (a) => (a === "left" || a === "right" ? a : null);
400
461
 
@@ -469,9 +530,13 @@ export function renderInline(c, m, marksEnvelopes = true) {
469
530
  }
470
531
 
471
532
  const inlineOf = (item) => renderInline(item.c ?? "", item.m);
533
+ const titleHtml = (item) => `<header${attr("data-id", item.id)} data-page-heading="1"${extrasOfItem(item)}>${item.pageCoverSrc ? `<img data-page-cover${attr("src", item.pageCoverSrc)}${attr("alt", item.pageCoverAlt ?? "")} style="object-position:${item.pageCoverX ?? 50}% ${item.pageCoverY ?? 50}%">` : ""}${item.pageIcon ? `<span data-page-icon aria-hidden="true">${escText(item.pageIcon)}</span>` : ""}<h1>${inlineOf(item)}</h1></header>`;
472
534
  const toolData = (item) => item.artifact || item.rev || (item.state && Object.keys(item.state).length)
473
535
  ? `<script type="application/json" data-tool>${canon({ artifact: item.artifact ?? null, rev: item.rev ?? null, state: item.state ?? {} }).replace(/</g, "\\u003c")}</script>`
474
536
  : "";
537
+ // A header names its column for every cell under it: the table id and the column
538
+ // id together, so a copied column keeps a name no other table shares.
539
+ const headerId = (tableId, colId) => `${tableId}-${colId}`;
475
540
  const cellHtml = (cell) => (typeof cell === "string" ? escText(cell) : cell && typeof cell === "object" ? renderInline(String(cell.c ?? ""), cell.m) : "");
476
541
  const dataAttrs = (obj) => Object.entries(obj).map(([k, v]) => attr(`data-${k}`, v)).join("");
477
542
 
@@ -492,9 +557,12 @@ function renderLeaf(item, clean, tables) {
492
557
  return `<div${at} data-type="file"${attr("data-src", item.src ?? "")}${attr("data-name", item.name ?? "")}${attr("data-size", item.size ?? null)}${attr("data-mime", item.mime ?? null)}><a${attr("href", href)} rel="noopener noreferrer">${escText(item.name || "file")}</a></div>`;
493
558
  }
494
559
  case "table": {
495
- const head = item.cols.map((c) => `<th${attr("data-col", c.id)}${attr("data-kind", c.kind ?? null)}${attr("data-width", c.width ?? null)}${attr("style", c.width ? `width:${c.width}px` : null)}>${escText(c.name)}</th>`).join("");
496
- const body = item.rows.map((r) => `<tr${attr("data-id", r.id)}>${item.cols.map((c) => `<td>${cellHtml(r.cells[c.id])}</td>`).join("")}</tr>`).join("\n");
497
- return `<table${at}${attr("data-sort", item.sort != null ? JSON.stringify(item.sort) : null)}>\n<thead><tr>${head}</tr></thead>\n<tbody>\n${body}\n</tbody>\n</table>`;
560
+ const head = item.cols.map((c) => {
561
+ const sorted = item.sort?.col === c.id ? (item.sort.dir === "desc" ? "descending" : "ascending") : null;
562
+ return `<th${attr("data-col", c.id)}${attr("id", headerId(item.id, c.id))}${attr("data-kind", c.kind ?? null)}${attr("data-width", c.width ?? null)}${attr("style", c.width ? `width:${c.width}px` : null)} scope="col"${attr("aria-sort", sorted)}>${escText(c.name)}</th>`;
563
+ }).join("");
564
+ const body = item.rows.map((r) => `<tr${attr("data-id", r.id)}>${item.cols.map((c) => `<td${attr("headers", headerId(item.id, c.id))}>${cellHtml(r.cells[c.id])}</td>`).join("")}</tr>`).join("\n");
565
+ return `<table${at} aria-label="Table"${attr("data-sort", item.sort != null ? JSON.stringify(item.sort) : null)}>\n<thead><tr>${head}</tr></thead>\n<tbody>\n${body}\n</tbody>\n</table>`;
498
566
  }
499
567
  case "chart": {
500
568
  const data = dataAttrs({ source: item.source ?? null, kind: item.kind ?? null, x: item.x ?? null, series: item.series ? JSON.stringify(item.series) : null, highlight: item.highlight ?? null });
@@ -547,6 +615,7 @@ export function fragmentCleaner(doc) {
547
615
  export function renderModel(model, { fallbackOf = () => "", clean = RAW } = {}) {
548
616
  const lines = [];
549
617
  const tables = new Map(model.filter((item) => item.t === "table").map((item) => [item.id, item]));
618
+ const title = model.find(tocTitle) ?? null;
550
619
  const stack = [null];
551
620
  const lists = [];
552
621
  const add = (s) => { if (lists.length) lines[lines.length - 1] += s; else lines.push(s); };
@@ -569,11 +638,14 @@ export function renderModel(model, { fallbackOf = () => "", clean = RAW } = {})
569
638
  continue;
570
639
  }
571
640
  if (item.t === "toggle") {
572
- add(`<details${attr("data-id", item.id)}${extrasOfItem(item)}${item.open ? " open" : ""}><summary>${inlineOf(item)}</summary>`);
641
+ const h = toggleLevel(item.level);
642
+ add(`<details${attr("data-id", item.id)}${extrasOfItem(item)}${item.open ? " open" : ""}>${h ? `<summary><h${h}>${inlineOf(item)}</h${h}></summary>` : `<summary>${inlineOf(item)}</summary>`}`);
573
643
  stack.push(item.id);
574
644
  continue;
575
645
  }
576
646
  if (item.t === "tool") { add(`<section${attr("data-id", item.id)} data-type="tool">${toolData(item)}${clean.fallback(fallbackOf(item.id))}</section>`); continue; }
647
+ if (item.t === "toc") { add(tocHtml(item, model)); continue; }
648
+ if (item === title && (item.pageIcon || item.pageCoverSrc)) { add(titleHtml(item)); continue; }
577
649
  add(renderLeaf(item, clean, tables));
578
650
  }
579
651
  closeLists();
@@ -705,7 +777,11 @@ export function parseArticle(article) {
705
777
  const P = { parent };
706
778
  const record = envelopeAt(el);
707
779
  if (record && typeof record.t === "string") {
708
- if (knownType(record.t) || record.t === "opaque_block") throw new SyntaxError(`page: an envelope names the known block type ${record.t}`);
780
+ if (record.t === "opaque_block") throw new SyntaxError(`page: an envelope names the known block type ${record.t}`);
781
+ if (knownType(record.t)) {
782
+ items.push(knownRecordItem(idOf(el), record, parent));
783
+ return;
784
+ }
709
785
  const { t, ...fields } = record;
710
786
  items.push({ id: idOf(el), t, parent, ...fields });
711
787
  return;
@@ -713,6 +789,13 @@ export function parseArticle(article) {
713
789
  const onlyImage = tag === "P" && el.children.length === 1 && el.children[0].tagName === "IMG" && !el.textContent.trim();
714
790
  if (tag === "P" && !onlyImage) return push(el, "paragraph", parent, { ...omitDefaults("paragraph", P), ...tf(el) });
715
791
  if (/^H[1-6]$/.test(tag)) return push(el, "heading", parent, { ...omitDefaults("heading", { ...P, level: +tag[1] }), ...tf(el) });
792
+ if (tag === "HEADER" && el.getAttribute("data-page-heading") === ENVELOPE) {
793
+ const icon = el.querySelector(":scope > [data-page-icon]");
794
+ const cover = el.querySelector(":scope > img");
795
+ const [, x, y] = /object-position:\s*([-\d.]+)%\s+([-\d.]+)%/.exec(cover?.getAttribute("style") ?? "") ?? [];
796
+ const cover0 = cover ? { pageCoverSrc: safeSrc(cover.getAttribute("src")), pageCoverAlt: cover.getAttribute("alt") ?? "", pageCoverX: focal(x), pageCoverY: focal(y) } : {};
797
+ return push(el, "heading", parent, { ...omitDefaults("heading", { ...P, level: 1, pageIcon: icon ? icon.textContent : null, ...cover0 }), ...tf(el.querySelector(":scope > h1")) });
798
+ }
716
799
  if (tag === "ASIDE") return push(el, "callout", parent, { ...omitDefaults("callout", P), ...tf(el) });
717
800
  if (tag === "BLOCKQUOTE") return push(el, "quote", parent, { ...omitDefaults("quote", P), ...tf(el) });
718
801
  if (tag === "PRE") {
@@ -720,11 +803,16 @@ export function parseArticle(article) {
720
803
  return push(el, "code_block", parent, { ...omitDefaults("code_block", { ...P, lang: el.getAttribute("data-lang") || "" }), c: (code || el).textContent });
721
804
  }
722
805
  if (tag === "HR") return push(el, "divider", parent, omitDefaults("divider", P));
806
+ if (tag === "NAV" && el.getAttribute("aria-label") === TOC_LABEL) {
807
+ const maxLevel = +(el.getAttribute("data-max-level") ?? 0);
808
+ return push(el, "toc", parent, omitDefaults("toc", { ...P, maxLevel: maxLevel >= 1 && maxLevel <= 6 ? maxLevel : null }));
809
+ }
723
810
  if (tag === "UL" || tag === "OL") return list(el, parent, 0);
724
811
  if (tag === "DETAILS") {
725
812
  const summary = el.querySelector(":scope > summary");
813
+ const head = summary?.querySelector(":scope > h1, :scope > h2, :scope > h3");
726
814
  const at = items.length;
727
- push(el, "toggle", parent, { ...omitDefaults("toggle", { ...P, open: el.hasAttribute("open") }), ...tf(summary) });
815
+ push(el, "toggle", parent, { ...omitDefaults("toggle", { ...P, open: el.hasAttribute("open"), level: head ? Number(head.tagName[1]) : null }), ...tf(summary) });
728
816
  const body = el.ownerDocument.createElement("div");
729
817
  for (const n of [...el.childNodes]) if (n !== summary) body.appendChild(n.cloneNode(true));
730
818
  walk(body, { ref: at });
@@ -1,10 +1,15 @@
1
1
  import toast, { toastPersistent, dismissPersistent } from "../ui/toast-lazy.js";
2
2
  import { state as pmState } from "../vendor/prosemirror.vendor.js";
3
+ import { mountEditorUI } from "../ui/editor-ui.js";
3
4
 
4
5
  export const NOTICE_TEXT = "Some text you typed was kept aside when its block moved or was removed.";
5
6
 
6
- const STYLE_ID = "page-recover-style";
7
+ // The control and its panel sit in one shadow root inside the page shell, so the page's
8
+ // CSS cannot restyle them. The page's --page-* tokens still reach them, and they keep
9
+ // the page's font and colour.
7
10
  const STYLES = `
11
+ :host { font: inherit !important; color: inherit !important; }
12
+ .page-recover-root { display: contents; }
8
13
  .page-recover { position: fixed; right: 16px; bottom: 16px; z-index: 20; min-height: 36px; padding: 0 14px; font: inherit; font-size: 14px; color: var(--page-ink); background: var(--page-pop-bg); border: 1px solid var(--page-chrome-line-rest); border-radius: 999px; cursor: pointer; }
9
14
  .page-recover[hidden], .page-recover-panel[hidden] { display: none; }
10
15
  .page-recover-panel { position: fixed; right: 16px; bottom: 64px; z-index: 21; width: min(380px, calc(100vw - 32px)); max-height: 60vh; overflow-y: auto; color: var(--page-ink); background: var(--page-pop-bg); border: 1px solid var(--page-chrome-line-rest); border-radius: var(--page-chrome-radius); padding: 8px; box-sizing: border-box; }
@@ -33,13 +38,6 @@ const el = (doc, tag, className, attrs = {}) => {
33
38
  return node;
34
39
  };
35
40
 
36
- function ensureStyle(doc) {
37
- if (doc.getElementById(STYLE_ID)) return;
38
- const style = doc.createElement("style");
39
- style.id = STYLE_ID;
40
- style.textContent = STYLES;
41
- doc.head.append(style);
42
- }
43
41
 
44
42
  function previewOf(doc, record) {
45
43
  const out = el(doc, "div", "page-recover-text");
@@ -74,13 +72,14 @@ export function focusBlock(view, id) {
74
72
 
75
73
  export function createRecoverList({ binding, mount, ownTokens = [], onRestored = () => {}, onStale = () => {} }) {
76
74
  const doc = mount.ownerDocument;
77
- ensureStyle(doc);
78
75
  const own = new Set(ownTokens.filter(Boolean));
79
76
  const button = el(doc, "button", "page-recover", { type: "button", "aria-haspopup": "dialog", "aria-expanded": "false" });
80
77
  const panel = el(doc, "div", "page-recover-panel", { role: "dialog", "aria-label": "Recover changes" });
81
78
  button.hidden = true;
82
79
  panel.hidden = true;
83
- mount.append(button, panel);
80
+ const content = el(doc, "div", "page-recover-root");
81
+ content.append(button, panel);
82
+ const ui = mountEditorUI({ name: "page-recover", content, css: [STYLES], parent: mount });
84
83
 
85
84
  let snapshot = { recoverable: [], notices: [] };
86
85
  let target = null;
@@ -186,8 +185,7 @@ export function createRecoverList({ binding, mount, ownTokens = [], onRestored =
186
185
  destroy() {
187
186
  off();
188
187
  dismissPersistent(NOTICE_TEXT);
189
- button.remove();
190
- panel.remove();
188
+ ui.remove();
191
189
  },
192
190
  };
193
191
  }