@panphora/clayjs 1.23.0 → 1.24.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 (471) hide show
  1. package/dist/all.js +1 -1
  2. package/dist/blockeditor/themes/light-1.css +431 -0
  3. package/dist/clay-dom.js +1 -1
  4. package/dist/clay-events.js +1 -1
  5. package/dist/clay-internals.js +1 -1
  6. package/dist/clay-options.js +1 -1
  7. package/dist/clay-router.js +1 -1
  8. package/dist/clay-ui.js +1 -1
  9. package/dist/clay-utils.js +1 -1
  10. package/dist/clay.js +1 -1
  11. package/dist/clay.standalone.js +30285 -26613
  12. package/dist/m/c-277QP5ET.js +1 -0
  13. package/dist/m/c-2BLVA6IN.js +5 -0
  14. package/dist/m/c-2OJMOUPC.js +1 -0
  15. package/dist/m/c-2PVGJFI5.js +1 -0
  16. package/dist/m/{c-AYVGD6A6.js → c-3UW5EJ77.js} +1 -1
  17. package/dist/m/{c-T5NK2TVY.js → c-42ZNV7LI.js} +1 -1
  18. package/dist/m/{c-3TLG3OLG.js → c-46LJAZZJ.js} +1 -1
  19. package/dist/m/c-47IBJGPQ.js +1 -0
  20. package/dist/m/c-5FXEKU4Y.js +1 -0
  21. package/dist/m/c-5KXDKC5G.js +1 -0
  22. package/dist/m/{c-EUGJVHDD.js → c-5RZNFTWD.js} +1 -1
  23. package/dist/m/c-65LJU2H2.js +72 -0
  24. package/dist/m/{c-NQJRVJ56.js → c-6IJEVE6B.js} +1 -1
  25. package/dist/m/{c-NW54NHKE.js → c-6LEYVQJK.js} +1 -1
  26. package/dist/m/{c-GSRLXYWL.js → c-6Q6RGFBF.js} +1 -1
  27. package/dist/m/c-6RGEQNVV.js +1 -0
  28. package/dist/m/c-7CM4GMTS.js +6 -0
  29. package/dist/m/c-7NCWENHV.js +1 -0
  30. package/dist/m/c-7V6MGMX2.js +1 -0
  31. package/dist/m/{c-LKSL4AUJ.js → c-7WZSUTYP.js} +1 -1
  32. package/dist/m/c-A4L7APIU.js +1 -0
  33. package/dist/m/c-APGHGDZM.js +1 -0
  34. package/dist/m/c-AT7GLQGV.js +34 -0
  35. package/dist/m/{c-ZRXJD4G6.js → c-B7GOFGQR.js} +1 -1
  36. package/dist/m/{c-KDXIJEEF.js → c-BGN7RCTJ.js} +1 -1
  37. package/dist/m/c-BKM46LUJ.js +1 -0
  38. package/dist/m/c-BOMQIQ3V.js +1 -0
  39. package/dist/m/{c-62HZW5DH.js → c-C5AKJVRH.js} +1 -1
  40. package/dist/m/{c-BXYSDKAN.js → c-CJ7QYEWI.js} +1 -1
  41. package/dist/m/c-CTGRDT6E.js +1 -0
  42. package/dist/m/c-CV4T65JE.js +6 -0
  43. package/dist/m/c-CVSWLX3X.js +1 -0
  44. package/dist/m/c-CZHTXGJS.js +1 -0
  45. package/dist/m/c-D7NT5S4F.js +1 -0
  46. package/dist/m/c-DD26VXAP.js +1 -0
  47. package/dist/m/{c-ANNFZFLN.js → c-DDS23EY6.js} +1 -1
  48. package/dist/m/{c-ALDVFPWL.js → c-DFKBGSN2.js} +1 -1
  49. package/dist/m/c-DIKR7H57.js +147 -0
  50. package/dist/m/c-DXPOFLEJ.js +1 -0
  51. package/dist/m/c-EDE45NM7.js +1 -0
  52. package/dist/m/c-EILLN2H2.js +1 -0
  53. package/dist/m/c-EODTTNVA.js +1 -0
  54. package/dist/m/{c-G6COVIZB.js → c-ESK4S67I.js} +1 -1
  55. package/dist/m/c-FDWR3FL7.js +1 -0
  56. package/dist/m/{c-WQZTI5P2.js → c-FEC6LGFF.js} +1 -1
  57. package/dist/m/c-FLEIU6CG.js +1 -0
  58. package/dist/m/c-FQAQRXGK.js +1 -0
  59. package/dist/m/{c-W4JCVLAB.js → c-FSQXFG5T.js} +1 -1
  60. package/dist/m/c-FVPNX2GO.js +135 -0
  61. package/dist/m/c-FYDKYW6E.js +1 -0
  62. package/dist/m/c-GNI7WHKF.js +32 -0
  63. package/dist/m/c-GO635CRU.js +3 -0
  64. package/dist/m/c-H3FNLBHN.js +2 -0
  65. package/dist/m/c-HDVH3MVC.js +72 -0
  66. package/dist/m/c-HIX5H5L7.js +1 -0
  67. package/dist/m/c-HKSLOVU4.js +1 -0
  68. package/dist/m/{c-SGRIYOAJ.js → c-HL6BLJNA.js} +1 -1
  69. package/dist/m/c-HTLYXCUH.js +1 -0
  70. package/dist/m/{c-QIR5CAKM.js → c-IUL7PU4P.js} +1 -1
  71. package/dist/m/c-IXO7EI2Q.js +1 -0
  72. package/dist/m/{c-W5E5P2TZ.js → c-JQF2EUCG.js} +1 -1
  73. package/dist/m/{c-NEL7HQW3.js → c-JWDCQL6J.js} +1 -1
  74. package/dist/m/c-KQKKIVLW.js +20 -0
  75. package/dist/m/c-LATNQ6Q5.js +1 -0
  76. package/dist/m/c-LD6UVV5R.js +1 -0
  77. package/dist/m/c-LS7IVQVW.js +1 -0
  78. package/dist/m/{c-JCOQVZYS.js → c-LSVN3OLG.js} +1 -1
  79. package/dist/m/{c-JDZDF2QM.js → c-LTSPHVAK.js} +1 -1
  80. package/dist/m/c-MFOSMAVM.js +3 -0
  81. package/dist/m/c-MJ7GVE46.js +1 -0
  82. package/dist/m/c-MP6S4AZU.js +6 -0
  83. package/dist/m/c-MQKSKQHG.js +2 -0
  84. package/dist/m/{c-UHUNXWKN.js → c-MQYEDF3Q.js} +1 -1
  85. package/dist/m/{c-IHUWUKIU.js → c-MR75YPRT.js} +1 -1
  86. package/dist/m/c-ND3Q2G2I.js +1 -0
  87. package/dist/m/c-NEQRFC4O.js +1 -0
  88. package/dist/m/{c-5FKRZNJV.js → c-NFQFV7OP.js} +1 -1
  89. package/dist/m/c-NHXOBD6A.js +1 -0
  90. package/dist/m/{c-QIKT6SKM.js → c-NICICT4P.js} +1 -1
  91. package/dist/m/c-NQAPWM7O.js +1 -0
  92. package/dist/m/{c-QUGCKMWF.js → c-NVU3DORS.js} +1 -1
  93. package/dist/m/{c-LWIDDWAR.js → c-OCYG4NBQ.js} +22 -22
  94. package/dist/m/c-OH2FPYSY.js +19 -0
  95. package/dist/m/c-OYHI67B6.js +1 -0
  96. package/dist/m/{c-R2XUODVY.js → c-OYW5MFPZ.js} +1 -1
  97. package/dist/m/{c-5B4YBZXC.js → c-P2HKMJAW.js} +1 -1
  98. package/dist/m/{c-TSBVMWAH.js → c-PCNJETUA.js} +1 -1
  99. package/dist/m/c-PDBNCJCT.js +1 -0
  100. package/dist/m/c-PGSBXHUE.js +1 -0
  101. package/dist/m/{c-5TIZ2I64.js → c-PYG2NGWU.js} +1 -1
  102. package/dist/m/c-Q26XHBLQ.js +1 -0
  103. package/dist/m/c-Q6BG3ZLO.js +1 -0
  104. package/dist/m/c-QENKN7QI.js +1 -0
  105. package/dist/m/c-QQFHEODI.js +1 -0
  106. package/dist/m/c-QTEUO2K6.js +1 -0
  107. package/dist/m/c-R23UHMXG.js +1 -0
  108. package/dist/m/c-RETTCOWO.js +10 -0
  109. package/dist/m/c-SE3SIY7Y.js +7 -0
  110. package/dist/m/{c-XX75FFNL.js → c-SGGGCIVD.js} +1 -1
  111. package/dist/m/c-SGH3UTF3.js +1 -0
  112. package/dist/m/c-SIM7Z3U7.js +1 -0
  113. package/dist/m/{c-X5LNHET5.js → c-SKMIR5HQ.js} +1 -1
  114. package/dist/m/{c-R27DWQKX.js → c-STRI73GQ.js} +1 -1
  115. package/dist/m/c-SUXHUL7U.js +1 -0
  116. package/dist/m/c-SXGEWPFC.js +10 -0
  117. package/dist/m/c-SXNSSHPP.js +1 -0
  118. package/dist/m/c-T3P3AXEW.js +1 -0
  119. package/dist/m/{c-PXLTUYZC.js → c-TFLRT5JX.js} +1 -1
  120. package/dist/m/{c-YCLU4UNT.js → c-TGIMBAWE.js} +1 -1
  121. package/dist/m/c-TGSHHFO6.js +1 -0
  122. package/dist/m/c-U4NTUVDZ.js +1 -0
  123. package/dist/m/c-UOOIF2AL.js +1 -0
  124. package/dist/m/{c-6TYGD5AB.js → c-UOUUI265.js} +1 -1
  125. package/dist/m/c-V2U3F4QX.js +1 -0
  126. package/dist/m/c-V2V5FKXX.js +1 -0
  127. package/dist/m/c-VBXRXTVS.js +26 -0
  128. package/dist/m/c-VHSMPITY.js +1 -0
  129. package/dist/m/c-VPXCXBDT.js +1 -0
  130. package/dist/m/c-WCG6AKA7.js +1 -0
  131. package/dist/m/c-WNOLMHI2.js +1 -0
  132. package/dist/m/{c-CRPIDGXC.js → c-X6MOYATI.js} +1 -1
  133. package/dist/m/{c-FQGHR32O.js → c-X75G43SZ.js} +1 -1
  134. package/dist/m/c-XB6EAIAR.js +13 -0
  135. package/dist/m/c-XMIDHEKF.js +1 -0
  136. package/dist/m/c-XUZMRQ7O.js +4 -0
  137. package/dist/m/{c-2Z22FCFK.js → c-XW5TIYYB.js} +1 -1
  138. package/dist/m/c-YDW4VCHP.js +1 -0
  139. package/dist/m/{c-QGAPG7OM.js → c-YLHTD3KX.js} +1 -1
  140. package/dist/m/c-YNIEIPBS.js +1 -0
  141. package/dist/m/c-Z4G2UK6T.js +4 -0
  142. package/dist/m/c-Z6MROEQ4.js +1 -0
  143. package/dist/m/c-ZFO5RW6G.js +2 -0
  144. package/dist/m/c-ZGCO4J3H.js +8 -0
  145. package/dist/m/c-ZKKAF4UT.js +3 -0
  146. package/dist/m/c-ZRGEN6QQ.js +4 -0
  147. package/dist/m/core/{admin-attrs-U7IJNYBG.js → admin-attrs-ONRWVXPK.js} +1 -1
  148. package/dist/m/core/{autosave-F5YQCKVL.js → autosave-TBKAAAFB.js} +1 -1
  149. package/dist/m/core/conflict-notice-FOEE6I7E.js +1 -0
  150. package/dist/m/core/draft-mode-4MCL3LYI.js +1 -0
  151. package/dist/m/core/{host-permission-6EVJGNPL.js → host-permission-X4BENZEU.js} +1 -1
  152. package/dist/m/core/{is-edit-mode-GCX6767E.js → is-edit-mode-FFHCQ5DR.js} +1 -1
  153. package/dist/m/core/{persist-CJXIL7D4.js → persist-6ILUR34S.js} +1 -1
  154. package/dist/m/core/{recovery-DRFZRJED.js → recovery-APWADU4K.js} +1 -1
  155. package/dist/m/core/save-6HT2LABE.js +1 -0
  156. package/dist/m/core/save-core-EVMNZQ4V.js +1 -0
  157. package/dist/m/core/site-edits-G4BOZMV4.js +1 -0
  158. package/dist/m/core/{unsaved-warning-HNQVTA2D.js → unsaved-warning-ITZDIZ2I.js} +1 -1
  159. package/dist/m/internals/{index-NRPNDTSA.js → index-HS3CQDFW.js} +1 -1
  160. package/dist/m/loader-GLLVDUZA.js +1 -0
  161. package/dist/m/manifest-50FF1C45.js +1 -0
  162. package/dist/m/manifest-edit-BE1A621D.js +1 -0
  163. package/dist/m/manifest.json +2072 -1811
  164. package/dist/m/page/editor-KAZDJNND.js +307 -0
  165. package/dist/m/plugins/ai-edit-LABECCSN.js +6 -0
  166. package/dist/m/plugins/{cms-H7DTMUQX.js → cms-T2HLI7JG.js} +16 -16
  167. package/dist/m/plugins/{demo-42BSYQ7T.js → demo-T7B4RIKL.js} +1 -1
  168. package/dist/m/plugins/{derive-QVI3LI3A.js → derive-6LPJOCAV.js} +1 -1
  169. package/dist/m/plugins/indicator-J4ABFARX.js +1 -0
  170. package/dist/m/plugins/{live-DCUBKXY4.js → live-PGBIEMGB.js} +1 -1
  171. package/dist/m/plugins/menu-YZL3X2AJ.js +1 -0
  172. package/dist/m/plugins/page-WOCNX2IN.js +2 -0
  173. package/dist/m/plugins/page-view-SJODOOGE.js +1 -0
  174. package/dist/m/plugins/{people-5XRNRP5U.js → people-C4TCWFOQ.js} +1 -1
  175. package/dist/m/plugins/{quickcrop-WWF5I422.js → quickcrop-X5MRIBAP.js} +2 -2
  176. package/dist/m/plugins/richclay-Y2NV44NA.js +549 -0
  177. package/dist/m/plugins/sortable-XCHQG65Z.js +1 -0
  178. package/dist/m/plugins/{source-6BKMK4PO.js → source-YK7MO23W.js} +1 -1
  179. package/dist/m/plugins/{undo-3JEYK5QY.js → undo-VLRBQNPN.js} +1 -1
  180. package/dist/m/plugins/upgrade-NNTJBSK2.js +1 -0
  181. package/dist/m/plugins/{upload-TTCQRIM5.js → upload-ZKKJV76X.js} +1 -1
  182. package/dist/m/plugins/visitor-drafts-RTZNONHT.js +20 -0
  183. package/dist/m/plugins/{visitor-drafts-owner-Z5B2OQBR.js → visitor-drafts-owner-LHUHFU3L.js} +1 -1
  184. package/dist/m/plugins/{visitor-menu-4LQMKLPP.js → visitor-menu-FY4KM2SW.js} +1 -1
  185. package/dist/m/plugins/wire-M2NR354P.js +1 -0
  186. package/dist/m/{reader-core-POFQCKRV.js → reader-core-T2S3JC4E.js} +2 -2
  187. package/dist/m/sync/live-sync-Z64YREWQ.js +1 -0
  188. package/dist/m/ui/index-MGTWOW2C.js +1 -0
  189. package/dist/m/vendor/{sap-core.vendor-OA5SKL7Q.js → sap-core.vendor-QAEPMETX.js} +1 -1
  190. package/dist/offline-manifest.json +1250 -1082
  191. package/dist/server/core.cjs +132 -109
  192. package/dist/server/page-compaction-worker.cjs +5 -5
  193. package/dist/server/rooms.mjs +3 -1
  194. package/docs/guide.md +89 -44
  195. package/entries/clay-data.js +1 -1
  196. package/entries/sap.js +1 -1
  197. package/package.json +5 -3
  198. package/src/blockeditor/themes/content.css +70 -0
  199. package/src/blockeditor/themes/light-1.css +431 -0
  200. package/src/blockeditor/themes/light-1.source.css +270 -0
  201. package/src/blockeditor/themes/light-2.css +211 -0
  202. package/src/blockeditor/themes/light-3.css +130 -0
  203. package/src/blockeditor/themes/light-4.css +299 -0
  204. package/src/core/conflict-notice.js +28 -0
  205. package/src/core/draft-mode.js +6 -0
  206. package/src/core/host-meta.js +6 -6
  207. package/src/core/is-edit-mode.js +9 -3
  208. package/src/core/mode-support.js +3 -0
  209. package/src/core/mode-switch.js +4 -4
  210. package/src/core/mode-transition.js +3 -1
  211. package/src/core/page-format-wire.js +1 -1
  212. package/src/core/page-format.js +8 -8
  213. package/src/core/save-accepted.js +6 -7
  214. package/src/core/save-core.js +52 -23
  215. package/src/core/save-failure-notice.js +37 -0
  216. package/src/core/save-feedback.js +6 -0
  217. package/src/core/save-replace.js +1 -1
  218. package/src/core/save-size.js +2 -2
  219. package/src/core/save.js +78 -15
  220. package/src/core/site-edits.js +166 -0
  221. package/src/core/unsaved-warning.js +2 -2
  222. package/src/core/upgrade-run.js +4 -4
  223. package/src/lib/ai-comment.js +23 -0
  224. package/src/lib/effect.js +8 -0
  225. package/src/lib/idb-error-code.js +20 -0
  226. package/src/live/fast-lane.js +10 -10
  227. package/src/live/local-lane.js +10 -10
  228. package/src/live/page-compaction.js +8 -8
  229. package/src/live/server-lane.js +1 -1
  230. package/src/loader-logic.js +48 -18
  231. package/src/loader.js +11 -6
  232. package/src/page/adopt-boot.js +1 -1
  233. package/src/page/adopt.js +2 -2
  234. package/src/page/ai-area.js +182 -0
  235. package/src/page/ai-preview.js +80 -0
  236. package/src/page/ai-surface.js +257 -0
  237. package/src/page/ai-tool.js +308 -145
  238. package/src/page/announce.js +2 -2
  239. package/src/page/awareness.js +18 -18
  240. package/src/page/blocks.js +35 -34
  241. package/src/page/blocksel.js +2 -2
  242. package/src/page/board-drag.js +11 -11
  243. package/src/page/board-face.js +1 -1
  244. package/src/page/board-panel.js +26 -26
  245. package/src/page/board-style.js +127 -127
  246. package/src/page/board-view.js +48 -48
  247. package/src/page/chart.js +29 -29
  248. package/src/page/checkpoint-proof.js +19 -19
  249. package/src/page/chrome.js +74 -65
  250. package/src/page/clipboard-shape.js +1 -1
  251. package/src/page/csv-import.js +4 -4
  252. package/src/page/drag.js +5 -5
  253. package/src/page/editor.js +301 -296
  254. package/src/page/export-html.js +8 -8
  255. package/src/page/features/checklist.js +36 -36
  256. package/src/page/features/export-html.js +19 -19
  257. package/src/page/features/export-markdown.js +10 -10
  258. package/src/page/features/import-markdown.js +13 -13
  259. package/src/page/features/media.js +50 -50
  260. package/src/page/features/table.js +17 -17
  261. package/src/page/features/title-cover.js +17 -17
  262. package/src/page/features/title-icon.js +7 -7
  263. package/src/page/features/toc.js +1 -1
  264. package/src/page/features/tool.js +42 -18
  265. package/src/page/format-command.js +4 -4
  266. package/src/page/format-gate.js +6 -6
  267. package/src/page/format-host.js +6 -6
  268. package/src/page/format-level.js +3 -3
  269. package/src/page/format-native-commands.js +2 -2
  270. package/src/page/highlight-slot.js +1 -1
  271. package/src/page/highlight.js +4 -4
  272. package/src/page/history-intent.js +2 -2
  273. package/src/page/image-actions.js +4 -4
  274. package/src/page/link.js +10 -10
  275. package/src/page/media.js +3 -3
  276. package/src/page/mention-picker.js +7 -7
  277. package/src/page/merge.js +1 -1
  278. package/src/page/placeholder.js +3 -3
  279. package/src/page/projection.js +11 -11
  280. package/src/page/reader-patch.js +2 -2
  281. package/src/page/recover.js +26 -26
  282. package/src/page/recovery-ui.js +28 -28
  283. package/src/page/rich/chart.js +1 -1
  284. package/src/page/rich/page-tool.js +21 -6
  285. package/src/page/rich/tool-runtime.js +3 -2
  286. package/src/page/save-projection.js +2 -2
  287. package/src/page/save-states.js +9 -9
  288. package/src/page/schema.js +9 -9
  289. package/src/page/table-style.js +21 -21
  290. package/src/page/toc-link.js +1 -1
  291. package/src/page/tool-capability.js +8 -3
  292. package/src/page/tool-transport.js +52 -0
  293. package/src/page/tool-views.js +4 -0
  294. package/src/page/tools.js +6 -1
  295. package/src/page/view.js +6 -6
  296. package/src/page/ybind/binding.js +1 -1
  297. package/src/page/ybind/conversion.js +1 -1
  298. package/src/page/ybind/layout.js +4 -4
  299. package/src/page/ybind/migrate.js +1 -1
  300. package/src/page/ybind/origins.js +2 -2
  301. package/src/page/ybind/provider.js +2 -2
  302. package/src/page/ybind/recovery-proof.js +3 -3
  303. package/src/page/ybind/recovery-replay.js +2 -2
  304. package/src/plugins/ai-edit/picker.js +235 -0
  305. package/src/plugins/ai-edit.js +220 -34
  306. package/src/plugins/indicator-chip.js +39 -34
  307. package/src/plugins/indicator.js +13 -4
  308. package/src/plugins/live.js +21 -13
  309. package/src/plugins/menu/actions.js +89 -17
  310. package/src/plugins/menu/seo.js +32 -6
  311. package/src/plugins/menu/shell-style.js +26 -7
  312. package/src/plugins/menu/shell.js +12 -7
  313. package/src/plugins/menu/variants.js +6 -10
  314. package/src/plugins/menu/visitor.js +44 -34
  315. package/src/plugins/menu.js +3 -2
  316. package/src/plugins/page-view.js +2 -2
  317. package/src/plugins/page.js +257 -98
  318. package/src/plugins/sortable.js +7 -0
  319. package/src/plugins/upgrade.js +2 -1
  320. package/src/plugins/visitor-drafts/commit.js +303 -0
  321. package/src/plugins/visitor-drafts/idb.js +221 -0
  322. package/src/plugins/visitor-drafts/intro-style.js +1 -1
  323. package/src/plugins/visitor-drafts/intro.js +8 -25
  324. package/src/plugins/visitor-drafts/prompt.js +30 -4
  325. package/src/plugins/visitor-drafts/session.js +345 -0
  326. package/src/plugins/visitor-drafts/store.js +351 -32
  327. package/src/plugins/visitor-drafts.js +158 -27
  328. package/src/server/checkpoint/index.js +8 -8
  329. package/src/server/rooms/index.js +2 -2
  330. package/src/server/rooms/live-data-rooms.js +35 -35
  331. package/src/server/rooms/live-page-history.js +2 -2
  332. package/src/server/rooms/page-admission.js +34 -6
  333. package/src/server/rooms/page-conversion.js +1 -1
  334. package/src/server/rooms/page-lineage.js +4 -4
  335. package/src/server/rooms/page-rebase.js +4 -4
  336. package/src/server/rooms/page-room-conformance.js +14 -14
  337. package/src/server/rooms/page-state.js +2 -2
  338. package/src/server/rooms/page-write-admission.js +7 -7
  339. package/src/server/rooms/page-write-guard.js +3 -3
  340. package/src/sync/data-guard-notice.js +265 -0
  341. package/src/sync/live-sync.js +54 -11
  342. package/src/sync/page-relay.js +4 -4
  343. package/src/sync/presence-store.js +1 -1
  344. package/src/sync/presence-target.js +3 -3
  345. package/src/sync/presence.js +1 -1
  346. package/src/sync/stream.js +54 -13
  347. package/src/sync/wire-profile.js +8 -3
  348. package/src/ui/bevel.js +1 -1
  349. package/src/ui/index.js +9 -10
  350. package/src/ui/skins/cms.js +1 -1
  351. package/src/ui/skins/quickcrop.js +1 -1
  352. package/src/ui/skins/richclay.js +2 -2
  353. package/src/ui/toast-lazy.js +12 -3
  354. package/src/ui/toast.js +9 -3
  355. package/src/vendor/hyper-html-api-data.vendor.js +1 -1
  356. package/src/vendor/hyper-html-api-upgrade.vendor.js +2 -2
  357. package/src/vendor/hypercms.vendor.js +16 -16
  358. package/src/vendor/richclay.vendor.js +48 -20
  359. package/src/vendor/sap-core.vendor.js +1 -1
  360. package/tool-generation/context.md +44 -0
  361. package/tool-generation/system.md +23 -0
  362. package/dist/m/c-24PMUJIV.js +0 -2
  363. package/dist/m/c-2AYVYEI4.js +0 -1
  364. package/dist/m/c-2AZDZWCK.js +0 -1
  365. package/dist/m/c-2L6O5PDS.js +0 -6
  366. package/dist/m/c-2RYOGUQM.js +0 -2
  367. package/dist/m/c-2ZVOEU4M.js +0 -1
  368. package/dist/m/c-37NAONZA.js +0 -1
  369. package/dist/m/c-3GJ4SDE2.js +0 -1
  370. package/dist/m/c-3O7OBDCM.js +0 -1
  371. package/dist/m/c-5OJ7YF2N.js +0 -1
  372. package/dist/m/c-5WMXEKFH.js +0 -135
  373. package/dist/m/c-6RDOKLN7.js +0 -1
  374. package/dist/m/c-A4IP6MBC.js +0 -1
  375. package/dist/m/c-A6L3FMUS.js +0 -1
  376. package/dist/m/c-ATKAOH23.js +0 -1
  377. package/dist/m/c-B6O7AJYG.js +0 -32
  378. package/dist/m/c-BCGWJYXW.js +0 -1
  379. package/dist/m/c-BGKAT2FL.js +0 -7
  380. package/dist/m/c-BYTKL6UX.js +0 -1
  381. package/dist/m/c-DHBRA6DL.js +0 -1
  382. package/dist/m/c-DTMZ3ZHI.js +0 -1
  383. package/dist/m/c-E3ZXARWA.js +0 -1
  384. package/dist/m/c-EK63G3CG.js +0 -1
  385. package/dist/m/c-ELYIIYRS.js +0 -1
  386. package/dist/m/c-EXKHPOVC.js +0 -3
  387. package/dist/m/c-FCSZ3DC5.js +0 -20
  388. package/dist/m/c-FTWGYI5E.js +0 -1
  389. package/dist/m/c-G4PWUDD5.js +0 -1
  390. package/dist/m/c-GBKB5WDL.js +0 -2
  391. package/dist/m/c-GBTVCJXC.js +0 -1
  392. package/dist/m/c-GC2HICFJ.js +0 -1
  393. package/dist/m/c-GRWMD6O5.js +0 -1
  394. package/dist/m/c-HCNWJE4A.js +0 -4
  395. package/dist/m/c-HG2C77BM.js +0 -4
  396. package/dist/m/c-JGHEACGK.js +0 -1
  397. package/dist/m/c-JGLX6TBK.js +0 -1
  398. package/dist/m/c-JNRKHYWO.js +0 -1
  399. package/dist/m/c-KBS3UV6B.js +0 -1
  400. package/dist/m/c-KQ7E3PYY.js +0 -1
  401. package/dist/m/c-L3F5ZLIV.js +0 -1
  402. package/dist/m/c-L4KMT7FO.js +0 -6
  403. package/dist/m/c-L5VFATT6.js +0 -1
  404. package/dist/m/c-LCYPMULG.js +0 -1
  405. package/dist/m/c-LIGQYZ7M.js +0 -6
  406. package/dist/m/c-LKIWEPAV.js +0 -1
  407. package/dist/m/c-MPSKIU2I.js +0 -1
  408. package/dist/m/c-N7JPUPGC.js +0 -1
  409. package/dist/m/c-NK33MMYF.js +0 -1
  410. package/dist/m/c-NQLWOHLH.js +0 -10
  411. package/dist/m/c-NTHUTABN.js +0 -1
  412. package/dist/m/c-NWX3MFT4.js +0 -1
  413. package/dist/m/c-OKXI52N7.js +0 -1
  414. package/dist/m/c-OPONJ2UK.js +0 -128
  415. package/dist/m/c-OWQWOGYI.js +0 -1
  416. package/dist/m/c-P6Q2ZTFQ.js +0 -1
  417. package/dist/m/c-QEN6HZCA.js +0 -1
  418. package/dist/m/c-QIXT3Q7C.js +0 -28
  419. package/dist/m/c-QM5LXRDT.js +0 -9
  420. package/dist/m/c-QYYUVLVG.js +0 -1
  421. package/dist/m/c-RQRMPZXD.js +0 -1
  422. package/dist/m/c-SBCBXKOZ.js +0 -26
  423. package/dist/m/c-SKF5HL4I.js +0 -4
  424. package/dist/m/c-SRPC3VBE.js +0 -1
  425. package/dist/m/c-TANBH7FI.js +0 -1
  426. package/dist/m/c-THGQQDYY.js +0 -1
  427. package/dist/m/c-UD5JZTDL.js +0 -1
  428. package/dist/m/c-UDGEFWNU.js +0 -1
  429. package/dist/m/c-UGNV5MFB.js +0 -1
  430. package/dist/m/c-VIRFF5HG.js +0 -8
  431. package/dist/m/c-VJYEVRYK.js +0 -1
  432. package/dist/m/c-VQCEOGKH.js +0 -13
  433. package/dist/m/c-VYJ7O4RI.js +0 -34
  434. package/dist/m/c-W7IPVCAA.js +0 -1
  435. package/dist/m/c-WBGWGOM7.js +0 -1
  436. package/dist/m/c-WJ5DRBHT.js +0 -72
  437. package/dist/m/c-X5WC4PX5.js +0 -1
  438. package/dist/m/c-XCFQEWW6.js +0 -3
  439. package/dist/m/c-XGH4GS2T.js +0 -1
  440. package/dist/m/c-XLQ3BDMM.js +0 -1
  441. package/dist/m/c-ZQXNHZZT.js +0 -72
  442. package/dist/m/core/conflict-notice-42H4ASLA.js +0 -1
  443. package/dist/m/core/draft-mode-WSQAT67S.js +0 -1
  444. package/dist/m/core/save-ESPSQPLV.js +0 -1
  445. package/dist/m/core/save-core-6SQHOR6W.js +0 -1
  446. package/dist/m/loader-FBDE2UAB.js +0 -1
  447. package/dist/m/manifest-1D2F5CA5.js +0 -1
  448. package/dist/m/manifest-edit-F7CC5CFD.js +0 -1
  449. package/dist/m/page/editor-OSKOW6RS.js +0 -304
  450. package/dist/m/plugins/ai-edit-VV4QTINH.js +0 -6
  451. package/dist/m/plugins/indicator-WVPGMOZ7.js +0 -1
  452. package/dist/m/plugins/menu-Q4MFFQ6E.js +0 -1
  453. package/dist/m/plugins/page-OAWUJQEL.js +0 -2
  454. package/dist/m/plugins/page-view-DZ26ZDDQ.js +0 -1
  455. package/dist/m/plugins/richclay-PGOOJ4OK.js +0 -517
  456. package/dist/m/plugins/sortable-266HY6TR.js +0 -1
  457. package/dist/m/plugins/upgrade-BNZVFHMZ.js +0 -1
  458. package/dist/m/plugins/visitor-drafts-2AUYKAIJ.js +0 -20
  459. package/dist/m/plugins/wire-W2EV36KZ.js +0 -1
  460. package/dist/m/sync/live-sync-XGUPHI3I.js +0 -1
  461. package/dist/m/ui/index-VGYAKAKI.js +0 -1
  462. package/dist/page/themes/light-1.css +0 -431
  463. package/src/page/themes/content.css +0 -70
  464. package/src/page/themes/light-1.css +0 -431
  465. package/src/page/themes/light-1.source.css +0 -270
  466. package/src/page/themes/light-2.css +0 -211
  467. package/src/page/themes/light-3.css +0 -130
  468. package/src/page/themes/light-4.css +0 -299
  469. /package/dist/m/{c-FILLTJA7.js → c-QTTJYJMA.js} +0 -0
  470. /package/dist/m/plugins/{quickcrop-WWF5I422.js.LEGAL.txt → quickcrop-X5MRIBAP.js.LEGAL.txt} +0 -0
  471. /package/dist/m/plugins/{richclay-PGOOJ4OK.js.LEGAL.txt → richclay-Y2NV44NA.js.LEGAL.txt} +0 -0
