@panphora/clayjs 1.17.0 → 1.18.0
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.
- package/dist/all.js +1 -1
- package/dist/clay-dom.js +1 -1
- package/dist/clay-events.js +1 -1
- package/dist/clay-internals.js +1 -1
- package/dist/clay-options.js +1 -1
- package/dist/clay-router.js +1 -1
- package/dist/clay-ui.js +1 -1
- package/dist/clay-utils.js +1 -1
- package/dist/clay.js +1 -1
- package/dist/clay.standalone.js +72474 -62090
- package/dist/m/attrs/{save-freeze-MYNVXREN.js → save-freeze-LWGF6XUN.js} +1 -1
- package/dist/m/c-2GRUM77Q.js +30 -0
- package/dist/m/c-2KIEGNC4.js +1 -0
- package/dist/m/{c-AMSNPOCX.js → c-2KL3BD52.js} +1 -1
- package/dist/m/c-2ZZBC45O.js +1 -0
- package/dist/m/c-372N6H3B.js +1 -0
- package/dist/m/{c-4WKFKEKF.js → c-3G2DGZUP.js} +1 -1
- package/dist/m/c-3LDGIBMN.js +1 -0
- package/dist/m/c-3O7OBDCM.js +1 -0
- package/dist/m/c-4ASQPRQL.js +1 -0
- package/dist/m/c-4TXNLX4K.js +6 -0
- package/dist/m/c-4YU3BR4D.js +6 -0
- package/dist/m/c-5734MF2P.js +1 -0
- package/dist/m/c-57XDY6HC.js +1 -0
- package/dist/m/{c-KAU6E43D.js → c-5B4YBZXC.js} +1 -1
- package/dist/m/c-5ONTYIUI.js +1 -0
- package/dist/m/c-5OOVFCJM.js +1 -0
- package/dist/m/{c-3XIRD4NU.js → c-5T6NZHNM.js} +1 -1
- package/dist/m/{c-74MGYWZF.js → c-5ZQV7KC4.js} +1 -1
- package/dist/m/{c-7OLLJPWP.js → c-6DB2OLRJ.js} +1 -1
- package/dist/m/c-6DNRCPNM.js +1 -0
- package/dist/m/c-6UGWFMQC.js +2 -0
- package/dist/m/c-7K4SCQB7.js +1 -0
- package/dist/m/c-7MG5RU63.js +1 -0
- package/dist/m/c-7PRJCA3E.js +1 -0
- package/dist/m/c-A6L3FMUS.js +1 -0
- package/dist/m/c-AMU3BPPR.js +4 -0
- package/dist/m/{c-Y5HBBIQ4.js → c-AMYEFA2E.js} +1 -1
- package/dist/m/c-AQYCG7QW.js +1 -0
- package/dist/m/c-ATKAOH23.js +1 -0
- package/dist/m/c-B5CS55WR.js +1 -0
- package/dist/m/c-B5UJQT7W.js +1 -0
- package/dist/m/c-B7J4K2AE.js +3 -0
- package/dist/m/c-BHZYSHW4.js +1 -0
- package/dist/m/{c-VHM5XQHK.js → c-BIJALSRD.js} +1 -1
- package/dist/m/c-BJ7YQ5QZ.js +1 -0
- package/dist/m/{c-KIPQJX4B.js → c-BRLCTNMC.js} +1 -1
- package/dist/m/{c-VE6ZMYMC.js → c-BUAYFEV5.js} +1 -1
- package/dist/m/c-C6IPRG34.js +1 -0
- package/dist/m/{c-KU3ZFADW.js → c-CAS3NND4.js} +1 -1
- package/dist/m/{c-PS5ARVWR.js → c-CCQ25GFY.js} +1 -1
- package/dist/m/c-CJFDLD43.js +1 -0
- package/dist/m/c-COPTL5WB.js +1 -0
- package/dist/m/c-D3E4WJ4M.js +166 -0
- package/dist/m/c-D5IKEKXW.js +7 -0
- package/dist/m/c-DHBRA6DL.js +1 -0
- package/dist/m/c-DKLS74XB.js +72 -0
- package/dist/m/c-DVYGFTSK.js +3 -0
- package/dist/m/c-E3ZXARWA.js +1 -0
- package/dist/m/c-EK63G3CG.js +1 -0
- package/dist/m/c-ERQSNR6K.js +13 -0
- package/dist/m/c-EVYAISP3.js +1 -0
- package/dist/m/c-EXKHPOVC.js +3 -0
- package/dist/m/{c-QJ4OM3G6.js → c-FWKHM4E7.js} +1 -1
- package/dist/m/{c-4Q2XTQ2N.js → c-GBKB5WDL.js} +1 -1
- package/dist/m/c-GNDL3TKB.js +1 -0
- package/dist/m/c-GRWMD6O5.js +1 -0
- package/dist/m/c-GRXHHFPO.js +1 -0
- package/dist/m/c-HG2C77BM.js +4 -0
- package/dist/m/c-HHGJBU4D.js +1 -0
- package/dist/m/c-HMV6P4RX.js +1 -0
- package/dist/m/c-HMYWIHFG.js +1 -0
- package/dist/m/c-HT2DKBV2.js +1 -0
- package/dist/m/c-I2SCCUEW.js +1 -0
- package/dist/m/{c-TJ6WOJL3.js → c-ICJYHABF.js} +2 -2
- package/dist/m/c-IMZCWYHR.js +7 -0
- package/dist/m/c-IVMD3FEM.js +1 -0
- package/dist/m/{c-WDC5GVKU.js → c-IVTRVENZ.js} +1 -1
- package/dist/m/c-JKZJIUIP.js +1 -0
- package/dist/m/{c-UDUUJPFZ.js → c-JNLX3RJB.js} +1 -1
- package/dist/m/c-K3ADYNLU.js +1 -0
- package/dist/m/c-KGHVFRR3.js +1 -0
- package/dist/m/{c-5QWQ7A5L.js → c-KJJPV77R.js} +1 -1
- package/dist/m/{c-CZUSOB7V.js → c-KNPDOMDY.js} +1 -1
- package/dist/m/{c-EZU56NQV.js → c-KP64LT2A.js} +2 -2
- package/dist/m/c-KQ7E3PYY.js +1 -0
- package/dist/m/c-L3F5ZLIV.js +1 -0
- package/dist/m/{c-3RUU4TPX.js → c-L42OLXWM.js} +3 -2
- package/dist/m/c-L5VFATT6.js +1 -0
- package/dist/m/c-L7JL5TL3.js +3 -0
- package/dist/m/c-LKSL4AUJ.js +1 -0
- package/dist/m/c-M6FNQCTQ.js +1 -0
- package/dist/m/c-MCOOHCSG.js +1 -0
- package/dist/m/c-MHI3GYKF.js +1 -0
- package/dist/m/c-MWXFLW4J.js +1 -0
- package/dist/m/{c-5RJFTLSF.js → c-NEL7HQW3.js} +1 -1
- package/dist/m/{c-DCXOXBF3.js → c-NQJRVJ56.js} +1 -1
- package/dist/m/c-NWX3MFT4.js +1 -0
- package/dist/m/{c-HPURYVZS.js → c-OJYM642Q.js} +1 -1
- package/dist/m/c-OKXI52N7.js +1 -0
- package/dist/m/{c-R3L7ZJGB.js → c-OPLUZR3A.js} +1 -1
- package/dist/m/{c-GSFIGKOP.js → c-OTMKN2OO.js} +1 -1
- package/dist/m/{c-6NC5I2TV.js → c-OYRZ7XG2.js} +1 -1
- package/dist/m/{c-EVCQ3BKA.js → c-P3OFYUMA.js} +1 -1
- package/dist/m/c-PLN76GF3.js +6 -0
- package/dist/m/c-PLP4JKFC.js +1 -0
- package/dist/m/c-Q26MME6N.js +1 -0
- package/dist/m/{c-S7H2DRCB.js → c-Q3XOWZEV.js} +1 -1
- package/dist/m/{c-FRLHSY7E.js → c-QIKT6SKM.js} +1 -1
- package/dist/m/c-QIXT3Q7C.js +28 -0
- package/dist/m/c-QO4HNGCQ.js +1 -0
- package/dist/m/{c-JU3NK25H.js → c-R27DWQKX.js} +1 -1
- package/dist/m/{c-RSMOODDU.js → c-R2XUODVY.js} +1 -1
- package/dist/m/{c-QNKREOL6.js → c-R7LBFMF5.js} +1 -1
- package/dist/m/c-RND3G2S2.js +1 -0
- package/dist/m/{c-Q622NS2Y.js → c-S2U6NJU4.js} +1 -1
- package/dist/m/c-SPZPGD3R.js +1 -0
- package/dist/m/c-SW4YEG2D.js +8 -0
- package/dist/m/c-T637T7SN.js +1 -0
- package/dist/m/c-TJAXGIRV.js +1 -0
- package/dist/m/{c-RYUXUUBX.js → c-TNEM3RNM.js} +1 -1
- package/dist/m/c-TTB5EK4S.js +32 -0
- package/dist/m/c-U7SHNWDH.js +1 -0
- package/dist/m/c-UDHIVLYH.js +20 -0
- package/dist/m/{c-BBVGTQG7.js → c-UGNV5MFB.js} +1 -1
- package/dist/m/{c-QICP2YR5.js → c-UORXLSD3.js} +1 -1
- package/dist/m/c-UPD33ZPE.js +1 -0
- package/dist/m/c-URSMSFCB.js +1 -0
- package/dist/m/c-UY4QX42B.js +1 -0
- package/dist/m/c-V44KWI2L.js +4 -0
- package/dist/m/c-VILENZTD.js +1 -0
- package/dist/m/{c-HDDEEL77.js → c-VJYEVRYK.js} +1 -1
- package/dist/m/{c-SMBZG5X4.js → c-VR2BJ4AN.js} +1 -1
- package/dist/m/c-W4JCVLAB.js +1 -0
- package/dist/m/c-W6DQSHXI.js +135 -0
- package/dist/m/c-WBGWGOM7.js +1 -0
- package/dist/m/{c-4L3BTFRK.js → c-WCXLG3MV.js} +1 -1
- package/dist/m/c-WGW764WX.js +1 -0
- package/dist/m/c-WMRJKQ2V.js +5 -0
- package/dist/m/c-WNTYKCDG.js +1 -0
- package/dist/m/c-WQWIRWO3.js +72 -0
- package/dist/m/c-X5LNHET5.js +1 -0
- package/dist/m/{c-I2ZATQCD.js → c-X5TSXZYJ.js} +2 -2
- package/dist/m/c-XGH4GS2T.js +1 -0
- package/dist/m/c-Y6F2FORL.js +1 -0
- package/dist/m/c-YBKHUAK7.js +10 -0
- package/dist/m/c-YBSS55KU.js +20 -0
- package/dist/m/c-YCLU4UNT.js +2 -0
- package/dist/m/c-YVZ2L7CE.js +1 -0
- package/dist/m/c-ZK4GIZH2.js +1 -0
- package/dist/m/c-ZRXJD4G6.js +1 -0
- package/dist/m/c-ZWBI4HYK.js +1 -0
- package/dist/m/core/{admin-attrs-QHOKPJ7W.js → admin-attrs-YY7T5FGU.js} +1 -1
- package/dist/m/core/autosave-S6OMNDCK.js +1 -0
- package/dist/m/core/conflict-notice-IWHMHH43.js +1 -0
- package/dist/m/core/{host-permission-FNXVEFNE.js → host-permission-6EVJGNPL.js} +1 -1
- package/dist/m/core/is-edit-mode-GCX6767E.js +1 -0
- package/dist/m/core/{persist-JFYRHMRJ.js → persist-UKXV5KLA.js} +1 -1
- package/dist/m/core/recovery-DRFZRJED.js +1 -0
- package/dist/m/core/save-LYY7K6U7.js +1 -0
- package/dist/m/core/save-core-MKRPSEEO.js +1 -0
- package/dist/m/core/snapshot-NU3YM6GR.js +1 -0
- package/dist/m/core/unsaved-warning-7QTKEN7Z.js +1 -0
- package/dist/m/internals/{index-PVXGPUDA.js → index-TGLQINN3.js} +1 -1
- package/dist/m/loader-3BBNZZGM.js +1 -0
- package/dist/m/manifest-F449FF98.js +1 -0
- package/dist/m/manifest-edit-4396A009.js +1 -0
- package/dist/m/manifest.json +2111 -1573
- package/dist/m/page/{editor-NNJA4OKD.js → editor-6LRB3GE4.js} +123 -21
- package/dist/m/plugins/ai-edit-UTV7YO2I.js +6 -0
- package/dist/m/plugins/{cms-HP3LSTPN.js → cms-LRAOZHT7.js} +9 -9
- package/dist/m/plugins/{demo-RM5IR6AO.js → demo-OYO5GCAO.js} +1 -1
- package/dist/m/plugins/{derive-UAAA4V4S.js → derive-FRE5JJQE.js} +1 -1
- package/dist/m/plugins/indicator-4VDXWYTD.js +1 -0
- package/dist/m/plugins/live-AD4H6XSL.js +1 -0
- package/dist/m/plugins/menu-M5WW7DBF.js +1 -0
- package/dist/m/plugins/page-MD3T2ZX3.js +2 -0
- package/dist/m/plugins/page-view-PAWVZNFY.js +1 -0
- package/dist/m/plugins/{people-SGPJKANK.js → people-JCHVPF7P.js} +1 -1
- package/dist/m/plugins/quickcrop-BQ5YYFCH.js +26 -0
- package/dist/m/plugins/{richclay-NRQDSWX6.js → richclay-KLGETK77.js} +2 -2
- package/dist/m/plugins/sortable-4S6SQC3D.js +1 -0
- package/dist/m/plugins/source-TJXOIOYY.js +1 -0
- package/dist/m/plugins/undo-NLPGCJQY.js +1 -0
- package/dist/m/plugins/{unsent-HJFLQJ2O.js → unsent-OA4RGBUT.js} +1 -1
- package/dist/m/plugins/upgrade-HSUNDNJD.js +1 -0
- package/dist/m/plugins/{upload-WLYKK6TL.js → upload-NHGJXZK2.js} +1 -1
- package/dist/m/plugins/visitor-drafts-BW43DGY3.js +20 -0
- package/dist/m/plugins/visitor-drafts-owner-7ODQG7JX.js +1 -0
- package/dist/m/plugins/{wire-4N6GYAF6.js → wire-VBWXEXU2.js} +1 -1
- package/dist/m/reader-core-4W2KYEWQ.js +77 -0
- package/dist/m/route/route-62CHXL5B.js +1 -0
- package/dist/m/sync/live-sync-MO5DH33W.js +1 -0
- package/dist/m/ui/index-IVWN2QC4.js +1 -0
- package/dist/m/vendor/sap-core.vendor-RN4ZVY4X.js +6 -0
- package/dist/offline-manifest.json +1367 -930
- package/dist/page/themes/light-1.css +8 -7
- package/dist/server/core.cjs +1440 -288
- package/dist/server/offline-runtime.cjs +63 -63
- package/dist/server/offline-runtime.mjs +63 -63
- package/dist/server/page-compaction-worker.cjs +3710 -0
- package/dist/server/rooms.mjs +5 -0
- package/docs/guide.md +653 -101
- package/entries/sap.js +5 -5
- package/package.json +1 -1
- package/src/core/admin-contenteditable.js +5 -2
- package/src/core/admin-inputs.js +1 -0
- package/src/core/admin-onclick.js +2 -1
- package/src/core/conflict-notice-ui.js +4 -7
- package/src/core/download.js +2 -2
- package/src/core/host-meta.js +38 -0
- package/src/core/is-edit-mode.js +17 -1
- package/src/core/mode-key.js +125 -19
- package/src/core/mode-support.js +5 -0
- package/src/core/mode-transition.js +20 -6
- package/src/core/preserve-authored.js +4 -4
- package/src/core/recovery.js +121 -33
- package/src/core/save-accepted.js +33 -0
- package/src/core/save-core.js +106 -31
- package/src/core/save-job.js +108 -0
- package/src/core/save-prepare.js +53 -0
- package/src/core/save-size-notice.js +3 -1
- package/src/core/save-slices.js +15 -0
- package/src/core/save.js +557 -127
- package/src/core/serialize-steps.js +109 -0
- package/src/core/snapshot.js +170 -39
- package/src/core/source-map.js +83 -38
- package/src/core/stale-host-notice.js +1 -0
- package/src/core/upgrade-run.js +59 -8
- package/src/dom/active-element.js +5 -0
- package/src/lib/assets.js +1 -0
- package/src/lib/slice.js +65 -0
- package/src/lib/uimotion.js +774 -0
- package/src/lib/unsaved-state.js +2 -2
- package/src/live/fast-lane.js +10 -3
- package/src/live/local-lane.js +202 -11
- package/src/live/ops.js +16 -0
- package/src/live/page-compaction.js +162 -0
- package/src/live/server-lane.js +1 -0
- package/src/live/store.js +11 -3
- package/src/loader-logic.js +3 -1
- package/src/loader.js +14 -4
- package/src/page/adopt-boot.js +2 -1
- package/src/page/awareness.js +33 -2
- package/src/page/blocks.js +89 -27
- package/src/page/boot-pack.js +1 -1
- package/src/page/chart-tables.js +21 -3
- package/src/page/chart.js +406 -63
- package/src/page/checklist.js +10 -135
- package/src/page/checkpoint-proof.js +7 -1
- package/src/page/chrome.js +250 -51
- package/src/page/clipboard-shape.js +126 -0
- package/src/page/drag.js +33 -3
- package/src/page/editor.js +136 -25
- package/src/page/export-assets.js +357 -0
- package/src/page/export-html.js +209 -0
- package/src/page/export-markdown.js +361 -0
- package/src/page/features/checklist.js +428 -0
- package/src/page/features/export-html.js +189 -0
- package/src/page/features/export-markdown.js +169 -0
- package/src/page/features/import-markdown.js +349 -0
- package/src/page/features/media.js +61 -5
- package/src/page/features/registry.js +18 -0
- package/src/page/features/table.js +373 -83
- package/src/page/features/title-cover.js +331 -0
- package/src/page/features/title-icon.js +213 -0
- package/src/page/features/toc.js +87 -0
- package/src/page/format-command.js +25 -1
- package/src/page/format-gate.js +68 -18
- package/src/page/format-host.js +17 -0
- package/src/page/format-native-commands.js +21 -5
- package/src/page/image-actions.js +64 -0
- package/src/page/import-markdown.js +262 -0
- package/src/page/items.js +135 -17
- package/src/page/markdown.js +6 -2
- package/src/page/media.js +35 -119
- package/src/page/placeholder.js +14 -1
- package/src/page/projection.js +98 -10
- package/src/page/recover.js +10 -12
- package/src/page/recovery-ui.js +464 -0
- package/src/page/rich/chart.js +63 -7
- package/src/page/save-projection.js +28 -0
- package/src/page/save-states.js +13 -3
- package/src/page/schema.js +19 -3
- package/src/page/table-paste.js +3 -1
- package/src/page/table-style.js +4 -4
- package/src/page/table.js +44 -2
- package/src/page/themes/light-1.css +8 -7
- package/src/page/themes/light-1.source.css +8 -7
- package/src/page/toc-link.js +31 -0
- package/src/page/toc.js +5 -0
- package/src/page/view-hooks.js +38 -12
- package/src/page/view.js +13 -0
- package/src/page/ybind/binding.js +88 -5
- package/src/page/ybind/bridge.js +187 -20
- package/src/page/ybind/containment.js +162 -0
- package/src/page/ybind/doc.js +17 -9
- package/src/page/ybind/file-debt.js +63 -0
- package/src/page/ybind/layout.js +7 -2
- package/src/page/ybind/marks.js +1 -1
- package/src/page/ybind/moves.js +5 -4
- package/src/page/ybind/origins.js +106 -4
- package/src/page/ybind/parts.js +8 -1
- package/src/page/ybind/provider.js +113 -17
- package/src/page/ybind/recovery-proof.js +32 -9
- package/src/page/ybind/recovery-replay.js +558 -15
- package/src/page/ybind/recovery.js +174 -45
- package/src/page/ybind/table.js +67 -11
- package/src/page/ybind/walk-delta.js +258 -0
- package/src/page/ybind/walk.js +54 -29
- package/src/page/ybind/writer.js +1 -1
- package/src/plugins/ai-edit.js +13 -9
- package/src/plugins/indicator-chip.js +91 -0
- package/src/plugins/indicator.js +13 -80
- package/src/plugins/live.js +89 -14
- package/src/plugins/menu/actions.js +196 -0
- package/src/plugins/menu/people.js +279 -0
- package/src/plugins/menu/placement.js +121 -0
- package/src/plugins/menu/preferences.js +9 -0
- package/src/plugins/menu/seo.js +316 -397
- package/src/plugins/menu/style.js +171 -0
- package/src/plugins/menu/variants.js +296 -0
- package/src/plugins/menu.js +186 -183
- package/src/plugins/page-view.js +3 -2
- package/src/plugins/page.js +249 -44
- package/src/plugins/sortable.js +8 -1
- package/src/plugins/source.js +6 -0
- package/src/plugins/upgrade.js +51 -17
- package/src/plugins/upload-ui.js +12 -17
- package/src/plugins/visitor-drafts/bottom-ui.js +12 -4
- package/src/plugins/visitor-drafts/intro-style.js +7 -2
- package/src/plugins/visitor-drafts/intro.js +5 -3
- package/src/plugins/visitor-drafts/owner-chip.js +8 -12
- package/src/plugins/visitor-drafts/prompt.js +11 -9
- package/src/plugins/visitor-drafts/source.js +4 -3
- package/src/plugins/visitor-drafts/store.js +138 -9
- package/src/plugins/visitor-drafts/ui-memory.js +2 -2
- package/src/plugins/visitor-drafts-owner.js +4 -6
- package/src/plugins/visitor-drafts.js +5 -3
- package/src/recovery/store.js +1 -1
- package/src/route/route.js +4 -0
- package/src/server/rooms/index.js +5 -1
- package/src/server/rooms/live-data-rooms.js +302 -50
- package/src/server/rooms/page-compaction-worker.js +12 -0
- package/src/server/rooms/page-compactor.js +92 -0
- package/src/server/rooms/page-room-conformance.js +461 -0
- package/src/source/parse-steps.js +94 -0
- package/src/source/session.js +233 -57
- package/src/sync/editing-sender.js +12 -0
- package/src/sync/live-sync-edit.js +22 -2
- package/src/sync/live-sync.js +150 -23
- package/src/sync/page-relay.js +52 -0
- package/src/sync/presence-store.js +44 -4
- package/src/sync/presence.js +6 -3
- package/src/sync/saved-stream.js +11 -6
- package/src/ui/bevel-controls.js +1 -0
- package/src/ui/bevel-dialog.js +5 -2
- package/src/ui/editor-ui.js +77 -0
- package/src/ui/page-colour.js +281 -0
- package/src/ui/toast.js +16 -7
- package/src/vendor/hyper-html-api-upgrade.vendor.js +2 -2
- package/src/vendor/hyper-undo.vendor.js +1 -1
- package/src/vendor/hypercms.vendor.js +9 -9
- package/src/vendor/parse5.vendor.js +2 -2
- package/src/vendor/sap-core.vendor.js +5 -5
- package/dist/m/c-2SPVQSHC.js +0 -1
- package/dist/m/c-336SGU5W.js +0 -1
- package/dist/m/c-3H6BZDNJ.js +0 -6
- package/dist/m/c-4DFEJ2PO.js +0 -3
- package/dist/m/c-56QRZTZH.js +0 -1
- package/dist/m/c-5J4E7O4Y.js +0 -4
- package/dist/m/c-5LKDWQTL.js +0 -19
- package/dist/m/c-5V3MOVJT.js +0 -1
- package/dist/m/c-6AZOGAPE.js +0 -1
- package/dist/m/c-6CRUUXOX.js +0 -5
- package/dist/m/c-6HMB24EV.js +0 -1
- package/dist/m/c-6KEVEQ7L.js +0 -1
- package/dist/m/c-A3E3NIMC.js +0 -1
- package/dist/m/c-BQ6LOBEE.js +0 -1
- package/dist/m/c-BTDI4Y23.js +0 -1
- package/dist/m/c-CJ3A7ZKE.js +0 -1
- package/dist/m/c-CQHPGKX2.js +0 -1
- package/dist/m/c-DFS4XZJV.js +0 -2
- package/dist/m/c-DNENWY4O.js +0 -1
- package/dist/m/c-E4LIR5X5.js +0 -1
- package/dist/m/c-FDNHHZY5.js +0 -1
- package/dist/m/c-FROJUZMV.js +0 -1
- package/dist/m/c-G2JPKCTP.js +0 -1
- package/dist/m/c-GB6TU7WV.js +0 -1
- package/dist/m/c-GFJJEBTU.js +0 -1
- package/dist/m/c-GJAEGGXY.js +0 -1
- package/dist/m/c-GOWBDM6J.js +0 -1
- package/dist/m/c-HFKUVACH.js +0 -1
- package/dist/m/c-HHDFCNHV.js +0 -1
- package/dist/m/c-IEM4NTCS.js +0 -1
- package/dist/m/c-JDCX26UP.js +0 -25
- package/dist/m/c-KGVGROZT.js +0 -1
- package/dist/m/c-KQ6TYJAP.js +0 -135
- package/dist/m/c-LFPHCXY3.js +0 -1
- package/dist/m/c-LRPUO2MX.js +0 -1
- package/dist/m/c-LWLBHLVC.js +0 -3
- package/dist/m/c-M2L47S2X.js +0 -7
- package/dist/m/c-MFP2ZWD4.js +0 -1
- package/dist/m/c-MKSQ4Y57.js +0 -1
- package/dist/m/c-NUFFJVVJ.js +0 -1
- package/dist/m/c-NUHSPT5P.js +0 -1
- package/dist/m/c-O72HVYSA.js +0 -1
- package/dist/m/c-OIBUTDXI.js +0 -1
- package/dist/m/c-OW5QIGG3.js +0 -1
- package/dist/m/c-PGRCK73F.js +0 -1
- package/dist/m/c-Q7NQD65V.js +0 -1
- package/dist/m/c-QH63LQOS.js +0 -1
- package/dist/m/c-R7IWVINQ.js +0 -1
- package/dist/m/c-RM7J7BV2.js +0 -1
- package/dist/m/c-S4ZEH46B.js +0 -9
- package/dist/m/c-SDAXDM2D.js +0 -1
- package/dist/m/c-SMGU7RT3.js +0 -235
- package/dist/m/c-SPIORRYS.js +0 -1
- package/dist/m/c-SWLRT66R.js +0 -1
- package/dist/m/c-TCJTVAFN.js +0 -1
- package/dist/m/c-TQEMVJCS.js +0 -1
- package/dist/m/c-TYLXX4NF.js +0 -21
- package/dist/m/c-U62OB4BT.js +0 -1
- package/dist/m/c-U6YWUAR3.js +0 -8
- package/dist/m/c-UDCSU5G5.js +0 -2
- package/dist/m/c-VI5RMSVY.js +0 -1
- package/dist/m/c-VRZN56XY.js +0 -1
- package/dist/m/c-W5MCHEGA.js +0 -1
- package/dist/m/c-WNYBLIOZ.js +0 -1
- package/dist/m/c-WWXIDH4O.js +0 -28
- package/dist/m/c-XCNTK76U.js +0 -1
- package/dist/m/c-XMS6DPBR.js +0 -1
- package/dist/m/c-ZUCOKOHT.js +0 -1
- package/dist/m/c-ZVPVXTJF.js +0 -4
- package/dist/m/c-ZVRKXKM7.js +0 -1
- package/dist/m/core/autosave-HRYGUWV6.js +0 -1
- package/dist/m/core/conflict-notice-6MROJN2L.js +0 -1
- package/dist/m/core/is-edit-mode-KTWA3O5N.js +0 -1
- package/dist/m/core/recovery-FLTCC2OC.js +0 -1
- package/dist/m/core/save-HQZ4S667.js +0 -1
- package/dist/m/core/save-core-KGQWFUNH.js +0 -1
- package/dist/m/core/snapshot-EGQZNT45.js +0 -1
- package/dist/m/core/unsaved-warning-IDJLD66H.js +0 -1
- package/dist/m/loader-S4I7GKXR.js +0 -1
- package/dist/m/manifest-4C419D67.js +0 -1
- package/dist/m/manifest-edit-B077F288.js +0 -1
- package/dist/m/plugins/ai-edit-QN4PMMNL.js +0 -6
- package/dist/m/plugins/indicator-URDBBOQO.js +0 -1
- package/dist/m/plugins/live-HFWD4OIH.js +0 -1
- package/dist/m/plugins/menu-3HIEQSI6.js +0 -138
- package/dist/m/plugins/page-JOKB6XPR.js +0 -2
- package/dist/m/plugins/page-view-NXOJHNW6.js +0 -1
- package/dist/m/plugins/quickcrop-QNY3PKLD.js +0 -26
- package/dist/m/plugins/sortable-GWT4PWDV.js +0 -1
- package/dist/m/plugins/source-4ZRSAIYM.js +0 -1
- package/dist/m/plugins/undo-VDA5P7FH.js +0 -1
- package/dist/m/plugins/upgrade-W7FG5VFG.js +0 -1
- package/dist/m/plugins/visitor-drafts-LIDY7NH6.js +0 -21
- package/dist/m/plugins/visitor-drafts-owner-ZXCKBZE7.js +0 -1
- package/dist/m/reader-core-DXYCURFF.js +0 -68
- package/dist/m/route/route-KOCZSEGN.js +0 -1
- package/dist/m/sync/live-sync-J7VMYTKS.js +0 -1
- package/dist/m/ui/index-3JLVI27O.js +0 -1
- package/dist/m/vendor/sap-core.vendor-A7BMUYZT.js +0 -6
- /package/dist/m/{c-FILLTJA7.js → c-QTTJYJMA.js} +0 -0
- /package/dist/m/plugins/{quickcrop-QNY3PKLD.js.LEGAL.txt → quickcrop-BQ5YYFCH.js.LEGAL.txt} +0 -0
- /package/dist/m/plugins/{richclay-NRQDSWX6.js.LEGAL.txt → richclay-KLGETK77.js.LEGAL.txt} +0 -0
package/src/loader.js
CHANGED
|
@@ -86,10 +86,11 @@ export async function boot(base, params, readyResolve, manifest = null, suppleme
|
|
|
86
86
|
const regionPolicy = await MODULES["lib/region-policy.js"]();
|
|
87
87
|
|
|
88
88
|
const hasSap = Boolean(document.querySelector("[sap]"));
|
|
89
|
+
const hasVariants = document.querySelectorAll("head style[clay-variant]").length >= 2;
|
|
89
90
|
// derive.js imports the sapjs core only when no sap.js script took the page over.
|
|
90
91
|
const hasSapJs = Boolean(document.querySelector('script[src*="sap.js"]'));
|
|
91
92
|
bootPhase.holdSettle = hasSap && isEditMode;
|
|
92
|
-
const plan = resolveModules(params, isEditMode, { isDraftMode, hasSap, canEdit, templateSource: templateSource() });
|
|
93
|
+
const plan = resolveModules(params, isEditMode, { isDraftMode, hasSap, hasVariants, canEdit, templateSource: templateSource() });
|
|
93
94
|
// Where edits land, resolved once: a visitor draft saves into its draft slot, the
|
|
94
95
|
// demo plugin into localStorage, and everything else to the host. setMode takes no
|
|
95
96
|
// destination, and V4 has no draft-to-host transition.
|
|
@@ -126,16 +127,22 @@ export async function boot(base, params, readyResolve, manifest = null, suppleme
|
|
|
126
127
|
// Nothing is fetched for it here: the decision and the controller behind it wait for the
|
|
127
128
|
// first switch, so this costs a reader with a declaration no more than one attribute.
|
|
128
129
|
if (document.documentElement.getAttribute("clay-mode-switch") === "live") {
|
|
129
|
-
const editing = resolveModules(params, true, { isDraftMode, hasSap, canEdit, templateSource: templateSource() });
|
|
130
|
+
const editing = resolveModules(params, true, { isDraftMode, hasSap, hasVariants, canEdit, templateSource: templateSource() });
|
|
130
131
|
loaded["core/edit-mode.js"].noteLiveSwitch({
|
|
131
132
|
edit: editing,
|
|
132
133
|
// The plan a view boot would have resolved, not the edit plan this boot resolved: an
|
|
133
134
|
// exit imports it and starts its reader, and an edit-only module belongs to the
|
|
134
135
|
// session being left.
|
|
135
|
-
view: resolveModules(params, false, { isDraftMode, hasSap, canEdit, templateSource: templateSource() }),
|
|
136
|
+
view: resolveModules(params, false, { isDraftMode, hasSap, hasVariants, canEdit, templateSource: templateSource() }),
|
|
136
137
|
loaded,
|
|
137
138
|
modules: MODULES,
|
|
138
|
-
|
|
139
|
+
// A live entry attaches the edit plugins after boot: clay.plugins names them from then on.
|
|
140
|
+
attach: (path, mod) => {
|
|
141
|
+
attachPluginMember(path, mod);
|
|
142
|
+
const name = PLUGIN_NAMES[path];
|
|
143
|
+
const named = window.clay.plugins;
|
|
144
|
+
if (name && Array.isArray(named) && !named.includes(name)) window.clay.plugins = Object.freeze([...named, name]);
|
|
145
|
+
},
|
|
139
146
|
attachEditCore,
|
|
140
147
|
announce,
|
|
141
148
|
loadEditHints: loadEditHints ? editHints(loadEditHints, manifest, editing, hasSapJs) : null,
|
|
@@ -146,6 +153,9 @@ export async function boot(base, params, readyResolve, manifest = null, suppleme
|
|
|
146
153
|
// leases before a plugin can take input. A reader returns at the first line.
|
|
147
154
|
await loaded["core/edit-mode.js"].activateInitialMode();
|
|
148
155
|
window.clay.plugins = Object.freeze([...plan.plugins, ...plan.late].map((path) => PLUGIN_NAMES[path]));
|
|
156
|
+
// What an edit session here would load, so view-mode chrome can offer an edit-only feature.
|
|
157
|
+
const editPlan = isEditMode ? plan : resolveModules(params, true, { isDraftMode, hasSap, hasVariants, canEdit, templateSource: templateSource() });
|
|
158
|
+
window.clay.editPlugins = Object.freeze([...editPlan.plugins, ...editPlan.late].map((path) => PLUGIN_NAMES[path]));
|
|
149
159
|
|
|
150
160
|
for (const path of plan.plugins) {
|
|
151
161
|
// A plugin that throws on evaluation degrades to absent. Unguarded, its
|
package/src/page/adopt-boot.js
CHANGED
|
@@ -54,6 +54,7 @@ export function installAdoption({
|
|
|
54
54
|
notice = () => {},
|
|
55
55
|
snapshot = () => null,
|
|
56
56
|
mergeTagless = false,
|
|
57
|
+
seeded = false,
|
|
57
58
|
writerReady = () => Promise.resolve(),
|
|
58
59
|
adopted = () => {},
|
|
59
60
|
hold = suspendAutosave,
|
|
@@ -216,7 +217,7 @@ export function installAdoption({
|
|
|
216
217
|
}
|
|
217
218
|
|
|
218
219
|
doc.addEventListener("clay:sync-applied", onFrame);
|
|
219
|
-
if (source) run(source, true);
|
|
220
|
+
if (source && !seeded) run(source, true);
|
|
220
221
|
|
|
221
222
|
return {
|
|
222
223
|
// Resolves once everything queued so far has been attempted, with the boot
|
package/src/page/awareness.js
CHANGED
|
@@ -54,6 +54,12 @@ const caretElement = (doc, name, color) => {
|
|
|
54
54
|
|
|
55
55
|
const labelOf = (person) => (typeof person.name === "string" && person.name.trim() ? person.name.trim() : "Someone");
|
|
56
56
|
|
|
57
|
+
let barrier = false;
|
|
58
|
+
if (typeof document !== "undefined") {
|
|
59
|
+
document.addEventListener("clay:presence-quiesce", () => { barrier = true; });
|
|
60
|
+
document.addEventListener("clay:presence-resume", () => { barrier = false; });
|
|
61
|
+
}
|
|
62
|
+
|
|
57
63
|
/**
|
|
58
64
|
* The decorations one snapshot produces in one document.
|
|
59
65
|
*
|
|
@@ -104,14 +110,20 @@ export function createPageAwareness({ binding, view, store = presenceStore, epoc
|
|
|
104
110
|
styleWithLegacyId(STYLE_ID, STYLE_CSS, STYLE_ID, ["editor-ui"]);
|
|
105
111
|
const doc = view.dom.ownerDocument;
|
|
106
112
|
let disposed = false;
|
|
107
|
-
|
|
113
|
+
// The exit's barrier, and the clear that came with it: while it runs this tab
|
|
114
|
+
// publishes nothing, so a caret move or a doc change during the barrier cannot put
|
|
115
|
+
// a target back the session is about to release.
|
|
116
|
+
let quiesced = barrier;
|
|
117
|
+
// Focus is a fact about the document, not a guess: an editor mounted in a background
|
|
118
|
+
// tab is not focused, and publishing a target for it would claim a caret nobody holds.
|
|
119
|
+
let focused = typeof view.hasFocus === "function" ? view.hasFocus() === true : view.dom.contains(doc.activeElement);
|
|
108
120
|
let pending = null;
|
|
109
121
|
const isComposing = () => (composing ? composing() === true : view.composing === true);
|
|
110
122
|
|
|
111
123
|
const supported = () => store.getSnapshot().pageAwareness !== false;
|
|
112
124
|
|
|
113
125
|
const publish = (state = view.state) => {
|
|
114
|
-
if (disposed) return;
|
|
126
|
+
if (disposed || quiesced) return;
|
|
115
127
|
if (!supported() || !focused || isComposing()) {
|
|
116
128
|
store.setTarget(null);
|
|
117
129
|
return;
|
|
@@ -167,6 +179,19 @@ export function createPageAwareness({ binding, view, store = presenceStore, epoc
|
|
|
167
179
|
schedule();
|
|
168
180
|
});
|
|
169
181
|
|
|
182
|
+
// The edit participant reaches these, so the page's target goes quiet with the
|
|
183
|
+
// sender during the exit's barrier and comes back with it on a refused exit.
|
|
184
|
+
const quiesce = () => {
|
|
185
|
+
if (disposed) return;
|
|
186
|
+
quiesced = true;
|
|
187
|
+
store.setTarget(null);
|
|
188
|
+
};
|
|
189
|
+
const resume = () => {
|
|
190
|
+
if (disposed) return;
|
|
191
|
+
quiesced = false;
|
|
192
|
+
publish();
|
|
193
|
+
};
|
|
194
|
+
|
|
170
195
|
const onFocus = () => { focused = true; publish(); schedule(); };
|
|
171
196
|
const onBlur = () => { focused = false; store.setTarget(null); };
|
|
172
197
|
const onHide = () => { store.setTarget(null); };
|
|
@@ -176,6 +201,8 @@ export function createPageAwareness({ binding, view, store = presenceStore, epoc
|
|
|
176
201
|
view.dom.addEventListener("blur", onBlur);
|
|
177
202
|
view.dom.addEventListener("compositionend", onCompositionEnd);
|
|
178
203
|
doc.addEventListener("pagehide", onHide);
|
|
204
|
+
doc.addEventListener("clay:presence-quiesce", quiesce);
|
|
205
|
+
doc.addEventListener("clay:presence-resume", resume);
|
|
179
206
|
view.updateState(view.state.reconfigure({ plugins: [...view.state.plugins, plugin] }));
|
|
180
207
|
publish();
|
|
181
208
|
schedule();
|
|
@@ -184,6 +211,8 @@ export function createPageAwareness({ binding, view, store = presenceStore, epoc
|
|
|
184
211
|
epoch,
|
|
185
212
|
refresh,
|
|
186
213
|
plugin,
|
|
214
|
+
quiesce,
|
|
215
|
+
resume,
|
|
187
216
|
get decorations() {
|
|
188
217
|
return awarenessKey.getState(view.state) ?? DecorationSet.empty;
|
|
189
218
|
},
|
|
@@ -199,6 +228,8 @@ export function createPageAwareness({ binding, view, store = presenceStore, epoc
|
|
|
199
228
|
view.dom.removeEventListener("blur", onBlur);
|
|
200
229
|
view.dom.removeEventListener("compositionend", onCompositionEnd);
|
|
201
230
|
doc.removeEventListener("pagehide", onHide);
|
|
231
|
+
doc.removeEventListener("clay:presence-quiesce", quiesce);
|
|
232
|
+
doc.removeEventListener("clay:presence-resume", resume);
|
|
202
233
|
store.setTarget(null);
|
|
203
234
|
store.releaseTarget();
|
|
204
235
|
if (!view.isDestroyed) {
|
package/src/page/blocks.js
CHANGED
|
@@ -9,7 +9,7 @@ import { safeHref, safeSrc } from "./link.js";
|
|
|
9
9
|
import { flatten, runsOf, unflatten, unitsOf } from "./inline.js";
|
|
10
10
|
import { OPAQUE_MARK, opaqueMark } from "./format-codec.js";
|
|
11
11
|
import { NATIVE_NAMES, nativeAttrs } from "./format-native.js";
|
|
12
|
-
import { DEFAULTS, MARKS, OPAQUE, envelopeAttrs, envelopeRecord, marksAttrs, marksEntries } from "./projection.js";
|
|
12
|
+
import { DEFAULTS, MARKS, OPAQUE, envelopeAttrs, envelopeRecord, marksAttrs, marksEntries, toggleLevel } from "./projection.js";
|
|
13
13
|
|
|
14
14
|
const alignOf = (a) => (a === "left" || a === "right" ? a : null);
|
|
15
15
|
|
|
@@ -37,7 +37,9 @@ const asStep = (dispatch) => dispatch && ((tr) => dispatch(history.closeHistory(
|
|
|
37
37
|
// hidden some toggle above it is closed
|
|
38
38
|
// subEnd index of the last block of its subtree (itself when it has none)
|
|
39
39
|
// A subtree is always contiguous, so it is the range [ents[i].at, ents[subEnd].end].
|
|
40
|
-
|
|
40
|
+
// `reveal` is a set of toggle ids a link opened for this reader only: a revealed
|
|
41
|
+
// toggle reads as open here, and its saved `open` is untouched.
|
|
42
|
+
export function outline(doc, reveal = null) {
|
|
41
43
|
const ents = [];
|
|
42
44
|
const toggleAt = new Map();
|
|
43
45
|
let run = [];
|
|
@@ -53,8 +55,9 @@ export function outline(doc) {
|
|
|
53
55
|
if (run.length) up = run[run.length - 1];
|
|
54
56
|
run.push(i);
|
|
55
57
|
} else run = [];
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
+
const open = isToggle(node) && (node.attrs.open || !!reveal?.has(node.attrs.id));
|
|
59
|
+
const hidden = t >= 0 && (ents[t].hidden || !ents[t].open);
|
|
60
|
+
ents.push({ node, at, end: at + node.nodeSize, i, up, depth: t >= 0 ? ents[t].depth + 1 : 0, hidden, open, subEnd: i });
|
|
58
61
|
if (isToggle(node) && node.attrs.id) toggleAt.set(node.attrs.id, i);
|
|
59
62
|
});
|
|
60
63
|
for (let j = ents.length - 1; j >= 0; j--) {
|
|
@@ -131,11 +134,19 @@ export function structureFixes(doc, oldDoc = null) {
|
|
|
131
134
|
}
|
|
132
135
|
|
|
133
136
|
export function structurePlugin() {
|
|
137
|
+
const valid = new WeakSet();
|
|
134
138
|
return new Plugin({
|
|
135
139
|
appendTransaction(trs, old, next) {
|
|
136
140
|
if (!trs.some((tr) => tr.docChanged && !tr.getMeta(REMOTE))) return null;
|
|
141
|
+
if (valid.has(old.doc) && sameStructure(old.doc, next.doc)) {
|
|
142
|
+
valid.add(next.doc);
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
137
145
|
const fixes = structureFixes(next.doc, old.doc);
|
|
138
|
-
if (!fixes.length)
|
|
146
|
+
if (!fixes.length) {
|
|
147
|
+
valid.add(next.doc);
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
139
150
|
const tr = next.tr;
|
|
140
151
|
for (const f of fixes) tr.setNodeMarkup(f.at, null, f.attrs);
|
|
141
152
|
return tr;
|
|
@@ -643,9 +654,22 @@ export function backspaceBodyBlock(st, dispatch) {
|
|
|
643
654
|
|
|
644
655
|
// ---- open / closed ----------------------------------------------------------
|
|
645
656
|
|
|
657
|
+
// A reveal is edit-mode state, never a document attribute: the toggle ids a followed link
|
|
658
|
+
// opened live in the collapse plugin's own state, so nothing is saved, no undo step is
|
|
659
|
+
// made and no peer is told.
|
|
660
|
+
export const REVEAL = "page-reveal";
|
|
661
|
+
|
|
662
|
+
export function revealToggles(tr, ids) {
|
|
663
|
+
return ids.length ? tr.setMeta(REVEAL, { add: ids }) : tr;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// A toggle the person opens or closes themselves drops any reveal a link left on it:
|
|
667
|
+
// the override never outlives the decision it saved them.
|
|
646
668
|
export function setOpen(st, ti, open, ents = outline(st.doc)) {
|
|
647
669
|
const e = ents[ti];
|
|
648
|
-
return st.tr.setNodeMarkup(e.at, null, { ...e.node.attrs, open })
|
|
670
|
+
return st.tr.setNodeMarkup(e.at, null, { ...e.node.attrs, open })
|
|
671
|
+
.setMeta("addToHistory", false)
|
|
672
|
+
.setMeta(REVEAL, { clear: [e.node.attrs.id] });
|
|
649
673
|
}
|
|
650
674
|
|
|
651
675
|
export function toggleOpenAtSelection(st, dispatch) {
|
|
@@ -662,7 +686,7 @@ export function toggleOpenAtSelection(st, dispatch) {
|
|
|
662
686
|
export function hiddenRanges(ents) {
|
|
663
687
|
const out = [];
|
|
664
688
|
for (const e of ents) {
|
|
665
|
-
if (!isToggle(e.node) || e.hidden || e.
|
|
689
|
+
if (!isToggle(e.node) || e.hidden || e.open || e.subEnd === e.i) continue;
|
|
666
690
|
out.push({ line: e.at + 1, sumEnd: e.end - 1, from: e.end, to: ents[e.subEnd].end });
|
|
667
691
|
}
|
|
668
692
|
return out;
|
|
@@ -759,35 +783,55 @@ export function sameStructure(a, b) {
|
|
|
759
783
|
return true;
|
|
760
784
|
}
|
|
761
785
|
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
786
|
+
const NO_REVEAL = new Set();
|
|
787
|
+
|
|
788
|
+
function collapseState(doc, reveal = NO_REVEAL) {
|
|
789
|
+
const ents = outline(doc, reveal);
|
|
790
|
+
return { decos: decorationsFor(doc, ents), ranges: hiddenRanges(ents), reveal };
|
|
765
791
|
}
|
|
766
792
|
|
|
793
|
+
// The block decorations of a long document in one linear pass. ProseMirror's
|
|
794
|
+
// DecorationSet scans every top-level node decoration for each child the view
|
|
795
|
+
// visits and each decoration it maps, which is quadratic in blocks; this set
|
|
796
|
+
// holds only node decorations at the top and finds a toggle's widget by binary
|
|
797
|
+
// search. It is built directly in document order instead of through create().
|
|
798
|
+
let OutlineSet = null;
|
|
799
|
+
const outlineSet = () => OutlineSet ??= class extends pmView.DecorationSet {
|
|
800
|
+
forChild(offset, node) {
|
|
801
|
+
if (node.isLeaf) return pmView.DecorationSet.empty;
|
|
802
|
+
const c = this.children;
|
|
803
|
+
let lo = 0, hi = c.length / 3;
|
|
804
|
+
while (lo < hi) { const mid = (lo + hi) >> 1; if (c[mid * 3] < offset) lo = mid + 1; else hi = mid; }
|
|
805
|
+
return lo * 3 < c.length && c[lo * 3] === offset ? c[lo * 3 + 2] : pmView.DecorationSet.empty;
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
|
|
767
809
|
export function decorationsFor(doc, ents = outline(doc)) {
|
|
768
810
|
const { Decoration, DecorationSet } = pmView;
|
|
769
811
|
const markers = orderedMarkers(ents);
|
|
770
|
-
const
|
|
812
|
+
const local = [], children = [];
|
|
771
813
|
for (const e of ents) {
|
|
772
814
|
const attrs = {};
|
|
773
815
|
if (e.hidden) { attrs.class = "page-hidden"; attrs["aria-hidden"] = "true"; }
|
|
774
816
|
if (e.depth) attrs.style = `--page-depth:${e.depth}`;
|
|
775
817
|
if (markers.has(e.i)) attrs["data-marker"] = markers.get(e.i);
|
|
776
|
-
if (isToggle(e.node)) attrs["aria-expanded"] = e.
|
|
777
|
-
if (Object.keys(attrs).length)
|
|
818
|
+
if (isToggle(e.node)) attrs["aria-expanded"] = e.open ? "true" : "false";
|
|
819
|
+
if (Object.keys(attrs).length) local.push(Decoration.node(e.at, e.end, attrs));
|
|
778
820
|
if (isToggle(e.node) && !e.hidden) {
|
|
779
|
-
|
|
821
|
+
const widget = Decoration.widget(0, () => disclosure(e.node, e.open), { side: -1, ignoreSelection: true, key: `t:${e.node.attrs.id}:${e.open}` });
|
|
822
|
+
children.push(e.at, e.end, new DecorationSet([widget], []));
|
|
780
823
|
}
|
|
781
824
|
}
|
|
782
|
-
return DecorationSet.
|
|
825
|
+
if (!local.length && !children.length) return DecorationSet.empty;
|
|
826
|
+
return new (outlineSet())(local, children);
|
|
783
827
|
}
|
|
784
828
|
|
|
785
|
-
function disclosure(node) {
|
|
829
|
+
function disclosure(node, open = node.attrs.open) {
|
|
786
830
|
const b = document.createElement("button");
|
|
787
831
|
b.type = "button";
|
|
788
832
|
b.className = "page-toggle-button";
|
|
789
833
|
b.contentEditable = "false";
|
|
790
|
-
b.setAttribute("aria-label",
|
|
834
|
+
b.setAttribute("aria-label", open ? "Collapse" : "Expand");
|
|
791
835
|
b.setAttribute("data-toggle", node.attrs.id || "");
|
|
792
836
|
return b;
|
|
793
837
|
}
|
|
@@ -799,13 +843,15 @@ export function collapsePlugin() {
|
|
|
799
843
|
state: {
|
|
800
844
|
init: (_, s) => collapseState(s.doc),
|
|
801
845
|
apply(tr, value, old, s) {
|
|
846
|
+
const meta = tr.getMeta(REVEAL);
|
|
847
|
+
if (meta) {
|
|
848
|
+
const reveal = new Set(value.reveal);
|
|
849
|
+
for (const id of meta.add ?? []) reveal.add(id);
|
|
850
|
+
for (const id of meta.clear ?? []) reveal.delete(id);
|
|
851
|
+
return collapseState(s.doc, reveal);
|
|
852
|
+
}
|
|
802
853
|
if (!tr.docChanged) return value;
|
|
803
|
-
|
|
804
|
-
const m = tr.mapping;
|
|
805
|
-
return {
|
|
806
|
-
decos: value.decos.map(m, s.doc),
|
|
807
|
-
ranges: value.ranges.map((r) => ({ line: m.map(r.line, -1), sumEnd: m.map(r.sumEnd), from: m.map(r.from), to: m.map(r.to, -1) })),
|
|
808
|
-
};
|
|
854
|
+
return collapseState(s.doc, value.reveal);
|
|
809
855
|
},
|
|
810
856
|
},
|
|
811
857
|
appendTransaction(trs, old, next) {
|
|
@@ -1002,7 +1048,12 @@ export function flattenPastedHTML(html, doc = globalThis.document) {
|
|
|
1002
1048
|
t.setAttribute("data-page-toggle", k);
|
|
1003
1049
|
if (child.hasAttribute("open")) t.setAttribute("data-open", "true");
|
|
1004
1050
|
if (parentKey) t.setAttribute("data-page-parent", parentKey);
|
|
1005
|
-
|
|
1051
|
+
// A toggle heading saves as a heading in its summary: keep the level, paste its text.
|
|
1052
|
+
const head = summary?.querySelector(":scope > h1, :scope > h2, :scope > h3");
|
|
1053
|
+
if (head) {
|
|
1054
|
+
t.setAttribute("data-level", head.tagName[1]);
|
|
1055
|
+
t.append(...head.childNodes);
|
|
1056
|
+
} else if (summary) t.append(...summary.childNodes);
|
|
1006
1057
|
target.appendChild(t);
|
|
1007
1058
|
for (const c of [...child.childNodes]) if (c !== summary) { const box = doc.createElement("div"); box.appendChild(c); walk(box, k, target); }
|
|
1008
1059
|
continue;
|
|
@@ -1043,6 +1094,8 @@ export function flattenPastedHTML(html, doc = globalThis.document) {
|
|
|
1043
1094
|
if (parent) for (const piece of pieces) piece.setAttribute("data-page-parent", parent);
|
|
1044
1095
|
child.replaceWith(...pieces);
|
|
1045
1096
|
}
|
|
1097
|
+
const sliced = root.querySelector("[data-pm-slice]");
|
|
1098
|
+
if (sliced) out.firstElementChild?.setAttribute("data-pm-slice", sliced.dataset.pmSlice);
|
|
1046
1099
|
return out.innerHTML;
|
|
1047
1100
|
}
|
|
1048
1101
|
|
|
@@ -1080,14 +1133,19 @@ const pastedOpaqueMarks = (dom) => {
|
|
|
1080
1133
|
try { return { entries: marksEntries(dom.getAttribute(MARKS)) }; } catch { return false; }
|
|
1081
1134
|
};
|
|
1082
1135
|
|
|
1136
|
+
// clipboard-shape.js: lists and tables on the clipboard.
|
|
1137
|
+
let shape = null;
|
|
1138
|
+
export const loadClipboardShape = () => import("./clipboard-shape.js").then((mod) => { shape = mod; }, () => {});
|
|
1139
|
+
|
|
1083
1140
|
// The clipboard parser: the schema has toDOM only, so paste gets its own rules.
|
|
1084
1141
|
export const clipboardParser = new model.DOMParser(parseSchema, [
|
|
1142
|
+
{ tag: "table", node: "table", getAttrs: (d) => shape?.table(d) ?? false, getContent: (d) => shape.rows(d) },
|
|
1085
1143
|
{ tag: `div[${OPAQUE}]`, node: "opaque_block", getAttrs: pastedOpaque, getContent: pastedOpaqueContent },
|
|
1086
1144
|
{ tag: `span[${MARKS}]`, mark: OPAQUE_MARK, getAttrs: pastedOpaqueMarks },
|
|
1087
1145
|
{ tag: "div[data-page-li]", node: "list_item", getAttrs: (d) => ({ kind: d.getAttribute("data-kind") || "bullet", indent: +d.getAttribute("data-indent") || 0, checked: d.getAttribute("data-checked") === "true", parent: parentAttr(d) }) },
|
|
1088
1146
|
{ tag: "div.page-li", node: "list_item", getAttrs: (d) => ({ kind: d.getAttribute("data-kind") || "bullet", indent: +d.getAttribute("data-indent") || 0, checked: d.getAttribute("data-checked") === "true", parent: parentAttr(d) }) },
|
|
1089
|
-
{ tag: "div[data-page-toggle]", node: "toggle", getAttrs: (d) => ({ id: d.getAttribute("data-page-toggle"), open: d.getAttribute("data-open") === "true", parent: parentAttr(d) }) },
|
|
1090
|
-
{ tag: "div.page-toggle", node: "toggle", getAttrs: (d) => ({ id: d.getAttribute("data-id"), open: d.getAttribute("data-open") === "true", parent: null }) },
|
|
1147
|
+
{ tag: "div[data-page-toggle]", node: "toggle", getAttrs: (d) => ({ id: d.getAttribute("data-page-toggle"), open: d.getAttribute("data-open") === "true", parent: parentAttr(d), level: toggleLevel(Number(d.getAttribute("data-level"))) }) },
|
|
1148
|
+
{ tag: "div.page-toggle", node: "toggle", getAttrs: (d) => ({ id: d.getAttribute("data-id"), open: d.getAttribute("data-open") === "true", parent: null, level: toggleLevel(Number(d.getAttribute("data-level"))) }) },
|
|
1091
1149
|
{ tag: "h1", node: "heading", getAttrs: (d) => ({ level: 1, parent: parentAttr(d) }) },
|
|
1092
1150
|
{ tag: "h2", node: "heading", getAttrs: (d) => ({ level: 2, parent: parentAttr(d) }) },
|
|
1093
1151
|
{ tag: "h3", node: "heading", getAttrs: (d) => ({ level: 3, parent: parentAttr(d) }) },
|
|
@@ -1173,6 +1231,7 @@ class ClipboardSerializer extends model.DOMSerializer {
|
|
|
1173
1231
|
if (isToggle(n) && n.attrs.id) dom.setAttribute("data-page-toggle", n.attrs.id);
|
|
1174
1232
|
if (n.type === N.image && n.attrs.width) dom.setAttribute("data-width", String(n.attrs.width));
|
|
1175
1233
|
});
|
|
1234
|
+
shape?.copy(fragment, doms);
|
|
1176
1235
|
return out;
|
|
1177
1236
|
}
|
|
1178
1237
|
}
|
|
@@ -1223,9 +1282,10 @@ function writesFormat(slice) {
|
|
|
1223
1282
|
|
|
1224
1283
|
function pasteFormat(view, event, slice) {
|
|
1225
1284
|
const from = view.state.selection.from, to = view.state.selection.to;
|
|
1285
|
+
const before = view.state.doc;
|
|
1226
1286
|
const plain = () => {
|
|
1227
1287
|
const text = slice.content.textBetween(0, slice.content.size, "\n", " ");
|
|
1228
|
-
if (!view.isDestroyed && text) view.dispatch(view.state.tr.insertText(text, from, to));
|
|
1288
|
+
if (!view.isDestroyed && text && view.state.doc === before) view.dispatch(view.state.tr.insertText(text, from, to));
|
|
1229
1289
|
return false;
|
|
1230
1290
|
};
|
|
1231
1291
|
import("./format-native-commands.js").then(({ pasteFormats }) => pasteFormats(view, slice, from, to), plain);
|
|
@@ -1234,12 +1294,14 @@ function pasteFormat(view, event, slice) {
|
|
|
1234
1294
|
|
|
1235
1295
|
export function pastePlugin() {
|
|
1236
1296
|
return new Plugin({
|
|
1297
|
+
view() { loadClipboardShape(); return {}; },
|
|
1237
1298
|
props: {
|
|
1238
1299
|
handlePaste(view, event, slice) {
|
|
1239
1300
|
if (writesFormat(slice)) return pasteFormat(view, event, slice);
|
|
1240
1301
|
return pasteIntoClosedSummary(view, event, slice);
|
|
1241
1302
|
},
|
|
1242
1303
|
clipboardSerializer,
|
|
1304
|
+
clipboardTextSerializer: (slice) => shape?.text(slice),
|
|
1243
1305
|
transformPastedHTML: (html) => flattenPastedHTML(html),
|
|
1244
1306
|
clipboardParser,
|
|
1245
1307
|
clipboardTextParser: (text, _$ctx, plain) => (plain ? null : parseListText(text)),
|
package/src/page/boot-pack.js
CHANGED
|
@@ -14,7 +14,7 @@ export { installAdoption, ADOPTION_TIMEOUT_MS } from "./adopt-boot.js";
|
|
|
14
14
|
export { classifyFile, readBack } from "./adopt.js";
|
|
15
15
|
export { mergePageModels } from "./merge.js";
|
|
16
16
|
export { canon } from "./projection.js";
|
|
17
|
-
export { renderFromTags } from "./save-projection.js";
|
|
17
|
+
export { renderFromTags, acceptedPageState } from "./save-projection.js";
|
|
18
18
|
export { blocksFromYValue } from "./ybind/decode.js";
|
|
19
19
|
export { createYPageBinding } from "./ybind/binding.js";
|
|
20
20
|
export { yValueOf } from "./ybind/provider.js";
|
package/src/page/chart-tables.js
CHANGED
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
import { schema } from "./schema.js";
|
|
2
2
|
import { orderedIds } from "./model.js";
|
|
3
3
|
|
|
4
|
-
// The tables a chart can be drawn from: a top-level table with
|
|
5
|
-
//
|
|
4
|
+
// The tables a chart can be drawn from: a top-level table with a labels column
|
|
5
|
+
// and at least one more to plot. The insert menu reads this without the chart module itself, which only
|
|
6
6
|
// a document that takes a chart loads.
|
|
7
7
|
export function chartTables(doc) {
|
|
8
8
|
const tables = [];
|
|
9
|
-
doc.forEach((node) => { if (node.type === schema.nodes.table && orderedIds(node.attrs.cols).length) tables.push(node); });
|
|
9
|
+
doc.forEach((node) => { if (node.type === schema.nodes.table && orderedIds(node.attrs.cols).length > 1) tables.push(node); });
|
|
10
10
|
return tables;
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
// A table's name for a person: the heading before it with no other table in
|
|
14
|
+
// between, else its place among the tables, so a chart and the picker name it
|
|
15
|
+
// without a stored title.
|
|
16
|
+
export function tableName(doc, tableId) {
|
|
17
|
+
let name = "";
|
|
18
|
+
let count = 0;
|
|
19
|
+
let found = null;
|
|
20
|
+
doc.forEach((node) => {
|
|
21
|
+
if (found !== null) return;
|
|
22
|
+
if (node.type === schema.nodes.heading) name = node.textContent;
|
|
23
|
+
if (node.type !== schema.nodes.table) return;
|
|
24
|
+
count += 1;
|
|
25
|
+
if (node.attrs.id === tableId) found = name || `Table ${count}`;
|
|
26
|
+
name = "";
|
|
27
|
+
});
|
|
28
|
+
return found;
|
|
29
|
+
}
|