@panphora/clayjs 1.15.2 → 1.17.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/README.md +4 -5
- package/THIRD-PARTY-NOTICES.md +16 -0
- package/compat/highlight-11.9.0.min.js +1213 -0
- package/compat/highlight-LICENSE +29 -0
- package/compat/journal-assets.lock.json +22 -0
- package/compat/overtype-2.6.1.min.js +116 -0
- package/compat/overtype-LICENSE +21 -0
- package/dist/all.js +90 -0
- package/dist/clay-dom.js +84 -0
- package/dist/clay-events.js +103 -0
- package/dist/clay-internals.js +85 -0
- package/dist/clay-options.js +93 -0
- package/dist/clay-router.js +98 -0
- package/dist/clay-ui.js +95 -0
- package/dist/clay-utils.js +84 -0
- package/dist/clay.js +146 -0
- package/dist/clay.standalone.js +84291 -57611
- package/dist/m/attrs/add-from-T5LJXFFI.js +1 -0
- package/dist/m/attrs/onaftersave-OKSWEJQF.js +1 -0
- package/dist/m/attrs/refetch-on-save-ZUE7PSCI.js +1 -0
- package/dist/m/attrs/save-freeze-MYNVXREN.js +1 -0
- package/dist/m/c-2AZDZWCK.js +1 -0
- package/dist/m/c-2SPVQSHC.js +1 -0
- package/dist/m/c-2YYDMLNZ.js +1 -0
- package/dist/m/c-336SGU5W.js +1 -0
- package/dist/m/c-33JJ6CBX.js +2 -0
- package/dist/m/c-3GJ4SDE2.js +1 -0
- package/dist/m/c-3H6BZDNJ.js +6 -0
- package/dist/m/c-3OWDMNJR.js +2 -0
- package/dist/m/c-3RUU4TPX.js +91 -0
- package/dist/m/c-3XIRD4NU.js +1 -0
- package/dist/m/c-46XYM55L.js +1 -0
- package/dist/m/c-4DFEJ2PO.js +3 -0
- package/dist/m/c-4JZDZFF6.js +1 -0
- package/dist/m/c-4L3BTFRK.js +1 -0
- package/dist/m/c-4Q2XTQ2N.js +2 -0
- package/dist/m/c-4WKFKEKF.js +1 -0
- package/dist/m/c-56QRZTZH.js +1 -0
- package/dist/m/c-5J4E7O4Y.js +4 -0
- package/dist/m/c-5LKDWQTL.js +19 -0
- package/dist/m/c-5QWQ7A5L.js +1 -0
- package/dist/m/c-5RJFTLSF.js +1 -0
- package/dist/m/c-5V3MOVJT.js +1 -0
- package/dist/m/c-5VYOWDTI.js +1 -0
- package/dist/m/c-5YIHJ3TJ.js +1 -0
- package/dist/m/c-6AZOGAPE.js +1 -0
- package/dist/m/c-6CRUUXOX.js +5 -0
- package/dist/m/c-6HMB24EV.js +1 -0
- package/dist/m/c-6KEVEQ7L.js +1 -0
- package/dist/m/c-6NC5I2TV.js +1 -0
- package/dist/m/c-74MGYWZF.js +1 -0
- package/dist/m/c-7DJDKPGL.js +1 -0
- package/dist/m/c-7OLLJPWP.js +1 -0
- package/dist/m/c-7SWMYKAI.js +1 -0
- package/dist/m/c-A3E3NIMC.js +1 -0
- package/dist/m/c-A7LS5UZW.js +1 -0
- package/dist/m/c-AMSNPOCX.js +1 -0
- package/dist/m/c-AQLFEATB.js +1 -0
- package/dist/m/c-B3JM5ZXC.js +1 -0
- package/dist/m/c-BBVGTQG7.js +1 -0
- package/dist/m/c-BPF2NSPV.js +1 -0
- package/dist/m/c-BQ6LOBEE.js +1 -0
- package/dist/m/c-BTDI4Y23.js +1 -0
- package/dist/m/c-BWFVSBDF.js +1 -0
- package/dist/m/c-BYTKL6UX.js +1 -0
- package/dist/m/c-CFHW5AMY.js +6 -0
- package/dist/m/c-CJ3A7ZKE.js +1 -0
- package/dist/m/c-CQHPGKX2.js +1 -0
- package/dist/m/c-CYWLPPUS.js +1 -0
- package/dist/m/c-CZUSOB7V.js +1 -0
- package/dist/m/c-DCFSEJZG.js +1 -0
- package/dist/m/c-DCXOXBF3.js +1 -0
- package/dist/m/c-DFS4XZJV.js +2 -0
- package/dist/m/c-DNENWY4O.js +1 -0
- package/dist/m/c-DNZ5IFM6.js +1 -0
- package/dist/m/c-E4LIR5X5.js +1 -0
- package/dist/m/c-EJTGYSLN.js +1 -0
- package/dist/m/c-EVCQ3BKA.js +1 -0
- package/dist/m/c-EZU56NQV.js +34 -0
- package/dist/m/c-FDNHHZY5.js +1 -0
- package/dist/m/c-FILLTJA7.js +1 -0
- package/dist/m/c-FRLHSY7E.js +1 -0
- package/dist/m/c-FROJUZMV.js +1 -0
- package/dist/m/c-G2JPKCTP.js +1 -0
- package/dist/m/c-GB6TU7WV.js +1 -0
- package/dist/m/c-GFJJEBTU.js +1 -0
- package/dist/m/c-GJAEGGXY.js +1 -0
- package/dist/m/c-GOWBDM6J.js +1 -0
- package/dist/m/c-GQ6F6IDK.js +1 -0
- package/dist/m/c-GSFIGKOP.js +1 -0
- package/dist/m/c-GY422N3Q.js +1 -0
- package/dist/m/c-H4LG442Q.js +1 -0
- package/dist/m/c-HA6INT6J.js +1 -0
- package/dist/m/c-HAWFNBYG.js +1 -0
- package/dist/m/c-HDDEEL77.js +1 -0
- package/dist/m/c-HFKUVACH.js +1 -0
- package/dist/m/c-HHDFCNHV.js +1 -0
- package/dist/m/c-HPURYVZS.js +2 -0
- package/dist/m/c-I2ZATQCD.js +2 -0
- package/dist/m/c-IEM4NTCS.js +1 -0
- package/dist/m/c-IJUK2GPW.js +1 -0
- package/dist/m/c-IW6GGOU2.js +1 -0
- package/dist/m/c-JAX2667S.js +6 -0
- package/dist/m/c-JDCX26UP.js +25 -0
- package/dist/m/c-JRKY44DK.js +1 -0
- package/dist/m/c-JU3NK25H.js +1 -0
- package/dist/m/c-KAU6E43D.js +1 -0
- package/dist/m/c-KBS3UV6B.js +1 -0
- package/dist/m/c-KGVGROZT.js +1 -0
- package/dist/m/c-KI7M4AY3.js +1 -0
- package/dist/m/c-KIPQJX4B.js +1 -0
- package/dist/m/c-KQ6TYJAP.js +135 -0
- package/dist/m/c-KU3ZFADW.js +1 -0
- package/dist/m/c-L4WQSC27.js +1 -0
- package/dist/m/c-LFPHCXY3.js +1 -0
- package/dist/m/c-LRPUO2MX.js +1 -0
- package/dist/m/c-LWLBHLVC.js +3 -0
- package/dist/m/c-LZJPNR2W.js +1 -0
- package/dist/m/c-M2L47S2X.js +7 -0
- package/dist/m/c-MFP2ZWD4.js +1 -0
- package/dist/m/c-MKSQ4Y57.js +1 -0
- package/dist/m/c-MTQHWQC3.js +1 -0
- package/dist/m/c-N326R2JD.js +1 -0
- package/dist/m/c-N7JPUPGC.js +1 -0
- package/dist/m/c-NRPJEVJS.js +1 -0
- package/dist/m/c-NUFFJVVJ.js +1 -0
- package/dist/m/c-NUHP2XDB.js +1 -0
- package/dist/m/c-NUHSPT5P.js +1 -0
- package/dist/m/c-O72HVYSA.js +1 -0
- package/dist/m/c-OCSZ4QGN.js +1 -0
- package/dist/m/c-OIBUTDXI.js +1 -0
- package/dist/m/c-OIDRZKAF.js +1 -0
- package/dist/m/c-OW5QIGG3.js +1 -0
- package/dist/m/c-P7KNDG34.js +1 -0
- package/dist/m/c-PGRCK73F.js +1 -0
- package/dist/m/c-PQ5LK6QE.js +993 -0
- package/dist/m/c-PS5ARVWR.js +9 -0
- package/dist/m/c-PZ4XEPUP.js +2 -0
- package/dist/m/c-Q622NS2Y.js +1 -0
- package/dist/m/c-Q7NQD65V.js +1 -0
- package/dist/m/c-QH63LQOS.js +1 -0
- package/dist/m/c-QHIWXHRO.js +1 -0
- package/dist/m/c-QHWJ5ZIJ.js +1 -0
- package/dist/m/c-QICP2YR5.js +1 -0
- package/dist/m/c-QJ4OM3G6.js +1 -0
- package/dist/m/c-QNKREOL6.js +1 -0
- package/dist/m/c-R3L7ZJGB.js +2 -0
- package/dist/m/c-R7IWVINQ.js +1 -0
- package/dist/m/c-RM7J7BV2.js +1 -0
- package/dist/m/c-RSMOODDU.js +1 -0
- package/dist/m/c-RVMWGXEJ.js +1 -0
- package/dist/m/c-RYUXUUBX.js +1 -0
- package/dist/m/c-S4ZEH46B.js +9 -0
- package/dist/m/c-S7H2DRCB.js +1 -0
- package/dist/m/c-S7LK4KUE.js +1 -0
- package/dist/m/c-SDAXDM2D.js +1 -0
- package/dist/m/c-SGIA4IEQ.js +188 -0
- package/dist/m/c-SMBZG5X4.js +1 -0
- package/dist/m/c-SMGU7RT3.js +235 -0
- package/dist/m/c-SPIORRYS.js +1 -0
- package/dist/m/c-SWLRT66R.js +1 -0
- package/dist/m/c-SZGYW5HT.js +1 -0
- package/dist/m/c-TCCA5BZN.js +2 -0
- package/dist/m/c-TCJTVAFN.js +1 -0
- package/dist/m/c-TJ6WOJL3.js +67 -0
- package/dist/m/c-TQEMVJCS.js +1 -0
- package/dist/m/c-TRS6TM6O.js +1 -0
- package/dist/m/c-TYLXX4NF.js +21 -0
- package/dist/m/c-U62OB4BT.js +1 -0
- package/dist/m/c-U6YWUAR3.js +8 -0
- package/dist/m/c-UDCSU5G5.js +2 -0
- package/dist/m/c-UDUUJPFZ.js +1 -0
- package/dist/m/c-UGHH4MB3.js +1 -0
- package/dist/m/c-UL2YUY52.js +1 -0
- package/dist/m/c-VAK7SG37.js +1 -0
- package/dist/m/c-VDSS4K3Z.js +1 -0
- package/dist/m/c-VE6ZMYMC.js +1 -0
- package/dist/m/c-VG5XIN4T.js +1 -0
- package/dist/m/c-VHM5XQHK.js +1 -0
- package/dist/m/c-VHNSBD2M.js +1 -0
- package/dist/m/c-VI5RMSVY.js +1 -0
- package/dist/m/c-VKEDWYDF.js +1 -0
- package/dist/m/c-VRZN56XY.js +1 -0
- package/dist/m/c-W5MCHEGA.js +1 -0
- package/dist/m/c-WDC5GVKU.js +1 -0
- package/dist/m/c-WN5AY3OZ.js +1 -0
- package/dist/m/c-WNYBLIOZ.js +1 -0
- package/dist/m/c-WRBKEJD4.js +1 -0
- package/dist/m/c-WWXIDH4O.js +28 -0
- package/dist/m/c-WYFDLITL.js +1 -0
- package/dist/m/c-XCNTK76U.js +1 -0
- package/dist/m/c-XMS6DPBR.js +1 -0
- package/dist/m/c-XN6MBKI6.js +67 -0
- package/dist/m/c-XPELB6E5.js +1 -0
- package/dist/m/c-XQXZAO7N.js +1 -0
- package/dist/m/c-Y5HBBIQ4.js +1 -0
- package/dist/m/c-ZE46QDIH.js +1 -0
- package/dist/m/c-ZUCOKOHT.js +1 -0
- package/dist/m/c-ZVPVXTJF.js +4 -0
- package/dist/m/c-ZVRKXKM7.js +1 -0
- package/dist/m/c-ZWIOJGMT.js +1 -0
- package/dist/m/core/admin-attrs-QHOKPJ7W.js +1 -0
- package/dist/m/core/autosave-HRYGUWV6.js +1 -0
- package/dist/m/core/conflict-notice-6MROJN2L.js +1 -0
- package/dist/m/core/draft-mode-WSQAT67S.js +1 -0
- package/dist/m/core/host-permission-FNXVEFNE.js +1 -0
- package/dist/m/core/is-edit-mode-KTWA3O5N.js +1 -0
- package/dist/m/core/persist-JFYRHMRJ.js +3 -0
- package/dist/m/core/recovery-FLTCC2OC.js +1 -0
- package/dist/m/core/save-HQZ4S667.js +1 -0
- package/dist/m/core/save-core-KGQWFUNH.js +1 -0
- package/dist/m/core/snapshot-EGQZNT45.js +1 -0
- package/dist/m/core/unsaved-warning-IDJLD66H.js +1 -0
- package/dist/m/dom/all-APS5ZSKP.js +1 -0
- package/dist/m/dom/dom-helpers-L7OSR6S4.js +1 -0
- package/dist/m/events/index-RN2JNGBV.js +1 -0
- package/dist/m/internals/index-PVXGPUDA.js +1 -0
- package/dist/m/lib/cache-bust-MUMFXZK6.js +1 -0
- package/dist/m/lib/region-policy-SB2AWVG5.js +1 -0
- package/dist/m/loader-S4I7GKXR.js +1 -0
- package/dist/m/manifest-4C419D67.js +1 -0
- package/dist/m/manifest-edit-B077F288.js +1 -0
- package/dist/m/manifest.json +3988 -0
- package/dist/m/options/options-EJMS3K24.js +1 -0
- package/dist/m/page/editor-NNJA4OKD.js +202 -0
- package/dist/m/plugins/ai-edit-QN4PMMNL.js +6 -0
- package/dist/m/plugins/bind-text-NX46N5UV.js +1 -0
- package/dist/m/plugins/cms-HP3LSTPN.js +2293 -0
- package/dist/m/plugins/demo-RM5IR6AO.js +1 -0
- package/dist/m/plugins/derive-UAAA4V4S.js +1 -0
- package/dist/m/plugins/indicator-URDBBOQO.js +1 -0
- package/dist/m/plugins/live-HFWD4OIH.js +1 -0
- package/dist/m/plugins/menu-3HIEQSI6.js +138 -0
- package/dist/m/plugins/message-LQ6EDH4V.js +1 -0
- package/dist/m/plugins/page-JOKB6XPR.js +2 -0
- package/dist/m/plugins/page-view-NXOJHNW6.js +1 -0
- package/dist/m/plugins/people-SGPJKANK.js +1 -0
- package/dist/m/plugins/quickcrop-QNY3PKLD.js +26 -0
- package/dist/m/plugins/quickcrop-QNY3PKLD.js.LEGAL.txt +7 -0
- package/dist/m/plugins/richclay-NRQDSWX6.js +517 -0
- package/dist/m/plugins/richclay-NRQDSWX6.js.LEGAL.txt +1 -0
- package/dist/m/plugins/sortable-GWT4PWDV.js +1 -0
- package/dist/m/plugins/source-4ZRSAIYM.js +1 -0
- package/dist/m/plugins/undo-VDA5P7FH.js +1 -0
- package/dist/m/plugins/unsent-HJFLQJ2O.js +1 -0
- package/dist/m/plugins/upgrade-W7FG5VFG.js +1 -0
- package/dist/m/plugins/upload-WLYKK6TL.js +1 -0
- package/dist/m/plugins/visitor-drafts-LIDY7NH6.js +21 -0
- package/dist/m/plugins/visitor-drafts-owner-ZXCKBZE7.js +1 -0
- package/dist/m/plugins/wire-4N6GYAF6.js +1 -0
- package/dist/m/reader-core-DXYCURFF.js +68 -0
- package/dist/m/route/route-KOCZSEGN.js +1 -0
- package/dist/m/sync/live-sync-J7VMYTKS.js +1 -0
- package/dist/m/ui/index-3JLVI27O.js +1 -0
- package/dist/m/utils/index-4TJCVLT7.js +1 -0
- package/dist/m/vendor/Sortable.vendor-A755ITLN.js +3 -0
- package/dist/m/vendor/Sortable.vendor-A755ITLN.js.LEGAL.txt +1 -0
- package/dist/m/vendor/sap-core.vendor-A7BMUYZT.js +6 -0
- package/dist/offline-manifest.json +4034 -0
- package/dist/page/themes/light-1.css +430 -0
- package/dist/server/core.cjs +23748 -22855
- package/dist/server/offline-runtime.cjs +4954 -0
- package/dist/server/offline-runtime.mjs +4923 -0
- package/dist/server/rooms.mjs +9 -0
- package/docs/guide.md +1078 -669
- package/entries/all.js +2 -0
- package/entries/clay-data.js +1 -1
- package/entries/clay-dom.js +2 -0
- package/entries/clay-events.js +2 -0
- package/entries/clay-internals.js +2 -0
- package/entries/clay-options.js +2 -0
- package/entries/clay-router.js +2 -0
- package/entries/clay-ui.js +2 -0
- package/entries/clay-utils.js +2 -0
- package/entries/clay.js +2 -0
- package/entries/sap.js +6 -6
- package/fonts/ibm-plex-mono-LICENSE +93 -0
- package/fonts/ibm-plex-mono-latin-300-normal.woff2 +0 -0
- package/fonts/ibm-plex-mono-latin-400-italic.woff2 +0 -0
- package/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
- package/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
- package/fonts/ibm-plex-mono-latin-600-normal.woff2 +0 -0
- package/fonts/ibm-plex-sans-LICENSE +93 -0
- package/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
- package/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
- package/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
- package/fonts/ibm-plex.css +71 -0
- package/fonts/inter-LICENSE +93 -0
- package/fonts/inter-cyrillic-ext-wght-normal.woff2 +0 -0
- package/fonts/inter-cyrillic-wght-normal.woff2 +0 -0
- package/fonts/inter-greek-ext-wght-normal.woff2 +0 -0
- package/fonts/inter-greek-wght-normal.woff2 +0 -0
- package/fonts/inter-latin-ext-wght-normal.woff2 +0 -0
- package/fonts/inter-latin-wght-normal.woff2 +0 -0
- package/fonts/inter-vietnamese-wght-normal.woff2 +0 -0
- package/fonts/inter.css +62 -0
- package/fonts/newsreader-LICENSE +93 -0
- package/fonts/newsreader-latin-ext-opsz-normal.woff2 +0 -0
- package/fonts/newsreader-latin-opsz-normal.woff2 +0 -0
- package/fonts/newsreader-vietnamese-opsz-normal.woff2 +0 -0
- package/fonts/newsreader.css +26 -0
- package/fonts/work-sans-LICENSE +93 -0
- package/fonts/work-sans-latin-wght-normal.woff2 +0 -0
- package/fonts/work-sans.css +8 -0
- package/package.json +20 -3
- package/packed-contract.json +1 -0
- package/src/attrs/add-from.js +27 -4
- package/src/attrs/save-freeze.js +7 -52
- package/src/core/admin-attrs.js +119 -12
- package/src/core/admin-contenteditable.js +12 -10
- package/src/core/admin-inputs.js +14 -15
- package/src/core/admin-onclick.js +2 -0
- package/src/core/autosave.js +74 -21
- package/src/core/boot-phase.js +2 -1
- package/src/core/conflict-download.js +19 -23
- package/src/core/conflict-notice-ui.js +1173 -0
- package/src/core/conflict-notice.js +140 -697
- package/src/core/download.js +32 -0
- package/src/core/edit-mode.js +147 -14
- package/src/core/etag.js +30 -12
- package/src/core/host-meta.js +90 -8
- package/src/core/host-permission.js +29 -0
- package/src/core/is-edit-mode.js +145 -12
- package/src/core/mode-key.js +125 -0
- package/src/core/mode-lifecycle.js +544 -0
- package/src/core/mode-receipt.js +30 -0
- package/src/core/mode-refusal.js +13 -0
- package/src/core/mode-resources.js +52 -0
- package/src/core/mode-support.js +82 -0
- package/src/core/mode-switch.js +259 -0
- package/src/core/mode-transition.js +112 -0
- package/src/core/page-data-write.js +305 -0
- package/src/core/page-data.js +26 -227
- package/src/core/page-format-wire.js +4 -0
- package/src/core/page-format.js +58 -0
- package/src/core/persist.js +37 -9
- package/src/core/preserve-authored.js +114 -0
- package/src/core/recovery.js +772 -0
- package/src/core/runtime-url.js +105 -0
- package/src/core/save-core.js +113 -12
- package/src/core/save-replace.js +72 -0
- package/src/core/save-size-notice.js +134 -0
- package/src/core/save-size.js +140 -0
- package/src/core/save.js +806 -119
- package/src/core/snapshot.js +159 -11
- package/src/core/source-map.js +157 -9
- package/src/core/unsaved-warning.js +14 -4
- package/src/core/upgrade-run.js +408 -0
- package/src/core/version.js +18 -0
- package/src/lib/assets.js +30 -0
- package/src/lib/autosave-debug-gate.js +50 -0
- package/src/lib/autosave-scheduler.js +140 -0
- package/src/lib/boot-imports.js +8 -0
- package/src/lib/derived.js +3 -1
- package/src/lib/dirty-gate.js +15 -0
- package/src/lib/doc-storage.js +33 -0
- package/src/lib/effect.js +9 -4
- package/src/lib/mutation.js +4 -2
- package/src/lib/offline-runtime.js +226 -0
- package/src/lib/preload.js +48 -0
- package/src/lib/root-attrs.js +1 -1
- package/src/lib/trash.js +18 -0
- package/src/lib/undo/capture-move.js +152 -0
- package/src/live/local-channel.js +61 -0
- package/src/live/local-lane.js +60 -9
- package/src/live/server-lane.js +6 -3
- package/src/loader-logic.js +76 -15
- package/src/loader.js +218 -30
- package/src/page/adopt-boot.js +76 -22
- package/src/page/adopt.js +25 -4
- package/src/page/awareness.js +230 -0
- package/src/page/blocks.js +113 -6
- package/src/page/blocksel.js +20 -4
- package/src/page/board-face.js +13 -0
- package/src/page/board-panel.js +5 -17
- package/src/page/board-style.js +2 -13
- package/src/page/board-view.js +1 -11
- package/src/page/board-views.js +3 -0
- package/src/page/board.js +2 -2
- package/src/page/boot-pack.js +26 -0
- package/src/page/boot.js +237 -0
- package/src/page/chart-tables.js +11 -0
- package/src/page/chart.js +6 -10
- package/src/page/checklist.js +1 -1
- package/src/page/checkpoint-proof.js +289 -0
- package/src/page/chrome.js +431 -63
- package/src/page/csv-import.js +17 -2
- package/src/page/document-title-dom.js +52 -0
- package/src/page/document-title-runtime.js +90 -0
- package/src/page/document-title.js +12 -0
- package/src/page/drag.js +48 -13
- package/src/page/drop.js +2 -1
- package/src/page/editor.js +399 -90
- package/src/page/emoji-data.js +162 -0
- package/src/page/feature-loader.js +72 -0
- package/src/page/features/board.js +21 -0
- package/src/page/features/chart.js +11 -0
- package/src/page/features/code.js +13 -0
- package/src/page/features/dates.js +180 -0
- package/src/page/features/emoji.js +187 -0
- package/src/page/features/media.js +290 -0
- package/src/page/features/mentions.js +188 -0
- package/src/page/features/registry.js +28 -0
- package/src/page/features/table.js +383 -0
- package/src/page/{tool-view.js → features/tool.js} +33 -2
- package/src/page/format-codec.js +215 -0
- package/src/page/format-command.js +9 -0
- package/src/page/format-gate.js +179 -0
- package/src/page/format-host.js +54 -0
- package/src/page/format-level.js +157 -0
- package/src/page/format-native-commands.js +142 -0
- package/src/page/format-native.js +42 -0
- package/src/page/highlight-slot.js +23 -0
- package/src/page/highlight.js +30 -16
- package/src/page/history-intent.js +78 -0
- package/src/page/inline.js +45 -28
- package/src/page/items.js +67 -14
- package/src/page/link.js +1 -0
- package/src/page/markdown.js +112 -3
- package/src/page/media-views.js +3 -0
- package/src/page/media.js +33 -245
- package/src/page/mention-picker.js +99 -0
- package/src/page/merge.js +1 -1
- package/src/page/outline-cache.js +11 -0
- package/src/page/placeholder.js +27 -7
- package/src/page/projection.js +240 -51
- package/src/page/reader-patch.js +306 -0
- package/src/page/recover.js +1 -1
- package/src/page/rich/page-tool.js +1 -4
- package/src/page/runtime-owner.js +27 -0
- package/src/page/save-projection.js +46 -4
- package/src/page/save-states.js +1 -1
- package/src/page/schema.js +47 -0
- package/src/page/table-rect-key.js +3 -0
- package/src/page/table-select.js +4 -3
- package/src/page/table-style.js +1 -1
- package/src/page/table-views.js +3 -0
- package/src/page/table.js +8 -293
- package/src/page/themes/content.css +25 -1
- package/src/page/themes/light-1.css +163 -2
- package/src/page/themes/light-1.source.css +269 -0
- package/src/page/tool-capability.js +3 -0
- package/src/page/tool-views.js +3 -0
- package/src/page/view-hooks.js +32 -0
- package/src/page/view.js +390 -107
- package/src/page/ybind/awareness.js +172 -0
- package/src/page/ybind/binding.js +40 -5
- package/src/page/ybind/bridge.js +50 -47
- package/src/page/ybind/decode.js +52 -19
- package/src/page/ybind/doc.js +27 -2
- package/src/page/ybind/group.js +12 -3
- package/src/page/ybind/index.js +2 -0
- package/src/page/ybind/lineage.js +71 -0
- package/src/page/ybind/marks.js +26 -1
- package/src/page/ybind/migrate.js +48 -13
- package/src/page/ybind/moves.js +32 -21
- package/src/page/ybind/positions.js +50 -0
- package/src/page/ybind/provider.js +97 -24
- package/src/page/ybind/recovery-proof.js +191 -0
- package/src/page/ybind/recovery-replay.js +488 -0
- package/src/page/ybind/tokens.js +15 -6
- package/src/page/ybind/walk.js +10 -3
- package/src/page/ybind/writer.js +48 -4
- package/src/plugins/ai-edit.js +167 -32
- package/src/plugins/bind-text.js +218 -0
- package/src/plugins/cms.js +93 -0
- package/src/plugins/indicator.js +57 -5
- package/src/plugins/live.js +319 -35
- package/src/plugins/menu/claygoo.svg.js +1 -0
- package/src/plugins/menu/seo-head.js +323 -0
- package/src/plugins/menu/seo.js +849 -0
- package/src/plugins/menu.js +425 -0
- package/src/plugins/page-view.js +131 -0
- package/src/plugins/page.js +1131 -270
- package/src/plugins/people.js +158 -31
- package/src/plugins/richclay.js +119 -9
- package/src/plugins/sortable.js +370 -60
- package/src/plugins/source.js +189 -366
- package/src/plugins/undo.js +289 -19
- package/src/plugins/unsent.js +132 -0
- package/src/plugins/upgrade-run.js +1 -0
- package/src/plugins/upgrade.js +210 -0
- package/src/plugins/upload-task.js +571 -0
- package/src/plugins/upload-ui.js +265 -0
- package/src/plugins/upload.js +34 -153
- package/src/plugins/visitor-drafts/inert.js +32 -0
- package/src/plugins/visitor-drafts/intro.js +2 -1
- package/src/plugins/visitor-drafts/owner-chip.js +3 -0
- package/src/plugins/visitor-drafts/prompt.js +2 -2
- package/src/plugins/visitor-drafts-owner.js +85 -0
- package/src/plugins/visitor-drafts.js +31 -42
- package/src/plugins/wire.js +82 -1
- package/src/reader-core.js +26 -0
- package/src/recovery/conflicts.js +287 -0
- package/src/recovery/identity.js +154 -0
- package/src/recovery/store.js +792 -0
- package/src/recovery/undo.js +257 -0
- package/src/server/checkpoint/index.js +68 -4
- package/src/server/offline-runtime/index.js +214 -0
- package/src/server/rooms/index.js +2 -1
- package/src/server/rooms/live-data-rooms.js +2 -2
- package/src/server/rooms/page-admission.js +33 -0
- package/src/server/rooms/page-lineage.js +56 -0
- package/src/server/rooms/page-rebase.js +11 -5
- package/src/server/rooms/page-state.js +2 -0
- package/src/server/rooms/page-write-admission.js +9 -3
- package/src/source/session.js +705 -0
- package/src/sync/conflict-revert.js +5 -4
- package/src/sync/conflicts-edit.js +119 -0
- package/src/sync/conflicts-facade.js +49 -0
- package/src/sync/conflicts.js +99 -1
- package/src/sync/editing-marker.js +37 -6
- package/src/sync/editing-sender.js +8 -1
- package/src/sync/live-sync-edit.js +63 -0
- package/src/sync/live-sync.js +364 -119
- package/src/sync/local-presence.js +187 -0
- package/src/sync/merge-declarations.js +10 -0
- package/src/sync/merge-engine.js +12 -0
- package/src/sync/presence-store.js +412 -0
- package/src/sync/presence-target.js +243 -0
- package/src/sync/presence.js +72 -41
- package/src/sync/saved-handoff.js +200 -0
- package/src/sync/saved-stream.js +544 -0
- package/src/sync/version-guard.js +92 -0
- package/src/sync/wire-profile.js +81 -0
- package/src/ui/bevel-controls.js +2 -8
- package/src/ui/page-scheme.js +7 -0
- package/src/ui/skins/cms.js +1 -1
- package/src/ui/theme-config.js +150 -0
- package/src/ui/theme.js +6 -138
- package/src/ui/toast-lazy.js +11 -0
- package/src/vendor/LICENSES-optional.md +253 -0
- package/src/vendor/highlight.vendor.js +3 -0
- package/src/vendor/hljs-bash.vendor.js +2 -0
- package/src/vendor/hljs-css.vendor.js +2 -0
- package/src/vendor/hljs-javascript.vendor.js +2 -0
- package/src/vendor/hljs-json.vendor.js +2 -0
- package/src/vendor/hljs-python.vendor.js +2 -0
- package/src/vendor/hljs-xml.vendor.js +2 -0
- package/src/vendor/hyper-html-api-data.vendor.js +1 -1
- package/src/vendor/hyper-html-api-upgrade.vendor.js +5 -0
- package/src/vendor/hyper-morph-identity.vendor.js +2 -0
- package/src/vendor/hyper-morph-json.vendor.js +3 -0
- package/src/vendor/hyper-morph.vendor.js +6 -6
- package/src/vendor/hyper-undo.vendor.js +1 -1
- package/src/vendor/hypercms.vendor.js +169 -84
- package/src/vendor/marked.vendor.js +68 -0
- package/src/vendor/overtype.vendor.js +994 -0
- package/src/vendor/richclay.vendor.js +17 -17
- package/src/vendor/sap-core.vendor.js +5 -5
- package/src/vendor/sap-ownership.vendor.js +11 -7
package/src/plugins/sortable.js
CHANGED
|
@@ -13,21 +13,84 @@
|
|
|
13
13
|
This wrapper conditionally loads the full Sortable.js vendor script (~118KB)
|
|
14
14
|
only when in edit mode, using dynamic import().
|
|
15
15
|
|
|
16
|
+
The editor it wires is one mode lease (see sortableParticipant): every instance,
|
|
17
|
+
subscription, listener and pending restore belongs to the session that made it, so a
|
|
18
|
+
page that leaves edit takes all of it back and a later entry starts from nothing
|
|
19
|
+
instead of from the previous session's leftovers.
|
|
20
|
+
|
|
16
21
|
*/
|
|
17
|
-
import { isEditMode } from "../core/is-edit-mode.js";
|
|
22
|
+
import { isEditMode, startsAtImport } from "../core/is-edit-mode.js";
|
|
18
23
|
import Mutation from "../lib/mutation.js";
|
|
19
24
|
import { capabilitySelector } from "../lib/region-capabilities.js";
|
|
20
25
|
import { onSnapshot } from "../core/snapshot.js";
|
|
26
|
+
import { beginMove, holdMove, releaseMove, releaseAllMoves, recordMove } from "../lib/undo/capture-move.js";
|
|
21
27
|
|
|
22
28
|
const EDITOR_UI_SELECTOR = capabilitySelector('history');
|
|
23
29
|
|
|
30
|
+
// The CMS hides one `cms-template` row in every list it fills: it is the seed a new row is
|
|
31
|
+
// cloned from, never a row itself. A drag never picks one up, and a move neither takes one
|
|
32
|
+
// nor lands before one.
|
|
33
|
+
const SEED_SELECTOR = '[cms-template]';
|
|
34
|
+
|
|
24
35
|
// Sortable marks the picked-up item and its links and images draggable="false" on press, and
|
|
25
36
|
// leaves style="" behind after a drag. Those attributes would be saved into the document, so a
|
|
26
37
|
// mere click would change the file. Record them when an item is chosen and put them back after.
|
|
27
38
|
const RUNTIME_ATTRS = ['draggable', 'style'];
|
|
28
39
|
|
|
40
|
+
// A press ends on one of these, wherever it lands.
|
|
41
|
+
const ENDS = ['pointerup', 'pointercancel', 'dragend', 'drop'];
|
|
42
|
+
|
|
43
|
+
// What a press recorded, for the snapshot hook below.
|
|
29
44
|
const pressed = new Set();
|
|
30
45
|
|
|
46
|
+
// The page's vendor constructor, snapshot transform, and one sortable session. All three
|
|
47
|
+
// outlive a session: a second entry asks for what the page already has rather than adding
|
|
48
|
+
// a second copy of it.
|
|
49
|
+
let vendor = null;
|
|
50
|
+
let installation = null;
|
|
51
|
+
let session = null;
|
|
52
|
+
|
|
53
|
+
// Every listener and timer a session starts is recorded with its target, type and options,
|
|
54
|
+
// so cleanup removes the exact subscription instead of hoping a bare type is enough.
|
|
55
|
+
function track(record, target, type, handler, options) {
|
|
56
|
+
const entry = { target, type, handler, options };
|
|
57
|
+
target.addEventListener(type, handler, options);
|
|
58
|
+
record.listeners.push(entry);
|
|
59
|
+
return entry;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function untrack(record, entry) {
|
|
63
|
+
entry.target.removeEventListener(entry.type, entry.handler, entry.options);
|
|
64
|
+
const index = record.listeners.indexOf(entry);
|
|
65
|
+
if (index !== -1) record.listeners.splice(index, 1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function later(record, run) {
|
|
69
|
+
const id = setTimeout(() => {
|
|
70
|
+
record.timers.delete(id);
|
|
71
|
+
run();
|
|
72
|
+
}, 0);
|
|
73
|
+
record.timers.add(id);
|
|
74
|
+
return id;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function ownership(Sortable, root) {
|
|
78
|
+
return {
|
|
79
|
+
Sortable,
|
|
80
|
+
root,
|
|
81
|
+
admitted: false,
|
|
82
|
+
instances: new Set(),
|
|
83
|
+
listeners: [],
|
|
84
|
+
timers: new Set(),
|
|
85
|
+
presses: new Set(),
|
|
86
|
+
stop: null,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// A direct makeSortable() call, outside any session, is still wired the same way; nothing
|
|
91
|
+
// disposes it, which is what such a call asked for.
|
|
92
|
+
const loose = { admitted: true, instances: new Set(), listeners: [], timers: new Set(), presses: new Set() };
|
|
93
|
+
|
|
31
94
|
function recordRuntimeAttrs(item) {
|
|
32
95
|
return [item, ...item.querySelectorAll('*')]
|
|
33
96
|
.filter(el => !el.closest(EDITOR_UI_SELECTOR))
|
|
@@ -50,10 +113,80 @@ function restoreRuntimeAttrs(recorded) {
|
|
|
50
113
|
}
|
|
51
114
|
}
|
|
52
115
|
|
|
53
|
-
|
|
116
|
+
// What one of a container's items is: a list holds its own rows, any other element holds
|
|
117
|
+
// its element children.
|
|
118
|
+
function childSelector(container) {
|
|
119
|
+
return /^(UL|OL)$/.test(container.tagName) ? 'li' : '*';
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function draggableSelector(container) {
|
|
123
|
+
return `> ${childSelector(container)}:not(${EDITOR_UI_SELECTOR})`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// The half of eligibility a container can answer about a node it does not hold yet: is
|
|
127
|
+
// this the kind of child it takes, and is it a real row rather than furniture or a seed?
|
|
128
|
+
// makeSortable gives the vendor the same rules through draggableSelector.
|
|
129
|
+
function acceptsItem(container, node) {
|
|
130
|
+
if (!container || !node || node.nodeType !== 1) return false;
|
|
131
|
+
if (!node.matches(childSelector(container))) return false;
|
|
132
|
+
return !node.closest(EDITOR_UI_SELECTOR) && !node.closest(SEED_SELECTOR);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function isItemOf(container, node) {
|
|
136
|
+
if (!container || !node || node.parentElement !== container) return false;
|
|
137
|
+
return acceptsItem(container, node);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// The next thing in the container that counts as an item. A seed row or a piece of editor
|
|
141
|
+
// furniture between two rows is not a position, so it is stepped over.
|
|
142
|
+
function nextItem(container, node) {
|
|
143
|
+
let sibling = node.nextElementSibling;
|
|
144
|
+
while (sibling && !isItemOf(container, sibling)) sibling = sibling.nextElementSibling;
|
|
145
|
+
return sibling;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// SortableJS reports a position as the item's element index among its container's
|
|
149
|
+
// children, and the facade keeps that convention so a drag report and a move report read
|
|
150
|
+
// the same way. Nothing in a template's intent should ever depend on these.
|
|
151
|
+
function elementIndex(container, node) {
|
|
152
|
+
return Array.prototype.indexOf.call(container.children, node);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// The one notification a completed reorder makes. A drag and clay.sortable.move() both
|
|
156
|
+
// reach it exactly once: the source container's author code, then `clay:sorted` with what
|
|
157
|
+
// moved, then the compatibility input event, both dispatched on the source container and
|
|
158
|
+
// bubbling from it.
|
|
159
|
+
function finishMove(result, onSorted) {
|
|
160
|
+
if (onSorted) {
|
|
161
|
+
try {
|
|
162
|
+
const asyncFn = new Function(`return (async function(evt) { ${onSorted} })`)();
|
|
163
|
+
asyncFn.call(result.from, result);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error('Error in onsorted execution:', error);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Announce the reorder as a real, self-documenting event carrying what moved.
|
|
169
|
+
// Reactive libs (e.g. Sap) and author code key off this without us knowing
|
|
170
|
+
// about them. Fires only in edit mode, since sortable only inits there.
|
|
171
|
+
result.from.dispatchEvent(new CustomEvent('clay:sorted', {
|
|
172
|
+
bubbles: true,
|
|
173
|
+
detail: {
|
|
174
|
+
item: result.item,
|
|
175
|
+
from: result.from,
|
|
176
|
+
to: result.to,
|
|
177
|
+
oldIndex: result.oldIndex,
|
|
178
|
+
newIndex: result.newIndex,
|
|
179
|
+
},
|
|
180
|
+
}));
|
|
181
|
+
// DEPRECATED: early versions dispatched a synthetic `input` here so reactive
|
|
182
|
+
// libs would re-derive. It is semantically off (a container has no value) and
|
|
183
|
+
// now redundant with clay:sorted and the mutation observers. Kept as a compat shim.
|
|
184
|
+
result.from.dispatchEvent(new Event('input', { bubbles: true }));
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function makeSortable(sortableElem, Sortable, record = loose) {
|
|
54
188
|
let options = {};
|
|
55
|
-
|
|
56
|
-
options.draggable = `> ${childSelector}:not(${EDITOR_UI_SELECTOR})`;
|
|
189
|
+
options.draggable = draggableSelector(sortableElem);
|
|
57
190
|
|
|
58
191
|
// Check if Sortable instance already exists
|
|
59
192
|
if (Sortable.get(sortableElem)) return;
|
|
@@ -78,6 +211,7 @@ function makeSortable(sortableElem, Sortable) {
|
|
|
78
211
|
const onsortingCode = sortableElem.getAttribute('onsorting');
|
|
79
212
|
if (onsortingCode) {
|
|
80
213
|
options.onMove = function(evt) {
|
|
214
|
+
if (!record.admitted) return;
|
|
81
215
|
try {
|
|
82
216
|
const asyncFn = new Function(`return (async function(evt) { ${onsortingCode} })`)();
|
|
83
217
|
asyncFn.call(sortableElem, evt);
|
|
@@ -90,68 +224,159 @@ function makeSortable(sortableElem, Sortable) {
|
|
|
90
224
|
// After a drop, run any author onsorted code, then notify reactive libraries.
|
|
91
225
|
const onsortedCode = sortableElem.getAttribute('onsorted');
|
|
92
226
|
options.onEnd = function(evt) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
227
|
+
// A session that has closed admission has already handed the page to the exit's
|
|
228
|
+
// barrier. The drop it allowed is not a new edit, so nothing of it reaches an author
|
|
229
|
+
// handler, a reactive engine or the file.
|
|
230
|
+
if (!record.admitted) return;
|
|
231
|
+
const result = { item: evt.item, from: evt.from, to: evt.to, oldIndex: evt.oldIndex, newIndex: evt.newIndex };
|
|
232
|
+
const start = press;
|
|
233
|
+
press = null;
|
|
234
|
+
// The runtime attributes go back before the move is recorded, so the entry holds
|
|
235
|
+
// the move and nothing of what the vendor wrote around it.
|
|
236
|
+
if (restoring) {
|
|
237
|
+
restoreRuntimeAttrs(restoring);
|
|
238
|
+
restoring = null;
|
|
100
239
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
detail: {
|
|
107
|
-
item: evt.item,
|
|
108
|
-
from: evt.from,
|
|
109
|
-
to: evt.to,
|
|
110
|
-
oldIndex: evt.oldIndex,
|
|
111
|
-
newIndex: evt.newIndex,
|
|
112
|
-
},
|
|
113
|
-
}));
|
|
114
|
-
// DEPRECATED: early versions dispatched a synthetic `input` here so reactive
|
|
115
|
-
// libs would re-derive. It is semantically off (a container has no value) and
|
|
116
|
-
// now redundant with clay:sorted and the mutation observers. Kept as a compat shim.
|
|
117
|
-
sortableElem.dispatchEvent(new Event('input', { bubbles: true }));
|
|
240
|
+
if (start) {
|
|
241
|
+
recordMove(start, result);
|
|
242
|
+
releaseMove(start);
|
|
243
|
+
}
|
|
244
|
+
finishMove(result, onsortedCode);
|
|
118
245
|
};
|
|
119
246
|
|
|
120
247
|
// Record on the capture phase, before Sortable's own press handler changes anything, and
|
|
121
248
|
// restore once the press ends: a plain click never fires Sortable's unchoose.
|
|
122
|
-
const ENDS = ['pointerup', 'pointercancel', 'dragend', 'drop'];
|
|
123
249
|
let recorded = null;
|
|
250
|
+
let press = null;
|
|
251
|
+
let restoring = null;
|
|
252
|
+
let started = false;
|
|
253
|
+
let ends = [];
|
|
254
|
+
// A press that ends without a drop (a click, a cancel) still has to hand the
|
|
255
|
+
// gesture's exclusion back: the drop itself releases it once its entry is recorded.
|
|
256
|
+
const endPress = () => {
|
|
257
|
+
const start = press;
|
|
258
|
+
press = null;
|
|
259
|
+
restoring = null;
|
|
260
|
+
releaseMove(start);
|
|
261
|
+
};
|
|
124
262
|
const restoreSoon = () => {
|
|
125
263
|
const pending = recorded;
|
|
126
264
|
recorded = null;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
265
|
+
if (pending) {
|
|
266
|
+
record.presses.delete(pending);
|
|
267
|
+
pressed.delete(pending);
|
|
268
|
+
restoring = pending;
|
|
269
|
+
}
|
|
270
|
+
ends.forEach(entry => untrack(record, entry));
|
|
271
|
+
ends = [];
|
|
272
|
+
if (pending) later(record, () => restoreRuntimeAttrs(pending));
|
|
273
|
+
};
|
|
274
|
+
const settleSoon = () => {
|
|
275
|
+
// Only the press that became a drag holds: a click has nothing to keep out of
|
|
276
|
+
// history, and its own handler's writes are the next entry.
|
|
277
|
+
if (started) {
|
|
278
|
+
holdMove(press);
|
|
279
|
+
} else {
|
|
280
|
+
releaseMove(press);
|
|
281
|
+
press = null;
|
|
282
|
+
}
|
|
283
|
+
started = false;
|
|
284
|
+
restoreSoon();
|
|
285
|
+
later(record, endPress);
|
|
130
286
|
};
|
|
131
|
-
sortableElem
|
|
287
|
+
track(record, sortableElem, 'pointerdown', (event) => {
|
|
132
288
|
let item = event.target instanceof Element ? event.target : null;
|
|
133
289
|
while (item && item.parentElement !== sortableElem) item = item.parentElement;
|
|
134
290
|
if (!item || recorded) return;
|
|
135
291
|
recorded = recordRuntimeAttrs(item);
|
|
292
|
+
press = beginMove(item);
|
|
293
|
+
started = false;
|
|
294
|
+
record.presses.add(recorded);
|
|
136
295
|
pressed.add(recorded);
|
|
137
|
-
ENDS.
|
|
296
|
+
ends = ENDS.map(type => track(record, document, type, settleSoon, true));
|
|
138
297
|
}, true);
|
|
139
298
|
options.onUnchoose = restoreSoon;
|
|
299
|
+
// The one signal a click never makes: Sortable says the press became a drag, so this
|
|
300
|
+
// press is the one that may hold the engine. A click's own writes are history's.
|
|
301
|
+
options.onStart = () => {
|
|
302
|
+
started = true;
|
|
303
|
+
};
|
|
140
304
|
|
|
141
305
|
Sortable.create(sortableElem, options);
|
|
306
|
+
record.instances.add(sortableElem);
|
|
142
307
|
}
|
|
143
308
|
|
|
144
|
-
|
|
145
|
-
|
|
309
|
+
// The semantic move: the reorder a drag makes, without dragging, without SortableJS and
|
|
310
|
+
// without waiting for it. Everything is validated before anything moves, and every
|
|
311
|
+
// refusal says why. It does not guess: an anchor that is gone is refused rather than
|
|
312
|
+
// re-targeted at a neighbour, and a request to stay put is not an insertion, an event or
|
|
313
|
+
// a history entry.
|
|
314
|
+
function move(item, toContainer, beforeItem = null) {
|
|
315
|
+
const refusal = (code) => ({ ok: false, code });
|
|
146
316
|
|
|
147
|
-
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
|
|
151
|
-
|
|
317
|
+
if (!isEditMode) return refusal('not-editable');
|
|
318
|
+
// Admission is the session's, exactly as a drag's is: a lease whose exit is already
|
|
319
|
+
// running has handed the page on, and a move is a new edit.
|
|
320
|
+
if (session && !session.admitted) return refusal('not-editable');
|
|
321
|
+
|
|
322
|
+
const doc = document;
|
|
323
|
+
if (!item || item.nodeType !== 1 || !item.isConnected || item.ownerDocument !== doc) {
|
|
324
|
+
return refusal('detached');
|
|
325
|
+
}
|
|
326
|
+
const from = item.parentElement;
|
|
327
|
+
if (!from || !from.isConnected) return refusal('detached');
|
|
328
|
+
if (!toContainer || toContainer.nodeType !== 1 || !toContainer.isConnected || toContainer.ownerDocument !== doc) {
|
|
329
|
+
return refusal('detached');
|
|
330
|
+
}
|
|
331
|
+
// The item has to be one of its source's own items, and the destination has to be a
|
|
332
|
+
// declared sortable that would hold it. A subtree cannot be moved into itself.
|
|
333
|
+
if (!from.hasAttribute('sortable') || !isItemOf(from, item)) return refusal('item');
|
|
334
|
+
if (!toContainer.hasAttribute('sortable') || !acceptsItem(toContainer, item)) return refusal('item');
|
|
335
|
+
if (item === toContainer || item.contains(toContainer)) return refusal('item');
|
|
336
|
+
// Crossing containers needs an equal, named group on both. Within one container there
|
|
337
|
+
// is nothing to compare, and SortableJS's own ungrouped lists stay single-list too.
|
|
338
|
+
if (from !== toContainer) {
|
|
339
|
+
const group = from.getAttribute('sortable');
|
|
340
|
+
if (!group || group !== toContainer.getAttribute('sortable')) return refusal('group');
|
|
341
|
+
}
|
|
342
|
+
// Asked to land before itself, the item is already where the call wants it.
|
|
343
|
+
if (beforeItem === item) return { ok: true, moved: false };
|
|
344
|
+
if (beforeItem !== null && !isItemOf(toContainer, beforeItem)) return refusal('anchor');
|
|
345
|
+
// The position the item already holds is not a move.
|
|
346
|
+
if (from === toContainer && nextItem(from, item) === beforeItem) return { ok: true, moved: false };
|
|
347
|
+
|
|
348
|
+
const oldIndex = elementIndex(from, item);
|
|
349
|
+
const start = beginMove(item);
|
|
350
|
+
holdMove(start);
|
|
351
|
+
let result;
|
|
352
|
+
try {
|
|
353
|
+
toContainer.insertBefore(item, beforeItem);
|
|
354
|
+
result = { item, from, to: toContainer, oldIndex, newIndex: elementIndex(toContainer, item) };
|
|
355
|
+
recordMove(start, result);
|
|
356
|
+
} finally {
|
|
357
|
+
releaseMove(start);
|
|
358
|
+
}
|
|
359
|
+
finishMove(result, from.getAttribute('onsorted'));
|
|
360
|
+
return { ok: true, moved: true, ...result };
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// Sortable's UMD header picks its target at run time: window.Sortable when no
|
|
364
|
+
// module system is present (a module load, and the single-file build), a
|
|
365
|
+
// default export when a bundler hands it one. Cover both. A failed fetch is forgotten,
|
|
366
|
+
// so the next entry asks again instead of inheriting the rejection.
|
|
367
|
+
function loadVendor() {
|
|
368
|
+
if (!vendor) {
|
|
369
|
+
vendor = import('../vendor/Sortable.vendor.js').then((mod) => window.Sortable || mod.default);
|
|
370
|
+
vendor.catch(() => { vendor = null; });
|
|
371
|
+
}
|
|
372
|
+
return vendor;
|
|
373
|
+
}
|
|
152
374
|
|
|
153
|
-
|
|
154
|
-
|
|
375
|
+
// A save taken mid-drag would otherwise write Sortable's classes and attributes into the
|
|
376
|
+
// file. Strip them from the snapshot clone only, so the live drag carries on untouched.
|
|
377
|
+
// Installed once, and it reads whatever the live session recorded.
|
|
378
|
+
function install() {
|
|
379
|
+
if (installation) return installation;
|
|
155
380
|
onSnapshot((root, { original }) => {
|
|
156
381
|
for (const el of root.querySelectorAll("[sortable] .sortable-chosen, [sortable] .sortable-ghost, [sortable] .sortable-drag")) {
|
|
157
382
|
el.classList.remove("sortable-chosen", "sortable-ghost", "sortable-drag");
|
|
@@ -168,27 +393,112 @@ async function init() {
|
|
|
168
393
|
});
|
|
169
394
|
}
|
|
170
395
|
});
|
|
396
|
+
installation = true;
|
|
397
|
+
return installation;
|
|
398
|
+
}
|
|
171
399
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
400
|
+
// One edit session over the live DOM. `enable` creates the instances and starts watching
|
|
401
|
+
// for containers that arrive afterwards; `quiesce` closes admission, so a drag that ends
|
|
402
|
+
// after it produces no event; `resume` is the refused exit; `dispose` destroys every
|
|
403
|
+
// instance this session created and removes exactly the subscriptions it added.
|
|
404
|
+
function sortableLease(record) {
|
|
405
|
+
return {
|
|
406
|
+
enable() {
|
|
407
|
+
if (record.admitted) return;
|
|
408
|
+
record.admitted = true;
|
|
409
|
+
for (const el of record.root.querySelectorAll('[sortable]')) makeSortable(el, record.Sortable, record);
|
|
410
|
+
// Set up listener for dynamically added elements.
|
|
411
|
+
// require:'observed' so drag works inside no-save / save-* regions (e.g. the
|
|
412
|
+
// CMS panel); pausable:false so it keeps wiring during a live-sync pause.
|
|
413
|
+
record.stop = Mutation.onAddElement({
|
|
414
|
+
selectorFilter: "[sortable]",
|
|
415
|
+
debounce: 200,
|
|
416
|
+
require: 'observed',
|
|
417
|
+
pausable: false
|
|
418
|
+
}, (changes) => {
|
|
419
|
+
if (!record.admitted) return;
|
|
420
|
+
changes.forEach(({ element }) => {
|
|
421
|
+
makeSortable(element, record.Sortable, record);
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
},
|
|
425
|
+
quiesce() {
|
|
426
|
+
record.admitted = false;
|
|
427
|
+
},
|
|
428
|
+
resume() {
|
|
429
|
+
record.admitted = true;
|
|
430
|
+
},
|
|
431
|
+
dispose() {
|
|
432
|
+
record.admitted = false;
|
|
433
|
+
if (record.stop) {
|
|
434
|
+
record.stop();
|
|
435
|
+
record.stop = null;
|
|
436
|
+
}
|
|
437
|
+
for (const entry of [...record.listeners]) untrack(record, entry);
|
|
438
|
+
for (const id of record.timers) clearTimeout(id);
|
|
439
|
+
record.timers.clear();
|
|
440
|
+
for (const recording of record.presses) pressed.delete(recording);
|
|
441
|
+
record.presses.clear();
|
|
442
|
+
releaseAllMoves();
|
|
443
|
+
for (const el of record.instances) record.Sortable?.get?.(el)?.destroy?.();
|
|
444
|
+
record.instances.clear();
|
|
445
|
+
if (session === record) session = null;
|
|
446
|
+
},
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const isStale = (context) => {
|
|
451
|
+
if (!context) return false;
|
|
452
|
+
if (context.signal?.aborted) return true;
|
|
453
|
+
return typeof context.isCurrent === "function" && !context.isCurrent();
|
|
454
|
+
};
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Sortable as a mode participant: the drag editor the commit that enters edit starts, and
|
|
458
|
+
* the one the exit takes back.
|
|
459
|
+
*
|
|
460
|
+
* `prepare` fetches the vendor and answers with the lease; the fetch can outlive the
|
|
461
|
+
* session that asked for it, so the generation is asked again once it is here. `enable`
|
|
462
|
+
* creates the instances. `quiesce` refuses a completion that arrives after it. `dispose`
|
|
463
|
+
* destroys the instances and hands back every listener and timer this session started.
|
|
464
|
+
*/
|
|
465
|
+
export function sortableParticipant(root = document) {
|
|
466
|
+
return {
|
|
467
|
+
id: "clay:sortable",
|
|
468
|
+
order: 300,
|
|
469
|
+
async prepare(context = {}) {
|
|
470
|
+
if (context.initial === true) return adopt();
|
|
471
|
+
const Sortable = await loadVendor();
|
|
472
|
+
if (isStale(context)) {
|
|
473
|
+
throw Object.assign(new Error("clay:sortable prepared for a stale generation"), { code: "stale-document" });
|
|
474
|
+
}
|
|
475
|
+
install();
|
|
476
|
+
return sortableLease(session || (session = ownership(Sortable, root)));
|
|
477
|
+
},
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// The boot this tab already made, adopted instead of prepared: it is the session `init`
|
|
482
|
+
// below enabled, or, on a boot that started none, nothing to hand back.
|
|
483
|
+
async function adopt() {
|
|
484
|
+
const lease = await ready;
|
|
485
|
+
return { enable() {}, quiesce: () => lease?.quiesce(), resume: () => lease?.resume(), dispose: () => lease?.dispose() };
|
|
188
486
|
}
|
|
189
487
|
|
|
190
488
|
// Auto-init when module is imported; the loader awaits `ready` before resolving clay.ready
|
|
489
|
+
async function init() {
|
|
490
|
+
if (!startsAtImport()) return null;
|
|
491
|
+
const lease = await sortableParticipant().prepare();
|
|
492
|
+
lease.enable();
|
|
493
|
+
return lease;
|
|
494
|
+
}
|
|
495
|
+
|
|
191
496
|
const ready = init();
|
|
192
497
|
|
|
193
|
-
|
|
498
|
+
// What the loader publishes on clay.sortable as soon as this module evaluates, so a move
|
|
499
|
+
// control never waits for the vendor the drag editor awaits.
|
|
500
|
+
const sortable = Object.freeze({ move });
|
|
501
|
+
|
|
502
|
+
export { init, ready, makeSortable, move, sortable };
|
|
503
|
+
export { sortableParticipant as modeParticipant };
|
|
194
504
|
export default init;
|