@@ -17,44 +17,44 @@ const N = schema.nodes;
17
17
  const RETRY = new Set(["timeout", "network", "error", "bad-response"]);
18
18
 
19
19
  export const MEDIA_CSS = `
20
- .page-editor .page-image { margin-inline: 0; }
21
- .page-image-frame { position: relative; margin: 0 auto; max-width: 100%; }
22
- .page-image-frame img { display: block; width: 100%; height: auto; border-radius: var(--page-image-radius, 6px); }
23
- .page-image[data-broken] .page-image-frame { min-height: 80px; background: var(--page-code-bg); border-radius: var(--page-image-radius, 6px); }
24
- .page-image-handle { position: absolute; top: 50%; inset-inline-end: 6px; width: 6px; height: 36px; margin-top: -18px; border-radius: 3px; background: var(--page-chrome-ink-moved); opacity: 0; cursor: ew-resize; touch-action: none; transition: opacity var(--page-fade); }
25
- .page-image:hover .page-image-handle, .page-image.is-selected .page-image-handle { opacity: 1; }
26
- .page-editor .page-image.page-block-selected { background: none; box-shadow: none; }
27
- .page-editor .page-image.page-block-selected .page-image-frame { box-shadow: 0 0 0 6px var(--page-block-selected, rgba(88, 120, 170, 0.12)); border-radius: var(--page-image-radius, 6px); }
28
- .page-image[data-align="left"] .page-image-frame { margin-left: 0; margin-right: auto; }
29
- .page-image[data-align="right"] .page-image-frame { margin-left: auto; margin-right: 0; }
30
- .page-image[data-align="left"] .page-image-caption { text-align: left; }
31
- .page-image[data-align="right"] .page-image-caption { text-align: right; }
32
- .page-image-align { position: absolute; top: 8px; inset-inline-end: 8px; display: none; gap: 1px; padding: 2px; background: var(--page-pop-bg); color: var(--page-pop-ink); border: 1px solid var(--page-pop-line); box-shadow: var(--page-pop-shadow); border-radius: 7px; }
33
- .page-image.is-selected .page-image-align, .page-image.page-block-selected .page-image-align { display: flex; }
34
- .page-image-align button { display: grid; place-items: center; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 5px; background: none; color: inherit; cursor: pointer; }
35
- .page-image-align button:hover, .page-image-align button[aria-pressed="true"] { background: var(--page-pop-hover); }
36
- .page-image.is-selected .page-image-frame img { outline: 2px solid var(--page-selection); outline-offset: 2px; }
37
- .page-image-caption { margin-top: 6px; color: var(--page-ink-soft); font-size: 0.88em; text-align: center; outline: none; }
38
- .page-image-caption[data-empty]::before { content: attr(data-placeholder); color: var(--page-ink-faint); }
39
- .page-image:not(.is-selected) .page-image-caption[data-empty]:not(:focus) { display: none; }
40
- .page-file-link { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--page-rule); border-radius: 8px; color: var(--page-ink); text-decoration: none; }
41
- .page-file-icon { color: var(--page-link, var(--page-accent)); }
42
- .page-file-name { color: var(--page-link, var(--page-accent)); min-width: 0; overflow-wrap: anywhere; }
43
- .page-file-meta { margin-inline-start: auto; color: var(--page-ink-faint); font-size: 0.88em; }
44
- .page-upload { display: flex; align-items: center; gap: 10px; margin: var(--page-block-gap) 0; padding: 8px 12px; border: 1px dashed var(--page-rule); border-radius: 8px; color: var(--page-ink-soft); font-size: 0.88em; }
45
- .page-upload-preview { width: 40px; height: 40px; object-fit: cover; border-radius: 4px; opacity: 0.6; }
46
- .page-upload-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
47
- .page-upload-bar { flex: 1; height: 2px; border-radius: 1px; background: var(--page-rule); overflow: hidden; }
48
- .page-upload-bar > span { display: block; height: 100%; background: var(--page-progress, var(--page-ink-soft)); transition: width 200ms; }
49
- .page-upload[data-state="error"] .page-upload-msg, .page-upload[data-state="embed-choice"] .page-upload-msg { flex: 1; }
50
- .page-upload[data-state="error"] .page-upload-msg { color: var(--page-danger, #9E3B2F); }
51
- .page-upload-btn { border: 0; padding: 4px 8px; border-radius: 6px; background: none; color: inherit; font: inherit; cursor: pointer; }
52
- .page-upload-btn:hover { background: var(--page-pop-hover); }`;
20
+ .blockeditor-editor .blockeditor-image { margin-inline: 0; }
21
+ .blockeditor-image-frame { position: relative; margin: 0 auto; max-width: 100%; }
22
+ .blockeditor-image-frame img { display: block; width: 100%; height: auto; border-radius: var(--blockeditor-image-radius, 6px); }
23
+ .blockeditor-image[data-broken] .blockeditor-image-frame { min-height: 80px; background: var(--blockeditor-code-bg); border-radius: var(--blockeditor-image-radius, 6px); }
24
+ .blockeditor-image-handle { position: absolute; top: 50%; inset-inline-end: 6px; width: 6px; height: 36px; margin-top: -18px; border-radius: 3px; background: var(--blockeditor-chrome-ink-moved); opacity: 0; cursor: ew-resize; touch-action: none; transition: opacity var(--blockeditor-fade); }
25
+ .blockeditor-image:hover .blockeditor-image-handle, .blockeditor-image.is-selected .blockeditor-image-handle { opacity: 1; }
26
+ .blockeditor-editor .blockeditor-image.blockeditor-block-selected { background: none; box-shadow: none; }
27
+ .blockeditor-editor .blockeditor-image.blockeditor-block-selected .blockeditor-image-frame { box-shadow: 0 0 0 6px var(--blockeditor-block-selected, rgba(88, 120, 170, 0.12)); border-radius: var(--blockeditor-image-radius, 6px); }
28
+ .blockeditor-image[data-align="left"] .blockeditor-image-frame { margin-left: 0; margin-right: auto; }
29
+ .blockeditor-image[data-align="right"] .blockeditor-image-frame { margin-left: auto; margin-right: 0; }
30
+ .blockeditor-image[data-align="left"] .blockeditor-image-caption { text-align: left; }
31
+ .blockeditor-image[data-align="right"] .blockeditor-image-caption { text-align: right; }
32
+ .blockeditor-image-align { position: absolute; top: 8px; inset-inline-end: 8px; display: none; gap: 1px; padding: 2px; background: var(--blockeditor-pop-bg); color: var(--blockeditor-pop-ink); border: 1px solid var(--blockeditor-pop-line); box-shadow: var(--blockeditor-pop-shadow); border-radius: 7px; }
33
+ .blockeditor-image.is-selected .blockeditor-image-align, .blockeditor-image.blockeditor-block-selected .blockeditor-image-align { display: flex; }
34
+ .blockeditor-image-align button { display: grid; place-items: center; width: 26px; height: 26px; padding: 0; border: 0; border-radius: 5px; background: none; color: inherit; cursor: pointer; }
35
+ .blockeditor-image-align button:hover, .blockeditor-image-align button[aria-pressed="true"] { background: var(--blockeditor-pop-hover); }
36
+ .blockeditor-image.is-selected .blockeditor-image-frame img { outline: 2px solid var(--blockeditor-selection); outline-offset: 2px; }
37
+ .blockeditor-image-caption { margin-top: 6px; color: var(--blockeditor-ink-soft); font-size: 0.88em; text-align: center; outline: none; }
38
+ .blockeditor-image-caption[data-empty]::before { content: attr(data-placeholder); color: var(--blockeditor-ink-faint); }
39
+ .blockeditor-image:not(.is-selected) .blockeditor-image-caption[data-empty]:not(:focus) { display: none; }
40
+ .blockeditor-file-link { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--blockeditor-rule); border-radius: 8px; color: var(--blockeditor-ink); text-decoration: none; }
41
+ .blockeditor-file-icon { color: var(--blockeditor-link, var(--blockeditor-accent)); }
42
+ .blockeditor-file-name { color: var(--blockeditor-link, var(--blockeditor-accent)); min-width: 0; overflow-wrap: anywhere; }
43
+ .blockeditor-file-meta { margin-inline-start: auto; color: var(--blockeditor-ink-faint); font-size: 0.88em; }
44
+ .blockeditor-upload { display: flex; align-items: center; gap: 10px; margin: var(--blockeditor-block-gap) 0; padding: 8px 12px; border: 1px dashed var(--blockeditor-rule); border-radius: 8px; color: var(--blockeditor-ink-soft); font-size: 0.88em; }
45
+ .blockeditor-upload-preview { width: 40px; height: 40px; object-fit: cover; border-radius: 4px; opacity: 0.6; }
46
+ .blockeditor-upload-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
47
+ .blockeditor-upload-bar { flex: 1; height: 2px; border-radius: 1px; background: var(--blockeditor-rule); overflow: hidden; }
48
+ .blockeditor-upload-bar > span { display: block; height: 100%; background: var(--blockeditor-progress, var(--blockeditor-ink-soft)); transition: width 200ms; }
49
+ .blockeditor-upload[data-state="error"] .blockeditor-upload-msg, .blockeditor-upload[data-state="embed-choice"] .blockeditor-upload-msg { flex: 1; }
50
+ .blockeditor-upload[data-state="error"] .blockeditor-upload-msg { color: var(--blockeditor-danger, #9E3B2F); }
51
+ .blockeditor-upload-btn { border: 0; padding: 4px 8px; border-radius: 6px; background: none; color: inherit; font: inherit; cursor: pointer; }
52
+ .blockeditor-upload-btn:hover { background: var(--blockeditor-pop-hover); }`;
53
53
 
54
54
  function button(doc, act, label, id) {
55
55
  const b = doc.createElement("button");
56
56
  b.type = "button";
57
- b.className = "page-upload-btn";
57
+ b.className = "blockeditor-upload-btn";
58
58
  b.dataset.act = act;
59
59
  b.dataset.upload = id;
60
60
  b.textContent = label;
@@ -63,25 +63,25 @@ function button(doc, act, label, id) {
63
63
 
64
64
  function bookmarkDOM(doc, it) {
65
65
  const box = doc.createElement("div");
66
- box.className = "page-upload";
66
+ box.className = "blockeditor-upload";
67
67
  box.dataset.state = it.state;
68
68
  box.dataset.kind = it.kind;
69
69
  box.contentEditable = "false";
70
70
  box.setAttribute("role", it.state === "uploading" ? "status" : "alert");
71
71
  if (it.preview) {
72
72
  const img = doc.createElement("img");
73
- img.className = "page-upload-preview";
73
+ img.className = "blockeditor-upload-preview";
74
74
  img.src = it.preview;
75
75
  img.alt = "";
76
76
  box.append(img);
77
77
  }
78
78
  const name = doc.createElement("span");
79
- name.className = "page-upload-name";
79
+ name.className = "blockeditor-upload-name";
80
80
  name.textContent = it.name;
81
81
  box.append(name);
82
82
  if (it.state === "uploading") {
83
83
  const bar = doc.createElement("span");
84
- bar.className = "page-upload-bar";
84
+ bar.className = "blockeditor-upload-bar";
85
85
  bar.setAttribute("role", "progressbar");
86
86
  bar.setAttribute("aria-label", `Uploading ${it.name}`);
87
87
  bar.setAttribute("aria-valuemin", "0");
@@ -94,7 +94,7 @@ function bookmarkDOM(doc, it) {
94
94
  return box;
95
95
  }
96
96
  const msg = doc.createElement("span");
97
- msg.className = "page-upload-msg";
97
+ msg.className = "blockeditor-upload-msg";
98
98
  msg.textContent = it.message;
99
99
  box.append(msg);
100
100
  if (it.state === "embed-choice") box.append(button(doc, "embed", "Keep this image inside the document", it.id));
@@ -118,21 +118,21 @@ export class ImageView {
118
118
  this.getPos = getPos;
119
119
  const doc = view.dom.ownerDocument;
120
120
  this.dom = doc.createElement("figure");
121
- this.dom.className = "page-image";
121
+ this.dom.className = "blockeditor-image";
122
122
  this.dom.addEventListener("dragstart", (event) => { event.preventDefault(); event.stopPropagation(); });
123
123
  this.dom.draggable = false;
124
124
  this.frame = doc.createElement("div");
125
- this.frame.className = "page-image-frame";
125
+ this.frame.className = "blockeditor-image-frame";
126
126
  this.img = doc.createElement("img");
127
127
  this.img.draggable = false;
128
128
  this.img.addEventListener("error", () => this.dom.toggleAttribute("data-broken", true));
129
129
  this.img.addEventListener("load", () => this.dom.removeAttribute("data-broken"));
130
130
  this.handle = doc.createElement("span");
131
- this.handle.className = "page-image-handle";
131
+ this.handle.className = "blockeditor-image-handle";
132
132
  this.handle.setAttribute("aria-hidden", "true");
133
133
  this.handle.addEventListener("pointerdown", (e) => this.resize(e));
134
134
  this.alignBar = doc.createElement("div");
135
- this.alignBar.className = "page-image-align";
135
+ this.alignBar.className = "blockeditor-image-align";
136
136
  this.alignBar.setAttribute("role", "toolbar");
137
137
  this.alignBar.setAttribute("aria-label", "Image alignment");
138
138
  for (const [value, label, path] of ALIGNS) {
@@ -151,7 +151,7 @@ export class ImageView {
151
151
  });
152
152
  this.frame.append(this.img, this.handle, this.alignBar);
153
153
  this.caption = doc.createElement("figcaption");
154
- this.caption.className = "page-image-caption";
154
+ this.caption.className = "blockeditor-image-caption";
155
155
  this.caption.contentEditable = "plaintext-only";
156
156
  this.caption.setAttribute("aria-label", "Caption");
157
157
  this.caption.dataset.placeholder = "Add a caption";
@@ -230,7 +230,7 @@ export class ImageView {
230
230
 
231
231
  selectNode() { this.dom.classList.add("is-selected"); }
232
232
  deselectNode() { this.dom.classList.remove("is-selected"); }
233
- stopEvent(event) { return this.caption.contains(event.target) || this.alignBar.contains(event.target) || event.target.classList?.contains("page-image-handle"); }
233
+ stopEvent(event) { return this.caption.contains(event.target) || this.alignBar.contains(event.target) || event.target.classList?.contains("blockeditor-image-handle"); }
234
234
  ignoreMutation() { return true; }
235
235
  }
236
236
 
@@ -246,19 +246,19 @@ export class FileView {
246
246
  this.node = node;
247
247
  const doc = view.dom.ownerDocument;
248
248
  this.dom = doc.createElement("div");
249
- this.dom.className = "page-file";
249
+ this.dom.className = "blockeditor-file";
250
250
  this.dom.addEventListener("dragstart", (event) => { event.preventDefault(); event.stopPropagation(); });
251
251
  this.link = doc.createElement("a");
252
- this.link.className = "page-file-link";
252
+ this.link.className = "blockeditor-file-link";
253
253
  this.link.target = "_blank";
254
254
  this.link.rel = "noopener noreferrer";
255
255
  this.icon = doc.createElement("span");
256
- this.icon.className = "page-file-icon";
256
+ this.icon.className = "blockeditor-file-icon";
257
257
  this.icon.textContent = "⎘";
258
258
  this.name = doc.createElement("span");
259
- this.name.className = "page-file-name";
259
+ this.name.className = "blockeditor-file-name";
260
260
  this.meta = doc.createElement("span");
261
- this.meta.className = "page-file-meta";
261
+ this.meta.className = "blockeditor-file-meta";
262
262
  this.link.append(this.icon, this.name, this.meta);
263
263
  this.dom.append(this.link);
264
264
  this.render(node);
@@ -19,11 +19,11 @@ const columns = (table) => orderedIds(table.attrs.cols);
19
19
  const UNAVAILABLE = "That part of the table is no longer available.";
20
20
  const GEAR = '<svg viewBox="0 0 16 16" width="14" height="14" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><g transform="scale(0.6667)" stroke-width="2.25"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></g></svg>';
21
21
  const ACTIONS_CSS = `
22
- .page-editor .page-table-actions { position: absolute; z-index: 2; bottom: 100%; inset-inline-end: 0; inset-inline-start: auto; width: 24px; height: 20px; padding: 0; display: grid; place-items: center; border: 1px solid var(--page-chrome-line-rest); border-bottom: 0; border-radius: 6px 6px 0 0; background: var(--page-chrome-bg-moved); color: var(--page-chrome-ink-moved); font: inherit; cursor: pointer; opacity: 1; }
23
- .page-editor .page-table-actions:hover { background: var(--page-pop-hover); color: var(--page-ink-soft); }
22
+ .blockeditor-editor .blockeditor-table-actions { position: absolute; z-index: 2; bottom: 100%; inset-inline-end: 0; inset-inline-start: auto; width: 24px; height: 20px; padding: 0; display: grid; place-items: center; border: 1px solid var(--blockeditor-chrome-line-rest); border-bottom: 0; border-radius: 6px 6px 0 0; background: var(--blockeditor-chrome-bg-moved); color: var(--blockeditor-chrome-ink-moved); font: inherit; cursor: pointer; opacity: 1; }
23
+ .blockeditor-editor .blockeditor-table-actions:hover { background: var(--blockeditor-pop-hover); color: var(--blockeditor-ink-soft); }
24
24
  @media (max-width: 560px) {
25
- .page-editor .page-table-actions { position: absolute; }
26
- .page-editor .page-table-actions::after { content: ""; position: absolute; inset: -12px; }
25
+ .blockeditor-editor .blockeditor-table-actions { position: absolute; }
26
+ .blockeditor-editor .blockeditor-table-actions::after { content: ""; position: absolute; inset: -12px; }
27
27
  }
28
28
  `;
29
29
 
@@ -94,12 +94,12 @@ export class TableView {
94
94
  this.destroyed = false;
95
95
  const doc = view.dom.ownerDocument;
96
96
  this.dom = doc.createElement("div");
97
- this.dom.className = "page-table";
97
+ this.dom.className = "blockeditor-table";
98
98
  this.dom.dataset.id = node.attrs.id ?? "";
99
99
  this.dom.setAttribute("role", "group");
100
100
  this.dom.setAttribute("aria-label", "Table");
101
101
  const scroll = doc.createElement("div");
102
- scroll.className = "page-table-scroll";
102
+ scroll.className = "blockeditor-table-scroll";
103
103
  const table = doc.createElement("table");
104
104
  table.setAttribute("aria-label", "Table");
105
105
  this.table = table;
@@ -110,16 +110,16 @@ export class TableView {
110
110
  table.append(this.colgroup, this.header, this.contentDOM);
111
111
  scroll.append(table);
112
112
  const addRowButton = button(doc, "+", () => this.append("row"));
113
- addRowButton.className = "page-table-add-row";
113
+ addRowButton.className = "blockeditor-table-add-row";
114
114
  addRowButton.setAttribute("aria-label", "Add a row");
115
115
  addRowButton.title = "Add a row";
116
116
  const addColumnButton = button(doc, "+", () => this.append("column"));
117
- addColumnButton.className = "page-table-add-col";
117
+ addColumnButton.className = "blockeditor-table-add-col";
118
118
  addColumnButton.setAttribute("aria-label", "Add a column");
119
119
  addColumnButton.title = "Add a column";
120
120
  const actions = doc.createElement("button");
121
121
  actions.type = "button";
122
- actions.className = "page-table-actions";
122
+ actions.className = "blockeditor-table-actions";
123
123
  actions.innerHTML = GEAR;
124
124
  actions.dataset.control = "actions";
125
125
  actions.setAttribute("aria-haspopup", "menu");
@@ -258,7 +258,7 @@ export class TableView {
258
258
  const tableId = this.node.attrs.id;
259
259
  const input = doc.createElement("input");
260
260
  input.type = "text";
261
- input.className = "page-table-rename";
261
+ input.className = "blockeditor-table-rename";
262
262
  input.dataset.control = "rename";
263
263
  input.dataset.col = colId;
264
264
  input.value = col.name ?? "";
@@ -316,7 +316,7 @@ export class TableView {
316
316
  resizer(colId, th, col, index) {
317
317
  const doc = this.dom.ownerDocument;
318
318
  const handle = doc.createElement("span");
319
- handle.className = "page-table-resize";
319
+ handle.className = "blockeditor-table-resize";
320
320
  handle.dataset.control = "resize";
321
321
  handle.dataset.col = colId;
322
322
  handle.setAttribute("role", "separator");
@@ -395,7 +395,7 @@ export class TableView {
395
395
  return this.command(colId, this.widthCommand(colId, width));
396
396
  }
397
397
  handleFor(colId) {
398
- return [...this.header.querySelectorAll(".page-table-resize")].find((handle) => handle.dataset.col === colId) ?? null;
398
+ return [...this.header.querySelectorAll(".blockeditor-table-resize")].find((handle) => handle.dataset.col === colId) ?? null;
399
399
  }
400
400
  // The arrow keys, Home, End, Enter and Escape preview a width; the key that
401
401
  // stops repeating, Enter, or leaving the handle commits the one command.
@@ -474,7 +474,7 @@ export class TableView {
474
474
  if (this.node.attrs.sort?.col === colId) th.setAttribute("aria-sort", this.node.attrs.sort.dir === "asc" ? "ascending" : "descending");
475
475
  const control = doc.createElement("button");
476
476
  control.type = "button";
477
- control.className = "page-table-col-menu";
477
+ control.className = "blockeditor-table-col-menu";
478
478
  control.textContent = name;
479
479
  control.dataset.control = "column";
480
480
  control.dataset.col = colId;
@@ -540,7 +540,7 @@ export class TableView {
540
540
  if (focused && !renaming) this.afterUpdate(focused);
541
541
  return true;
542
542
  }
543
- stopEvent(event) { return !!event.target.closest?.("thead, .page-table-actions, .page-table-add-row, .page-table-add-col"); }
543
+ stopEvent(event) { return !!event.target.closest?.("thead, .blockeditor-table-actions, .blockeditor-table-add-row, .blockeditor-table-add-col"); }
544
544
  ignoreMutation(mutation) { return !this.contentDOM.contains(mutation.target); }
545
545
  destroy() {
546
546
  this.destroyed = true;
@@ -566,7 +566,7 @@ export class TableCellView {
566
566
  this.contentDOM = doc.createElement("span");
567
567
  const menu = doc.createElement("button");
568
568
  menu.type = "button";
569
- menu.className = "page-table-row-menu";
569
+ menu.className = "blockeditor-table-row-menu";
570
570
  menu.innerHTML = GEAR;
571
571
  menu.dataset.control = "row";
572
572
  menu.setAttribute("aria-haspopup", "menu");
@@ -630,7 +630,7 @@ export class TableCellView {
630
630
  const doc = this.dom.ownerDocument;
631
631
  const input = doc.createElement("input");
632
632
  input.type = "date";
633
- input.className = "page-table-date";
633
+ input.className = "blockeditor-table-date";
634
634
  input.contentEditable = "false";
635
635
  input.setAttribute("aria-label", "Pick a date");
636
636
  const current = this.node.textContent.trim();
@@ -656,7 +656,7 @@ export class TableCellView {
656
656
  if (input?.isConnected) input.remove();
657
657
  }
658
658
  destroy() { this.closeDate(); }
659
- stopEvent(event) { return !!event.target.closest?.(".page-table-row-menu, .page-table-date"); }
659
+ stopEvent(event) { return !!event.target.closest?.(".blockeditor-table-row-menu, .blockeditor-table-date"); }
660
660
  ignoreMutation(mutation) { return !this.contentDOM.contains(mutation.target); }
661
661
  }
662
662
 
@@ -30,16 +30,16 @@ function titleOf(doc) {
30
30
  }
31
31
 
32
32
  // The bar sits in its own shadow root beside the editor, so the page's CSS cannot restyle
33
- // it. The page's --page-* tokens still reach it, and it keeps the editor's font and colour.
33
+ // it. The page's --blockeditor-* tokens still reach it, and it keeps the editor's font and colour.
34
34
  const COVER_CSS = `
35
35
  :host{font:inherit !important;color:inherit !important}
36
- .page-cover-panel{display:flex;align-items:center;gap:8px;margin:8px 0;padding:6px 10px;border:1px solid var(--page-pop-line);border-radius:8px;background:var(--page-pop-bg);color:var(--page-pop-ink);box-shadow:var(--page-pop-shadow);font-size:.88em}
37
- .page-cover-msg{max-width:34ch}
38
- .page-cover-bar{flex:1;height:2px;border-radius:1px;background:var(--page-rule);overflow:hidden}
39
- .page-cover-bar>span{display:block;height:100%;background:var(--page-progress, var(--page-ink-soft));transition:width 200ms}
40
- .page-cover-btn{border:0;padding:4px 8px;border-radius:6px;background:none;color:inherit;font:inherit;cursor:pointer}
41
- .page-cover-btn:hover{background:var(--page-pop-hover)}
42
- .page-cover-panel[data-state="error"] .page-cover-msg{color:var(--page-danger, #9E3B2F)}
36
+ .blockeditor-cover-panel{display:flex;align-items:center;gap:8px;margin:8px 0;padding:6px 10px;border:1px solid var(--blockeditor-pop-line);border-radius:8px;background:var(--blockeditor-pop-bg);color:var(--blockeditor-pop-ink);box-shadow:var(--blockeditor-pop-shadow);font-size:.88em}
37
+ .blockeditor-cover-msg{max-width:34ch}
38
+ .blockeditor-cover-bar{flex:1;height:2px;border-radius:1px;background:var(--blockeditor-rule);overflow:hidden}
39
+ .blockeditor-cover-bar>span{display:block;height:100%;background:var(--blockeditor-progress, var(--blockeditor-ink-soft));transition:width 200ms}
40
+ .blockeditor-cover-btn{border:0;padding:4px 8px;border-radius:6px;background:none;color:inherit;font:inherit;cursor:pointer}
41
+ .blockeditor-cover-btn:hover{background:var(--blockeditor-pop-hover)}
42
+ .blockeditor-cover-panel[data-state="error"] .blockeditor-cover-msg{color:var(--blockeditor-danger, #9E3B2F)}
43
43
  `;
44
44
 
45
45
  const clamp = (value) => Math.min(100, Math.max(0, Math.round(value)));
@@ -47,9 +47,9 @@ const clamp = (value) => Math.min(100, Math.max(0, Math.round(value)));
47
47
  // The format gate's own answer, as every command that writes a newer page format asks for
48
48
  // it: the command's result when the gate admitted the write, the gate's refusal otherwise.
49
49
  async function formatted(view, apply) {
50
- if (typeof view.runFormatCommand !== "function") return { ok: false, code: "page-format-unsupported" };
50
+ if (typeof view.runFormatCommand !== "function") return { ok: false, code: "blockeditor-format-unsupported" };
51
51
  const answer = await view.runFormatCommand(apply);
52
- return answer?.status === "applied" ? answer.result : { ok: false, code: answer?.code ?? answer?.status ?? "page-format-refused", retry: answer?.retry === true };
52
+ return answer?.status === "applied" ? answer.result : { ok: false, code: answer?.code ?? answer?.status ?? "blockeditor-format-refused", retry: answer?.retry === true };
53
53
  }
54
54
  const readDataUrl = (file) => new Promise((ok, no) => { const r = new FileReader(); r.onload = () => ok(r.result); r.onerror = () => no(r.error); r.readAsDataURL(file); });
55
55
 
@@ -78,7 +78,7 @@ export function createFeature({ view = null, upload = null } = {}) {
78
78
  const button = (act, label) => {
79
79
  const b = doc.createElement("button");
80
80
  b.type = "button";
81
- b.className = "page-cover-btn";
81
+ b.className = "blockeditor-cover-btn";
82
82
  b.dataset.act = act;
83
83
  b.textContent = label;
84
84
  return b;
@@ -88,18 +88,18 @@ export function createFeature({ view = null, upload = null } = {}) {
88
88
  // reposition's own message. It is runtime only, so nothing of it is in the record.
89
89
  function draw(s) {
90
90
  const box = s.panel ?? (s.panel = doc.createElement("div"));
91
- box.className = "page-cover-panel";
91
+ box.className = "blockeditor-cover-panel";
92
92
  box.dataset.state = s.state;
93
93
  box.setAttribute("contenteditable", "false");
94
94
  box.setAttribute("role", s.state === "uploading" ? "status" : "alert");
95
95
  box.textContent = "";
96
96
  const msg = doc.createElement("span");
97
- msg.className = "page-cover-msg";
97
+ msg.className = "blockeditor-cover-msg";
98
98
  msg.textContent = s.message;
99
99
  box.append(msg);
100
100
  if (s.state === "uploading") {
101
101
  const bar = doc.createElement("span");
102
- bar.className = "page-cover-bar";
102
+ bar.className = "blockeditor-cover-bar";
103
103
  bar.setAttribute("role", "progressbar");
104
104
  bar.setAttribute("aria-valuemin", "0");
105
105
  bar.setAttribute("aria-valuemax", "100");
@@ -113,7 +113,7 @@ export function createFeature({ view = null, upload = null } = {}) {
113
113
  else box.append(button("cancel", "Close"));
114
114
  if (!s.ui) {
115
115
  const host = view.dom.parentElement;
116
- s.ui = mountEditorUI({ name: "page-cover", content: box, css: [COVER_CSS], parent: host ?? doc.body, before: host ? view.dom : null });
116
+ s.ui = mountEditorUI({ name: "blockeditor-cover", content: box, css: [COVER_CSS], parent: host ?? doc.body, before: host ? view.dom : null });
117
117
  }
118
118
  }
119
119
 
@@ -156,7 +156,7 @@ export function createFeature({ view = null, upload = null } = {}) {
156
156
  const input = doc.createElement("input");
157
157
  input.type = "file";
158
158
  input.accept = "image/*";
159
- input.className = "page-cover-input";
159
+ input.className = "blockeditor-cover-input";
160
160
  input.hidden = true;
161
161
  (view.dom.parentElement ?? doc.body).appendChild(input);
162
162
  s.input = input;
@@ -261,7 +261,7 @@ export function createFeature({ view = null, upload = null } = {}) {
261
261
  return { ok: true, picker: true };
262
262
  }
263
263
 
264
- const coverImg = () => view.dom.querySelector("header[data-page-heading] img[data-page-cover]");
264
+ const coverImg = () => view.dom.querySelector("header[data-blockeditor-heading] img[data-blockeditor-cover]");
265
265
 
266
266
  function preview(s) {
267
267
  const img = coverImg();
@@ -11,10 +11,10 @@ import { createMentionPicker } from "../mention-picker.js";
11
11
  import { runFormatted } from "../format-command.js";
12
12
 
13
13
  const TITLE_CSS = `
14
- [data-page-heading]{display:block}
15
- [data-page-heading]>span[data-page-icon]{display:inline-block;font-size:34px;line-height:1;margin-block-end:.2em}
16
- [data-page-heading]>img[data-page-cover]{display:block;width:100%;height:180px;object-fit:cover;border-radius:var(--page-image-radius, 6px);margin-block-end:.6em}
17
- [data-page-heading]>h1{font-family:var(--page-font-display);font-size:var(--page-h1-size);font-weight:var(--page-h1-weight);letter-spacing:var(--page-h1-tracking);line-height:var(--page-h1-line);color:var(--page-ink-strong);margin-block:0 .6em}
14
+ [data-blockeditor-heading]{display:block}
15
+ [data-blockeditor-heading]>span[data-blockeditor-icon]{display:inline-block;font-size:34px;line-height:1;margin-block-end:.2em}
16
+ [data-blockeditor-heading]>img[data-blockeditor-cover]{display:block;width:100%;height:180px;object-fit:cover;border-radius:var(--blockeditor-image-radius, 6px);margin-block-end:.6em}
17
+ [data-blockeditor-heading]>h1{font-family:var(--blockeditor-font-display);font-size:var(--blockeditor-h1-size);font-weight:var(--blockeditor-h1-weight);letter-spacing:var(--blockeditor-h1-tracking);line-height:var(--blockeditor-h1-line);color:var(--blockeditor-ink-strong);margin-block:0 .6em}
18
18
  `;
19
19
 
20
20
  // The emoji feature, fetched on first use: one list of glyphs, one way of finding one and
@@ -49,7 +49,7 @@ export function titleOf(doc) {
49
49
  // part of it a person kept in view, so a reader draws it with nothing of this loaded.
50
50
  function coverImg(doc, attrs) {
51
51
  const img = doc.createElement("img");
52
- img.setAttribute("data-page-cover", "");
52
+ img.setAttribute("data-blockeditor-cover", "");
53
53
  img.setAttribute("src", attrs.pageCoverSrc);
54
54
  img.setAttribute("alt", attrs.pageCoverAlt ?? "");
55
55
  img.setAttribute("style", `object-position:${attrs.pageCoverX}% ${attrs.pageCoverY}%`);
@@ -72,12 +72,12 @@ class TitleHeadingView {
72
72
  if (!this.decorated) return;
73
73
  const box = doc.createElement("header");
74
74
  box.setAttribute("data-id", node.attrs.id);
75
- box.setAttribute("data-page-heading", "1");
75
+ box.setAttribute("data-blockeditor-heading", "1");
76
76
  head.removeAttribute("data-id");
77
77
  if (node.attrs.pageCoverSrc) box.append(coverImg(doc, node.attrs));
78
78
  if (node.attrs.pageIcon) {
79
79
  const mark = doc.createElement("span");
80
- mark.setAttribute("data-page-icon", "");
80
+ mark.setAttribute("data-blockeditor-icon", "");
81
81
  mark.setAttribute("aria-hidden", "true");
82
82
  mark.textContent = node.attrs.pageIcon;
83
83
  box.append(mark);
@@ -41,7 +41,7 @@ export class TocView {
41
41
  this.doc = view.state.doc;
42
42
  const doc = view.dom.ownerDocument;
43
43
  this.dom = doc.createElement("div");
44
- this.dom.className = "page-toc";
44
+ this.dom.className = "blockeditor-toc";
45
45
  this.dom.contentEditable = "false";
46
46
  this.dom.setAttribute("role", "group");
47
47
  this.dom.setAttribute("aria-label", "Table of contents");
@@ -4,48 +4,47 @@
4
4
  import { openPageMenu } from "../chrome.js";
5
5
  import { schema } from "../schema.js";
6
6
  import { createToolHost } from "../tools.js";
7
- import { toolViews } from "../tool-views.js";
7
+ import { toolBlockViews, toolViews } from "../tool-views.js";
8
8
 
9
9
  export const TOOL_CSS = `
10
- .page-tool-block { position: relative; min-height: 48px; border: 1px solid var(--page-rule); border-radius: 8px; padding: 12px; }
11
- .page-tool-settings { position: absolute; top: 4px; inset-inline-end: 4px; border: 0; border-radius: 5px; background: var(--page-pop-bg); color: var(--page-ink-soft); font: 12px var(--page-font); padding: 5px 8px; cursor: pointer; opacity: 0; }
12
- .page-tool-block:hover .page-tool-settings, .page-tool-block:focus-within .page-tool-settings { opacity: 1; }
13
- .page-ai-panel { position: relative; z-index: 5; width: min(520px, 100%); box-sizing: border-box; margin: 12px auto; padding: 14px; border: 1px solid var(--page-pop-line); border-radius: 10px; background: var(--page-pop-bg); color: var(--page-pop-ink); box-shadow: var(--page-pop-shadow); }
14
- .page-ai-panel textarea { width: 100%; min-height: 88px; box-sizing: border-box; padding: 8px; border: 1px solid var(--page-pop-line); border-radius: 6px; background: var(--page-pop-bg); color: inherit; font: inherit; resize: vertical; }
15
- .page-ai-actions { display: flex; gap: 8px; margin-top: 8px; }
16
- .page-ai-actions button { border: 1px solid var(--page-pop-line); border-radius: 6px; background: var(--page-pop-bg); color: inherit; font: inherit; padding: 5px 10px; cursor: pointer; }
17
- .page-ai-status, [data-tool-note], [data-tool-error] { color: var(--page-danger); font-size: 0.85em; }`;
10
+ .blockeditor-tool-block { position: relative; min-height: 48px; border: 1px solid var(--blockeditor-rule); border-radius: 8px; padding: 12px; }
11
+ .blockeditor-tool-settings { position: absolute; top: 4px; inset-inline-end: 4px; border: 0; border-radius: 5px; background: var(--blockeditor-pop-bg); color: var(--blockeditor-ink-soft); font: 12px var(--blockeditor-font); padding: 5px 8px; cursor: pointer; opacity: 0; }
12
+ .blockeditor-tool-block:hover .blockeditor-tool-settings, .blockeditor-tool-block:focus-within .blockeditor-tool-settings { opacity: 1; }
13
+ [data-tool-note], [data-tool-error] { color: var(--blockeditor-danger); font-size: 0.85em; }`;
18
14
 
19
15
  export class ToolView {
20
- constructor(node, view, getPos, { host, revise = null }) {
16
+ constructor(node, view, getPos, { host, revise = null, blocks = null }) {
21
17
  this.node = node;
22
18
  this.view = view;
23
19
  this.getPos = getPos;
24
20
  this.host = host;
25
21
  this.revise = revise;
22
+ this.blocks = blocks;
26
23
  this.showingFallback = false;
24
+ this.suspended = false;
27
25
  const doc = view.dom.ownerDocument;
28
26
  this.dom = doc.createElement("section");
29
- this.dom.className = "page-tool-block";
27
+ this.dom.className = "blockeditor-tool-block";
30
28
  this.dom.dataset.type = "tool";
31
29
  this.dom.dataset.id = node.attrs.id ?? "";
32
30
  this.dom.contentEditable = "false";
33
31
  this.content = doc.createElement("div");
34
- this.content.className = "page-tool-content";
32
+ this.content.className = "blockeditor-tool-content";
35
33
  this.menu = doc.createElement("button");
36
34
  this.menu.type = "button";
37
- this.menu.className = "page-tool-settings";
35
+ this.menu.className = "blockeditor-tool-settings";
38
36
  this.menu.textContent = "Tool options";
39
37
  this.menu.setAttribute("aria-label", "Tool options");
40
38
  this.menu.addEventListener("click", () => this.openMenu());
41
39
  this.dom.append(this.content, this.menu);
40
+ if (this.blocks && this.dom.dataset.id) this.blocks.set(this.dom.dataset.id, this);
42
41
  this.mount();
43
42
  }
44
43
 
45
44
  mount() {
46
45
  this.instance?.dispose();
47
46
  this.instance = null;
48
- if (this.showingFallback) this.content.innerHTML = this.node.attrs.artifact?.fallbackHtml ?? "";
47
+ if (this.suspended || this.showingFallback) this.content.innerHTML = this.node.attrs.artifact?.fallbackHtml ?? "";
49
48
  else this.instance = this.host.mount(this.content, {
50
49
  id: this.node.attrs.id,
51
50
  artifact: this.node.attrs.artifact,
@@ -54,6 +53,18 @@ export class ToolView {
54
53
  });
55
54
  }
56
55
 
56
+ suspend() {
57
+ if (this.suspended) return;
58
+ this.suspended = true;
59
+ this.mount();
60
+ }
61
+
62
+ resume() {
63
+ if (!this.suspended) return;
64
+ this.suspended = false;
65
+ this.mount();
66
+ }
67
+
57
68
  openMenu() {
58
69
  const items = [];
59
70
  if (this.revise) items.push({ label: "Revise…", run: () => this.revise(this.node.attrs.id, this.node.attrs.rev) });
@@ -73,26 +84,39 @@ export class ToolView {
73
84
  if (node.type !== schema.nodes.tool || node.attrs.id !== this.node.attrs.id) return false;
74
85
  const changed = node.attrs.rev !== this.node.attrs.rev || JSON.stringify(node.attrs.artifact) !== JSON.stringify(this.node.attrs.artifact);
75
86
  this.node = node;
76
- if (changed) this.mount();
87
+ if (changed) {
88
+ this.suspended = false;
89
+ this.mount();
90
+ }
77
91
  return true;
78
92
  }
79
93
 
80
94
  stopEvent(event) { return this.dom.contains(event.target); }
81
95
  ignoreMutation() { return true; }
82
- destroy() { this.instance?.dispose(); this.instance = null; }
96
+ destroy() {
97
+ const id = this.node.attrs.id;
98
+ if (this.blocks?.get(id) === this) this.blocks.delete(id);
99
+ this.instance?.dispose();
100
+ this.instance = null;
101
+ }
83
102
  }
84
103
 
85
104
  export function createFeature({ toolHost = null, revise = null, view = null } = {}) {
86
105
  const host = toolHost ?? createToolHost({ mode: "edit" });
87
- if (view) toolViews.set(view, host);
106
+ const blocks = new Map();
107
+ if (view) {
108
+ toolViews.set(view, host);
109
+ toolBlockViews.set(view, blocks);
110
+ }
88
111
  return {
89
112
  id: "tool",
90
113
  nodeViews: {
91
- tool: (node, editorView, getPos) => new ToolView(node, editorView, getPos, { host, revise }),
114
+ tool: (node, editorView, getPos) => new ToolView(node, editorView, getPos, { host, revise, blocks }),
92
115
  },
93
116
  css: TOOL_CSS,
94
117
  dispose() {
95
118
  if (view && toolViews.get(view) === host) toolViews.delete(view);
119
+ if (view && toolBlockViews.get(view) === blocks) toolBlockViews.delete(view);
96
120
  if (!toolHost) host.dispose();
97
121
  },
98
122
  };
@@ -4,7 +4,7 @@ import toast from "../ui/toast-lazy.js";
4
4
  // A refusal the person cannot see is the same as a command that did nothing, so the
5
5
  // gate's "no" is said out loud. Only the gate's own refusal: a command the gate let
6
6
  // through reports its own result to its caller.
7
- const UNSUPPORTED = new Set(["page-format-unsupported", "unsupported-host"]);
7
+ const UNSUPPORTED = new Set(["blockeditor-format-unsupported", "unsupported-host"]);
8
8
  const UNSUPPORTED_TEXT = "This host can't store that yet, so nothing was added.";
9
9
  const RETRY_TEXT = "That didn't go through. Try again.";
10
10
  const REFUSED_TEXT = "That couldn't be added here.";
@@ -23,11 +23,11 @@ function say(view, answer) {
23
23
  // caller writes nothing on a refusal.
24
24
  export async function runFormatted(view, apply) {
25
25
  if (typeof view.runFormatCommand !== "function") {
26
- say(view, { code: "page-format-unsupported" });
27
- return { ok: false, code: "page-format-unsupported" };
26
+ say(view, { code: "blockeditor-format-unsupported" });
27
+ return { ok: false, code: "blockeditor-format-unsupported" };
28
28
  }
29
29
  const answer = await view.runFormatCommand(apply);
30
30
  if (answer?.status === "applied") return answer.result;
31
31
  say(view, answer);
32
- return { ok: false, code: answer?.code ?? answer?.status ?? "page-format-refused", retry: answer?.retry === true };
32
+ return { ok: false, code: answer?.code ?? answer?.status ?? "blockeditor-format-refused", retry: answer?.retry === true };
33
33
  }