@panphora/clayjs 1.23.0 → 1.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/all.js +1 -1
- package/dist/blockeditor/themes/light-1.css +431 -0
- 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 +30285 -26613
- package/dist/m/c-277QP5ET.js +1 -0
- package/dist/m/c-2BLVA6IN.js +5 -0
- package/dist/m/c-2OJMOUPC.js +1 -0
- package/dist/m/c-2PVGJFI5.js +1 -0
- package/dist/m/{c-AYVGD6A6.js → c-3UW5EJ77.js} +1 -1
- package/dist/m/{c-T5NK2TVY.js → c-42ZNV7LI.js} +1 -1
- package/dist/m/{c-3TLG3OLG.js → c-46LJAZZJ.js} +1 -1
- package/dist/m/c-47IBJGPQ.js +1 -0
- package/dist/m/c-5FXEKU4Y.js +1 -0
- package/dist/m/c-5KXDKC5G.js +1 -0
- package/dist/m/{c-EUGJVHDD.js → c-5RZNFTWD.js} +1 -1
- package/dist/m/c-65LJU2H2.js +72 -0
- package/dist/m/{c-NQJRVJ56.js → c-6IJEVE6B.js} +1 -1
- package/dist/m/{c-NW54NHKE.js → c-6LEYVQJK.js} +1 -1
- package/dist/m/{c-GSRLXYWL.js → c-6Q6RGFBF.js} +1 -1
- package/dist/m/c-6RGEQNVV.js +1 -0
- package/dist/m/c-7CM4GMTS.js +6 -0
- package/dist/m/c-7NCWENHV.js +1 -0
- package/dist/m/c-7V6MGMX2.js +1 -0
- package/dist/m/{c-LKSL4AUJ.js → c-7WZSUTYP.js} +1 -1
- package/dist/m/c-A4L7APIU.js +1 -0
- package/dist/m/c-APGHGDZM.js +1 -0
- package/dist/m/c-AT7GLQGV.js +34 -0
- package/dist/m/{c-ZRXJD4G6.js → c-B7GOFGQR.js} +1 -1
- package/dist/m/{c-KDXIJEEF.js → c-BGN7RCTJ.js} +1 -1
- package/dist/m/c-BKM46LUJ.js +1 -0
- package/dist/m/c-BOMQIQ3V.js +1 -0
- package/dist/m/{c-62HZW5DH.js → c-C5AKJVRH.js} +1 -1
- package/dist/m/{c-BXYSDKAN.js → c-CJ7QYEWI.js} +1 -1
- package/dist/m/c-CTGRDT6E.js +1 -0
- package/dist/m/c-CV4T65JE.js +6 -0
- package/dist/m/c-CVSWLX3X.js +1 -0
- package/dist/m/c-CZHTXGJS.js +1 -0
- package/dist/m/c-D7NT5S4F.js +1 -0
- package/dist/m/c-DD26VXAP.js +1 -0
- package/dist/m/{c-ANNFZFLN.js → c-DDS23EY6.js} +1 -1
- package/dist/m/{c-ALDVFPWL.js → c-DFKBGSN2.js} +1 -1
- package/dist/m/c-DIKR7H57.js +147 -0
- package/dist/m/c-DXPOFLEJ.js +1 -0
- package/dist/m/c-EDE45NM7.js +1 -0
- package/dist/m/c-EILLN2H2.js +1 -0
- package/dist/m/c-EODTTNVA.js +1 -0
- package/dist/m/{c-G6COVIZB.js → c-ESK4S67I.js} +1 -1
- package/dist/m/c-FDWR3FL7.js +1 -0
- package/dist/m/{c-WQZTI5P2.js → c-FEC6LGFF.js} +1 -1
- package/dist/m/c-FLEIU6CG.js +1 -0
- package/dist/m/c-FQAQRXGK.js +1 -0
- package/dist/m/{c-W4JCVLAB.js → c-FSQXFG5T.js} +1 -1
- package/dist/m/c-FVPNX2GO.js +135 -0
- package/dist/m/c-FYDKYW6E.js +1 -0
- package/dist/m/c-GNI7WHKF.js +32 -0
- package/dist/m/c-GO635CRU.js +3 -0
- package/dist/m/c-H3FNLBHN.js +2 -0
- package/dist/m/c-HDVH3MVC.js +72 -0
- package/dist/m/c-HIX5H5L7.js +1 -0
- package/dist/m/c-HKSLOVU4.js +1 -0
- package/dist/m/{c-SGRIYOAJ.js → c-HL6BLJNA.js} +1 -1
- package/dist/m/c-HTLYXCUH.js +1 -0
- package/dist/m/{c-QIR5CAKM.js → c-IUL7PU4P.js} +1 -1
- package/dist/m/c-IXO7EI2Q.js +1 -0
- package/dist/m/{c-W5E5P2TZ.js → c-JQF2EUCG.js} +1 -1
- package/dist/m/{c-NEL7HQW3.js → c-JWDCQL6J.js} +1 -1
- package/dist/m/c-KQKKIVLW.js +20 -0
- package/dist/m/c-LATNQ6Q5.js +1 -0
- package/dist/m/c-LD6UVV5R.js +1 -0
- package/dist/m/c-LS7IVQVW.js +1 -0
- package/dist/m/{c-JCOQVZYS.js → c-LSVN3OLG.js} +1 -1
- package/dist/m/{c-JDZDF2QM.js → c-LTSPHVAK.js} +1 -1
- package/dist/m/c-MFOSMAVM.js +3 -0
- package/dist/m/c-MJ7GVE46.js +1 -0
- package/dist/m/c-MP6S4AZU.js +6 -0
- package/dist/m/c-MQKSKQHG.js +2 -0
- package/dist/m/{c-UHUNXWKN.js → c-MQYEDF3Q.js} +1 -1
- package/dist/m/{c-IHUWUKIU.js → c-MR75YPRT.js} +1 -1
- package/dist/m/c-ND3Q2G2I.js +1 -0
- package/dist/m/c-NEQRFC4O.js +1 -0
- package/dist/m/{c-5FKRZNJV.js → c-NFQFV7OP.js} +1 -1
- package/dist/m/c-NHXOBD6A.js +1 -0
- package/dist/m/{c-QIKT6SKM.js → c-NICICT4P.js} +1 -1
- package/dist/m/c-NQAPWM7O.js +1 -0
- package/dist/m/{c-QUGCKMWF.js → c-NVU3DORS.js} +1 -1
- package/dist/m/{c-LWIDDWAR.js → c-OCYG4NBQ.js} +22 -22
- package/dist/m/c-OH2FPYSY.js +19 -0
- package/dist/m/c-OYHI67B6.js +1 -0
- package/dist/m/{c-R2XUODVY.js → c-OYW5MFPZ.js} +1 -1
- package/dist/m/{c-5B4YBZXC.js → c-P2HKMJAW.js} +1 -1
- package/dist/m/{c-TSBVMWAH.js → c-PCNJETUA.js} +1 -1
- package/dist/m/c-PDBNCJCT.js +1 -0
- package/dist/m/c-PGSBXHUE.js +1 -0
- package/dist/m/{c-5TIZ2I64.js → c-PYG2NGWU.js} +1 -1
- package/dist/m/c-Q26XHBLQ.js +1 -0
- package/dist/m/c-Q6BG3ZLO.js +1 -0
- package/dist/m/c-QENKN7QI.js +1 -0
- package/dist/m/c-QQFHEODI.js +1 -0
- package/dist/m/c-QTEUO2K6.js +1 -0
- package/dist/m/c-R23UHMXG.js +1 -0
- package/dist/m/c-RETTCOWO.js +10 -0
- package/dist/m/c-SE3SIY7Y.js +7 -0
- package/dist/m/{c-XX75FFNL.js → c-SGGGCIVD.js} +1 -1
- package/dist/m/c-SGH3UTF3.js +1 -0
- package/dist/m/c-SIM7Z3U7.js +1 -0
- package/dist/m/{c-X5LNHET5.js → c-SKMIR5HQ.js} +1 -1
- package/dist/m/{c-R27DWQKX.js → c-STRI73GQ.js} +1 -1
- package/dist/m/c-SUXHUL7U.js +1 -0
- package/dist/m/c-SXGEWPFC.js +10 -0
- package/dist/m/c-SXNSSHPP.js +1 -0
- package/dist/m/c-T3P3AXEW.js +1 -0
- package/dist/m/{c-PXLTUYZC.js → c-TFLRT5JX.js} +1 -1
- package/dist/m/{c-YCLU4UNT.js → c-TGIMBAWE.js} +1 -1
- package/dist/m/c-TGSHHFO6.js +1 -0
- package/dist/m/c-U4NTUVDZ.js +1 -0
- package/dist/m/c-UOOIF2AL.js +1 -0
- package/dist/m/{c-6TYGD5AB.js → c-UOUUI265.js} +1 -1
- package/dist/m/c-V2U3F4QX.js +1 -0
- package/dist/m/c-V2V5FKXX.js +1 -0
- package/dist/m/c-VBXRXTVS.js +26 -0
- package/dist/m/c-VHSMPITY.js +1 -0
- package/dist/m/c-VPXCXBDT.js +1 -0
- package/dist/m/c-WCG6AKA7.js +1 -0
- package/dist/m/c-WNOLMHI2.js +1 -0
- package/dist/m/{c-CRPIDGXC.js → c-X6MOYATI.js} +1 -1
- package/dist/m/{c-FQGHR32O.js → c-X75G43SZ.js} +1 -1
- package/dist/m/c-XB6EAIAR.js +13 -0
- package/dist/m/c-XMIDHEKF.js +1 -0
- package/dist/m/c-XUZMRQ7O.js +4 -0
- package/dist/m/{c-2Z22FCFK.js → c-XW5TIYYB.js} +1 -1
- package/dist/m/c-YDW4VCHP.js +1 -0
- package/dist/m/{c-QGAPG7OM.js → c-YLHTD3KX.js} +1 -1
- package/dist/m/c-YNIEIPBS.js +1 -0
- package/dist/m/c-Z4G2UK6T.js +4 -0
- package/dist/m/c-Z6MROEQ4.js +1 -0
- package/dist/m/c-ZFO5RW6G.js +2 -0
- package/dist/m/c-ZGCO4J3H.js +8 -0
- package/dist/m/c-ZKKAF4UT.js +3 -0
- package/dist/m/c-ZRGEN6QQ.js +4 -0
- package/dist/m/core/{admin-attrs-U7IJNYBG.js → admin-attrs-ONRWVXPK.js} +1 -1
- package/dist/m/core/{autosave-F5YQCKVL.js → autosave-TBKAAAFB.js} +1 -1
- package/dist/m/core/conflict-notice-FOEE6I7E.js +1 -0
- package/dist/m/core/draft-mode-4MCL3LYI.js +1 -0
- package/dist/m/core/{host-permission-6EVJGNPL.js → host-permission-X4BENZEU.js} +1 -1
- package/dist/m/core/{is-edit-mode-GCX6767E.js → is-edit-mode-FFHCQ5DR.js} +1 -1
- package/dist/m/core/{persist-CJXIL7D4.js → persist-6ILUR34S.js} +1 -1
- package/dist/m/core/{recovery-DRFZRJED.js → recovery-APWADU4K.js} +1 -1
- package/dist/m/core/save-6HT2LABE.js +1 -0
- package/dist/m/core/save-core-EVMNZQ4V.js +1 -0
- package/dist/m/core/site-edits-G4BOZMV4.js +1 -0
- package/dist/m/core/{unsaved-warning-HNQVTA2D.js → unsaved-warning-ITZDIZ2I.js} +1 -1
- package/dist/m/internals/{index-NRPNDTSA.js → index-HS3CQDFW.js} +1 -1
- package/dist/m/loader-GLLVDUZA.js +1 -0
- package/dist/m/manifest-50FF1C45.js +1 -0
- package/dist/m/manifest-edit-BE1A621D.js +1 -0
- package/dist/m/manifest.json +2072 -1811
- package/dist/m/page/editor-KAZDJNND.js +307 -0
- package/dist/m/plugins/ai-edit-LABECCSN.js +6 -0
- package/dist/m/plugins/{cms-H7DTMUQX.js → cms-T2HLI7JG.js} +16 -16
- package/dist/m/plugins/{demo-42BSYQ7T.js → demo-T7B4RIKL.js} +1 -1
- package/dist/m/plugins/{derive-QVI3LI3A.js → derive-6LPJOCAV.js} +1 -1
- package/dist/m/plugins/indicator-J4ABFARX.js +1 -0
- package/dist/m/plugins/{live-DCUBKXY4.js → live-PGBIEMGB.js} +1 -1
- package/dist/m/plugins/menu-YZL3X2AJ.js +1 -0
- package/dist/m/plugins/page-WOCNX2IN.js +2 -0
- package/dist/m/plugins/page-view-SJODOOGE.js +1 -0
- package/dist/m/plugins/{people-5XRNRP5U.js → people-C4TCWFOQ.js} +1 -1
- package/dist/m/plugins/{quickcrop-WWF5I422.js → quickcrop-X5MRIBAP.js} +2 -2
- package/dist/m/plugins/richclay-Y2NV44NA.js +549 -0
- package/dist/m/plugins/sortable-XCHQG65Z.js +1 -0
- package/dist/m/plugins/{source-6BKMK4PO.js → source-YK7MO23W.js} +1 -1
- package/dist/m/plugins/{undo-3JEYK5QY.js → undo-VLRBQNPN.js} +1 -1
- package/dist/m/plugins/upgrade-NNTJBSK2.js +1 -0
- package/dist/m/plugins/{upload-TTCQRIM5.js → upload-ZKKJV76X.js} +1 -1
- package/dist/m/plugins/visitor-drafts-RTZNONHT.js +20 -0
- package/dist/m/plugins/{visitor-drafts-owner-Z5B2OQBR.js → visitor-drafts-owner-LHUHFU3L.js} +1 -1
- package/dist/m/plugins/{visitor-menu-4LQMKLPP.js → visitor-menu-FY4KM2SW.js} +1 -1
- package/dist/m/plugins/wire-M2NR354P.js +1 -0
- package/dist/m/{reader-core-POFQCKRV.js → reader-core-T2S3JC4E.js} +2 -2
- package/dist/m/sync/live-sync-Z64YREWQ.js +1 -0
- package/dist/m/ui/index-MGTWOW2C.js +1 -0
- package/dist/m/vendor/{sap-core.vendor-OA5SKL7Q.js → sap-core.vendor-QAEPMETX.js} +1 -1
- package/dist/offline-manifest.json +1250 -1082
- package/dist/server/core.cjs +132 -109
- package/dist/server/page-compaction-worker.cjs +5 -5
- package/dist/server/rooms.mjs +3 -1
- package/docs/guide.md +89 -44
- package/entries/clay-data.js +1 -1
- package/entries/sap.js +1 -1
- package/package.json +5 -3
- package/src/blockeditor/themes/content.css +70 -0
- package/src/blockeditor/themes/light-1.css +431 -0
- package/src/blockeditor/themes/light-1.source.css +270 -0
- package/src/blockeditor/themes/light-2.css +211 -0
- package/src/blockeditor/themes/light-3.css +130 -0
- package/src/blockeditor/themes/light-4.css +299 -0
- package/src/core/conflict-notice.js +28 -0
- package/src/core/draft-mode.js +6 -0
- package/src/core/host-meta.js +6 -6
- package/src/core/is-edit-mode.js +9 -3
- package/src/core/mode-support.js +3 -0
- package/src/core/mode-switch.js +4 -4
- package/src/core/mode-transition.js +3 -1
- package/src/core/page-format-wire.js +1 -1
- package/src/core/page-format.js +8 -8
- package/src/core/save-accepted.js +6 -7
- package/src/core/save-core.js +52 -23
- package/src/core/save-failure-notice.js +37 -0
- package/src/core/save-feedback.js +6 -0
- package/src/core/save-replace.js +1 -1
- package/src/core/save-size.js +2 -2
- package/src/core/save.js +78 -15
- package/src/core/site-edits.js +166 -0
- package/src/core/unsaved-warning.js +2 -2
- package/src/core/upgrade-run.js +4 -4
- package/src/lib/ai-comment.js +23 -0
- package/src/lib/effect.js +8 -0
- package/src/lib/idb-error-code.js +20 -0
- package/src/live/fast-lane.js +10 -10
- package/src/live/local-lane.js +10 -10
- package/src/live/page-compaction.js +8 -8
- package/src/live/server-lane.js +1 -1
- package/src/loader-logic.js +48 -18
- package/src/loader.js +11 -6
- package/src/page/adopt-boot.js +1 -1
- package/src/page/adopt.js +2 -2
- package/src/page/ai-area.js +182 -0
- package/src/page/ai-preview.js +80 -0
- package/src/page/ai-surface.js +257 -0
- package/src/page/ai-tool.js +308 -145
- package/src/page/announce.js +2 -2
- package/src/page/awareness.js +18 -18
- package/src/page/blocks.js +35 -34
- package/src/page/blocksel.js +2 -2
- package/src/page/board-drag.js +11 -11
- package/src/page/board-face.js +1 -1
- package/src/page/board-panel.js +26 -26
- package/src/page/board-style.js +127 -127
- package/src/page/board-view.js +48 -48
- package/src/page/chart.js +29 -29
- package/src/page/checkpoint-proof.js +19 -19
- package/src/page/chrome.js +74 -65
- package/src/page/clipboard-shape.js +1 -1
- package/src/page/csv-import.js +4 -4
- package/src/page/drag.js +5 -5
- package/src/page/editor.js +301 -296
- package/src/page/export-html.js +8 -8
- package/src/page/features/checklist.js +36 -36
- package/src/page/features/export-html.js +19 -19
- package/src/page/features/export-markdown.js +10 -10
- package/src/page/features/import-markdown.js +13 -13
- package/src/page/features/media.js +50 -50
- package/src/page/features/table.js +17 -17
- package/src/page/features/title-cover.js +17 -17
- package/src/page/features/title-icon.js +7 -7
- package/src/page/features/toc.js +1 -1
- package/src/page/features/tool.js +42 -18
- package/src/page/format-command.js +4 -4
- package/src/page/format-gate.js +6 -6
- package/src/page/format-host.js +6 -6
- package/src/page/format-level.js +3 -3
- package/src/page/format-native-commands.js +2 -2
- package/src/page/highlight-slot.js +1 -1
- package/src/page/highlight.js +4 -4
- package/src/page/history-intent.js +2 -2
- package/src/page/image-actions.js +4 -4
- package/src/page/link.js +10 -10
- package/src/page/media.js +3 -3
- package/src/page/mention-picker.js +7 -7
- package/src/page/merge.js +1 -1
- package/src/page/placeholder.js +3 -3
- package/src/page/projection.js +11 -11
- package/src/page/reader-patch.js +2 -2
- package/src/page/recover.js +26 -26
- package/src/page/recovery-ui.js +28 -28
- package/src/page/rich/chart.js +1 -1
- package/src/page/rich/page-tool.js +21 -6
- package/src/page/rich/tool-runtime.js +3 -2
- package/src/page/save-projection.js +2 -2
- package/src/page/save-states.js +9 -9
- package/src/page/schema.js +9 -9
- package/src/page/table-style.js +21 -21
- package/src/page/toc-link.js +1 -1
- package/src/page/tool-capability.js +8 -3
- package/src/page/tool-transport.js +52 -0
- package/src/page/tool-views.js +4 -0
- package/src/page/tools.js +6 -1
- package/src/page/view.js +6 -6
- package/src/page/ybind/binding.js +1 -1
- package/src/page/ybind/conversion.js +1 -1
- package/src/page/ybind/layout.js +4 -4
- package/src/page/ybind/migrate.js +1 -1
- package/src/page/ybind/origins.js +2 -2
- package/src/page/ybind/provider.js +2 -2
- package/src/page/ybind/recovery-proof.js +3 -3
- package/src/page/ybind/recovery-replay.js +2 -2
- package/src/plugins/ai-edit/picker.js +235 -0
- package/src/plugins/ai-edit.js +220 -34
- package/src/plugins/indicator-chip.js +39 -34
- package/src/plugins/indicator.js +13 -4
- package/src/plugins/live.js +21 -13
- package/src/plugins/menu/actions.js +89 -17
- package/src/plugins/menu/seo.js +32 -6
- package/src/plugins/menu/shell-style.js +26 -7
- package/src/plugins/menu/shell.js +12 -7
- package/src/plugins/menu/variants.js +6 -10
- package/src/plugins/menu/visitor.js +44 -34
- package/src/plugins/menu.js +3 -2
- package/src/plugins/page-view.js +2 -2
- package/src/plugins/page.js +257 -98
- package/src/plugins/sortable.js +7 -0
- package/src/plugins/upgrade.js +2 -1
- package/src/plugins/visitor-drafts/commit.js +303 -0
- package/src/plugins/visitor-drafts/idb.js +221 -0
- package/src/plugins/visitor-drafts/intro-style.js +1 -1
- package/src/plugins/visitor-drafts/intro.js +8 -25
- package/src/plugins/visitor-drafts/prompt.js +30 -4
- package/src/plugins/visitor-drafts/session.js +345 -0
- package/src/plugins/visitor-drafts/store.js +351 -32
- package/src/plugins/visitor-drafts.js +158 -27
- package/src/server/checkpoint/index.js +8 -8
- package/src/server/rooms/index.js +2 -2
- package/src/server/rooms/live-data-rooms.js +35 -35
- package/src/server/rooms/live-page-history.js +2 -2
- package/src/server/rooms/page-admission.js +34 -6
- package/src/server/rooms/page-conversion.js +1 -1
- package/src/server/rooms/page-lineage.js +4 -4
- package/src/server/rooms/page-rebase.js +4 -4
- package/src/server/rooms/page-room-conformance.js +14 -14
- package/src/server/rooms/page-state.js +2 -2
- package/src/server/rooms/page-write-admission.js +7 -7
- package/src/server/rooms/page-write-guard.js +3 -3
- package/src/sync/data-guard-notice.js +265 -0
- package/src/sync/live-sync.js +54 -11
- package/src/sync/page-relay.js +4 -4
- package/src/sync/presence-store.js +1 -1
- package/src/sync/presence-target.js +3 -3
- package/src/sync/presence.js +1 -1
- package/src/sync/stream.js +54 -13
- package/src/sync/wire-profile.js +8 -3
- package/src/ui/bevel.js +1 -1
- package/src/ui/index.js +9 -10
- package/src/ui/skins/cms.js +1 -1
- package/src/ui/skins/quickcrop.js +1 -1
- package/src/ui/skins/richclay.js +2 -2
- package/src/ui/toast-lazy.js +12 -3
- package/src/ui/toast.js +9 -3
- package/src/vendor/hyper-html-api-data.vendor.js +1 -1
- package/src/vendor/hyper-html-api-upgrade.vendor.js +2 -2
- package/src/vendor/hypercms.vendor.js +16 -16
- package/src/vendor/richclay.vendor.js +48 -20
- package/src/vendor/sap-core.vendor.js +1 -1
- package/tool-generation/context.md +44 -0
- package/tool-generation/system.md +23 -0
- package/dist/m/c-24PMUJIV.js +0 -2
- package/dist/m/c-2AYVYEI4.js +0 -1
- package/dist/m/c-2AZDZWCK.js +0 -1
- package/dist/m/c-2L6O5PDS.js +0 -6
- package/dist/m/c-2RYOGUQM.js +0 -2
- package/dist/m/c-2ZVOEU4M.js +0 -1
- package/dist/m/c-37NAONZA.js +0 -1
- package/dist/m/c-3GJ4SDE2.js +0 -1
- package/dist/m/c-3O7OBDCM.js +0 -1
- package/dist/m/c-5OJ7YF2N.js +0 -1
- package/dist/m/c-5WMXEKFH.js +0 -135
- package/dist/m/c-6RDOKLN7.js +0 -1
- package/dist/m/c-A4IP6MBC.js +0 -1
- package/dist/m/c-A6L3FMUS.js +0 -1
- package/dist/m/c-ATKAOH23.js +0 -1
- package/dist/m/c-B6O7AJYG.js +0 -32
- package/dist/m/c-BCGWJYXW.js +0 -1
- package/dist/m/c-BGKAT2FL.js +0 -7
- package/dist/m/c-BYTKL6UX.js +0 -1
- package/dist/m/c-DHBRA6DL.js +0 -1
- package/dist/m/c-DTMZ3ZHI.js +0 -1
- package/dist/m/c-E3ZXARWA.js +0 -1
- package/dist/m/c-EK63G3CG.js +0 -1
- package/dist/m/c-ELYIIYRS.js +0 -1
- package/dist/m/c-EXKHPOVC.js +0 -3
- package/dist/m/c-FCSZ3DC5.js +0 -20
- package/dist/m/c-FTWGYI5E.js +0 -1
- package/dist/m/c-G4PWUDD5.js +0 -1
- package/dist/m/c-GBKB5WDL.js +0 -2
- package/dist/m/c-GBTVCJXC.js +0 -1
- package/dist/m/c-GC2HICFJ.js +0 -1
- package/dist/m/c-GRWMD6O5.js +0 -1
- package/dist/m/c-HCNWJE4A.js +0 -4
- package/dist/m/c-HG2C77BM.js +0 -4
- package/dist/m/c-JGHEACGK.js +0 -1
- package/dist/m/c-JGLX6TBK.js +0 -1
- package/dist/m/c-JNRKHYWO.js +0 -1
- package/dist/m/c-KBS3UV6B.js +0 -1
- package/dist/m/c-KQ7E3PYY.js +0 -1
- package/dist/m/c-L3F5ZLIV.js +0 -1
- package/dist/m/c-L4KMT7FO.js +0 -6
- package/dist/m/c-L5VFATT6.js +0 -1
- package/dist/m/c-LCYPMULG.js +0 -1
- package/dist/m/c-LIGQYZ7M.js +0 -6
- package/dist/m/c-LKIWEPAV.js +0 -1
- package/dist/m/c-MPSKIU2I.js +0 -1
- package/dist/m/c-N7JPUPGC.js +0 -1
- package/dist/m/c-NK33MMYF.js +0 -1
- package/dist/m/c-NQLWOHLH.js +0 -10
- package/dist/m/c-NTHUTABN.js +0 -1
- package/dist/m/c-NWX3MFT4.js +0 -1
- package/dist/m/c-OKXI52N7.js +0 -1
- package/dist/m/c-OPONJ2UK.js +0 -128
- package/dist/m/c-OWQWOGYI.js +0 -1
- package/dist/m/c-P6Q2ZTFQ.js +0 -1
- package/dist/m/c-QEN6HZCA.js +0 -1
- package/dist/m/c-QIXT3Q7C.js +0 -28
- package/dist/m/c-QM5LXRDT.js +0 -9
- package/dist/m/c-QYYUVLVG.js +0 -1
- package/dist/m/c-RQRMPZXD.js +0 -1
- package/dist/m/c-SBCBXKOZ.js +0 -26
- package/dist/m/c-SKF5HL4I.js +0 -4
- package/dist/m/c-SRPC3VBE.js +0 -1
- package/dist/m/c-TANBH7FI.js +0 -1
- package/dist/m/c-THGQQDYY.js +0 -1
- package/dist/m/c-UD5JZTDL.js +0 -1
- package/dist/m/c-UDGEFWNU.js +0 -1
- package/dist/m/c-UGNV5MFB.js +0 -1
- package/dist/m/c-VIRFF5HG.js +0 -8
- package/dist/m/c-VJYEVRYK.js +0 -1
- package/dist/m/c-VQCEOGKH.js +0 -13
- package/dist/m/c-VYJ7O4RI.js +0 -34
- package/dist/m/c-W7IPVCAA.js +0 -1
- package/dist/m/c-WBGWGOM7.js +0 -1
- package/dist/m/c-WJ5DRBHT.js +0 -72
- package/dist/m/c-X5WC4PX5.js +0 -1
- package/dist/m/c-XCFQEWW6.js +0 -3
- package/dist/m/c-XGH4GS2T.js +0 -1
- package/dist/m/c-XLQ3BDMM.js +0 -1
- package/dist/m/c-ZQXNHZZT.js +0 -72
- package/dist/m/core/conflict-notice-42H4ASLA.js +0 -1
- package/dist/m/core/draft-mode-WSQAT67S.js +0 -1
- package/dist/m/core/save-ESPSQPLV.js +0 -1
- package/dist/m/core/save-core-6SQHOR6W.js +0 -1
- package/dist/m/loader-FBDE2UAB.js +0 -1
- package/dist/m/manifest-1D2F5CA5.js +0 -1
- package/dist/m/manifest-edit-F7CC5CFD.js +0 -1
- package/dist/m/page/editor-OSKOW6RS.js +0 -304
- package/dist/m/plugins/ai-edit-VV4QTINH.js +0 -6
- package/dist/m/plugins/indicator-WVPGMOZ7.js +0 -1
- package/dist/m/plugins/menu-Q4MFFQ6E.js +0 -1
- package/dist/m/plugins/page-OAWUJQEL.js +0 -2
- package/dist/m/plugins/page-view-DZ26ZDDQ.js +0 -1
- package/dist/m/plugins/richclay-PGOOJ4OK.js +0 -517
- package/dist/m/plugins/sortable-266HY6TR.js +0 -1
- package/dist/m/plugins/upgrade-BNZVFHMZ.js +0 -1
- package/dist/m/plugins/visitor-drafts-2AUYKAIJ.js +0 -20
- package/dist/m/plugins/wire-W2EV36KZ.js +0 -1
- package/dist/m/sync/live-sync-XGUPHI3I.js +0 -1
- package/dist/m/ui/index-VGYAKAKI.js +0 -1
- package/dist/page/themes/light-1.css +0 -431
- package/src/page/themes/content.css +0 -70
- package/src/page/themes/light-1.css +0 -431
- package/src/page/themes/light-1.source.css +0 -270
- package/src/page/themes/light-2.css +0 -211
- package/src/page/themes/light-3.css +0 -130
- package/src/page/themes/light-4.css +0 -299
- /package/dist/m/{c-FILLTJA7.js → c-QTTJYJMA.js} +0 -0
- /package/dist/m/plugins/{quickcrop-WWF5I422.js.LEGAL.txt → quickcrop-X5MRIBAP.js.LEGAL.txt} +0 -0
- /package/dist/m/plugins/{richclay-PGOOJ4OK.js.LEGAL.txt → richclay-Y2NV44NA.js.LEGAL.txt} +0 -0
package/src/page/format-gate.js
CHANGED
|
@@ -28,10 +28,10 @@
|
|
|
28
28
|
// admitted editors again and persists the marker, so a legacy registration that
|
|
29
29
|
// lands between `capabilities()` and `activate()` is refused rather than missed.
|
|
30
30
|
|
|
31
|
-
import { PAGE_FORMAT, PAGE_FORMAT_EXTENSION, PAGE_FORMAT_UPGRADE, formatCapability, notePageFormatFloor, pageFormatDecision,
|
|
31
|
+
import { PAGE_FORMAT, PAGE_FORMAT_EXTENSION, PAGE_FORMAT_UPGRADE, formatCapability, notePageFormatFloor, pageFormatDecision, blockeditorFormatFloor } from "./format-level.js";
|
|
32
32
|
import { registerUnsavedState } from "../lib/unsaved-state.js";
|
|
33
33
|
|
|
34
|
-
const PENDING_COMMAND = "
|
|
34
|
+
const PENDING_COMMAND = "blockeditor-format-command";
|
|
35
35
|
|
|
36
36
|
const UPGRADE_MESSAGE = "This document uses a newer page format; update the editor in the other tabs to keep writing";
|
|
37
37
|
|
|
@@ -80,7 +80,7 @@ export function createFormatGate({
|
|
|
80
80
|
async function read() {
|
|
81
81
|
try {
|
|
82
82
|
const answer = await host.read();
|
|
83
|
-
note(answer?.floor ??
|
|
83
|
+
note(answer?.floor ?? blockeditorFormatFloor(answer?.html));
|
|
84
84
|
} catch {}
|
|
85
85
|
return floor;
|
|
86
86
|
}
|
|
@@ -106,7 +106,7 @@ export function createFormatGate({
|
|
|
106
106
|
|
|
107
107
|
async function activateNow() {
|
|
108
108
|
if (disposed) return { status: "disposed", retry: false };
|
|
109
|
-
if (!(await supportedHere())) return { status: "unsupported-host", code: "
|
|
109
|
+
if (!(await supportedHere())) return { status: "unsupported-host", code: "blockeditor-format-unsupported", extension: PAGE_FORMAT_EXTENSION };
|
|
110
110
|
await read();
|
|
111
111
|
if (floor >= PAGE_FORMAT) {
|
|
112
112
|
await requestLane();
|
|
@@ -120,11 +120,11 @@ export function createFormatGate({
|
|
|
120
120
|
try {
|
|
121
121
|
answer = await host.activate({ floor: PAGE_FORMAT, capability, revision: stamp.revision, installed: stamp.installed });
|
|
122
122
|
} catch (error) {
|
|
123
|
-
return { status: "failed", code: "
|
|
123
|
+
return { status: "failed", code: "blockeditor-format-activation-failed", error, retry: true };
|
|
124
124
|
}
|
|
125
125
|
if (!answer || answer.accepted !== true) {
|
|
126
126
|
if (answer?.code === PAGE_FORMAT_UPGRADE) return upgrade(PAGE_FORMAT);
|
|
127
|
-
return { status: "failed", code: answer?.code ?? "
|
|
127
|
+
return { status: "failed", code: answer?.code ?? "blockeditor-format-activation-failed", retry: true };
|
|
128
128
|
}
|
|
129
129
|
if (disposed) {
|
|
130
130
|
// The save was accepted, so the document is at floor 1 either way; this
|
package/src/page/format-host.js
CHANGED
|
@@ -5,22 +5,22 @@
|
|
|
5
5
|
// The host is the authority, so `capabilities()` answers nothing here: the editors
|
|
6
6
|
// admitted to the document are checked under its admission/write lock when the save
|
|
7
7
|
// carrying the marker arrives, which is the check no registration can race. A save
|
|
8
|
-
// refused there reports `
|
|
8
|
+
// refused there reports `blockeditor-format-upgrade-required` like any other refusal, and
|
|
9
9
|
// this tab stays at the floor it already knew.
|
|
10
10
|
//
|
|
11
11
|
// Nothing is noted before the host answers: `notePageFormatFloor` runs when the gate
|
|
12
12
|
// accepts the activation, so a refusal leaves every later save at floor 0.
|
|
13
13
|
|
|
14
|
-
import { PAGE_FORMAT, PAGE_FORMAT_META, PAGE_FORMAT_UPGRADE, knownPageFormatFloor,
|
|
14
|
+
import { PAGE_FORMAT, PAGE_FORMAT_META, PAGE_FORMAT_UPGRADE, knownPageFormatFloor, blockeditorFormatFloor } from "./format-level.js";
|
|
15
15
|
import { hostPageFormat } from "../core/host-meta.js";
|
|
16
16
|
|
|
17
|
-
const FAILED = "
|
|
17
|
+
const FAILED = "blockeditor-format-activation-failed";
|
|
18
18
|
|
|
19
19
|
// The document's own marker, as it was served. A tab that joined a document already
|
|
20
20
|
// at floor 1 must not ask to activate it again.
|
|
21
21
|
function servedFloor() {
|
|
22
22
|
const tag = document.querySelector(`meta[name="${PAGE_FORMAT_META}"]`);
|
|
23
|
-
return tag ?
|
|
23
|
+
return tag ? blockeditorFormatFloor(tag.outerHTML) : 0;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// The editor's own explicit save, fetched when a floor is really raised: a tab that
|
|
@@ -55,10 +55,10 @@ export function createFormatHost({
|
|
|
55
55
|
async activate({ floor = PAGE_FORMAT } = {}) {
|
|
56
56
|
let result;
|
|
57
57
|
try {
|
|
58
|
-
result = await save({
|
|
58
|
+
result = await save({ blockeditorFormatFloor: floor });
|
|
59
59
|
for (let attempt = 1; attempt < SKIPPED_ATTEMPTS && skippedBehindSave(result); attempt += 1) {
|
|
60
60
|
await settles();
|
|
61
|
-
result = await save({
|
|
61
|
+
result = await save({ blockeditorFormatFloor: floor });
|
|
62
62
|
}
|
|
63
63
|
} catch (error) {
|
|
64
64
|
return { accepted: false, code: error?.code ?? FAILED };
|
package/src/page/format-level.js
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
//
|
|
4
4
|
// The canonical marker is document metadata, outside the unchanged `{v,g,y}`
|
|
5
5
|
// page value:
|
|
6
|
-
// <meta name="clay-
|
|
6
|
+
// <meta name="clay-blockeditor-format" content="1">
|
|
7
7
|
// Absence means floor 0. A document's floor only ever rises, and every path that
|
|
8
8
|
// writes a page declares the capability it writes with in
|
|
9
|
-
// `X-Clay-
|
|
9
|
+
// `X-Clay-Blockeditor-Format`. The value is protocol capability, not authorization: the
|
|
10
10
|
// host still applies every permission check.
|
|
11
11
|
//
|
|
12
12
|
// `requiredPageFormat` answers the other direction: what floor does THIS content
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
export {
|
|
17
17
|
PAGE_FORMAT, PAGE_FORMAT_HEADER, PAGE_FORMAT_META, PAGE_FORMAT_EXTENSION, PAGE_FORMAT_UPGRADE,
|
|
18
|
-
formatCapability,
|
|
18
|
+
formatCapability, blockeditorFormatFloor, withPageFormatFloor, knownPageFormatFloor, notePageFormatFloor,
|
|
19
19
|
} from "../core/page-format.js";
|
|
20
20
|
import { PAGE_FORMAT, PAGE_FORMAT_UPGRADE, formatCapability } from "../core/page-format.js";
|
|
21
21
|
|
|
@@ -18,7 +18,7 @@ import { openPageMenu } from "./chrome.js";
|
|
|
18
18
|
// blocks.js's STEP, read here rather than imported from it: this module is part
|
|
19
19
|
// of the projection's graph, and blocks.js reads the projection's constants as it
|
|
20
20
|
// loads. A command of ours is one undo item by itself, like every other command.
|
|
21
|
-
const STEP = "
|
|
21
|
+
const STEP = "blockeditor-step";
|
|
22
22
|
const asStep = (tr) => history.closeHistory(tr).setMeta(STEP, true);
|
|
23
23
|
|
|
24
24
|
const holds = (mark, attrs) => !!mark && Object.keys(mark.type.attrs).every((name) => mark.attrs[name] === attrs[name]);
|
|
@@ -55,7 +55,7 @@ function remove(view, type) {
|
|
|
55
55
|
// format, and a refusal leaves the content exactly as it was.
|
|
56
56
|
export function runFormat(view, apply) {
|
|
57
57
|
const run = view.runFormatCommand;
|
|
58
|
-
if (typeof run !== "function") return Promise.resolve({ status: "unsupported-host", code: "
|
|
58
|
+
if (typeof run !== "function") return Promise.resolve({ status: "unsupported-host", code: "blockeditor-format-unsupported", retry: false });
|
|
59
59
|
return run(apply);
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -6,7 +6,7 @@ import { state, view as pmView } from "../vendor/prosemirror.vendor.js";
|
|
|
6
6
|
const { Plugin, PluginKey } = state;
|
|
7
7
|
const { DecorationSet } = pmView;
|
|
8
8
|
|
|
9
|
-
export const highlightKey = new PluginKey("
|
|
9
|
+
export const highlightKey = new PluginKey("blockeditor-highlight");
|
|
10
10
|
|
|
11
11
|
export function highlightSlot() {
|
|
12
12
|
return new Plugin({
|
package/src/page/highlight.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Syntax colours for code blocks. A code block with a language gets inline
|
|
2
2
|
// decorations from Pierre's highlighter, loaded on first use (src/vendor/pierre/).
|
|
3
3
|
// Only blocks on screen are highlighted, and only after typing pauses. Colours are
|
|
4
|
-
// --
|
|
4
|
+
// --blockeditor-code-token-* variables, so each page theme sets them.
|
|
5
5
|
import { state, view as pmView } from "../vendor/prosemirror.vendor.js";
|
|
6
6
|
import { schema } from "./schema.js";
|
|
7
7
|
import { asStep } from "./blocksel.js";
|
|
@@ -54,7 +54,7 @@ const color = (name) => ({ color: name });
|
|
|
54
54
|
const THEME = {
|
|
55
55
|
name: "page",
|
|
56
56
|
appearance: "light",
|
|
57
|
-
cssVariables: { prefix: "--
|
|
57
|
+
cssVariables: { prefix: "--blockeditor-code-token-" },
|
|
58
58
|
style: {
|
|
59
59
|
syntax: {
|
|
60
60
|
comment: color("comment"),
|
|
@@ -99,7 +99,7 @@ export async function tokenize(code, lang) {
|
|
|
99
99
|
return codeToTokens(code, { lang, theme: THEME }).tokens;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
const FOREGROUND = "var(--
|
|
102
|
+
const FOREGROUND = "var(--blockeditor-code-token-foreground)";
|
|
103
103
|
const styleOf = (t) => {
|
|
104
104
|
const s = [];
|
|
105
105
|
if (t.color && t.color !== FOREGROUND) s.push(`color: ${t.color}`);
|
|
@@ -246,7 +246,7 @@ export class CodeBlockView {
|
|
|
246
246
|
this.dom = doc.createElement("pre");
|
|
247
247
|
this.contentDOM = doc.createElement("code");
|
|
248
248
|
this.select = doc.createElement("select");
|
|
249
|
-
this.select.className = "
|
|
249
|
+
this.select.className = "blockeditor-code-lang";
|
|
250
250
|
this.select.contentEditable = "false";
|
|
251
251
|
this.select.setAttribute("aria-label", "Code language");
|
|
252
252
|
for (const [id, label] of LANGS) this.select.append(new Option(label, id));
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { state } from "../vendor/prosemirror.vendor.js";
|
|
5
5
|
import { STEP } from "./blocks.js";
|
|
6
6
|
|
|
7
|
-
export const HISTORY_INTENT = "
|
|
7
|
+
export const HISTORY_INTENT = "blockeditor-history-intent";
|
|
8
8
|
export const GROUP_MS = 500;
|
|
9
9
|
|
|
10
10
|
const blockIdAt = (doc, pos) => {
|
|
@@ -29,7 +29,7 @@ export function continuesGroup(prev, next) {
|
|
|
29
29
|
const DELETES = { deleteContentBackward: -1, deleteContentForward: 1 };
|
|
30
30
|
const pendingDeletes = new WeakMap();
|
|
31
31
|
const PENDING_MS = 1000;
|
|
32
|
-
export const DERIVED = "
|
|
32
|
+
export const DERIVED = "blockeditor-derived";
|
|
33
33
|
|
|
34
34
|
// A native deletion arrives as a DOM change with no handler, sometimes after a delayed flush
|
|
35
35
|
// (Android waits 20 ms), so the beforeinput that announced it is held with the document it saw
|
|
@@ -28,10 +28,10 @@ export function openAltEditor(view, id) {
|
|
|
28
28
|
let at = 0;
|
|
29
29
|
for (let i = 0; i < index; i++) at += view.state.doc.child(i).nodeSize;
|
|
30
30
|
const box = doc.createElement("div");
|
|
31
|
-
box.className = "
|
|
31
|
+
box.className = "blockeditor-link";
|
|
32
32
|
box.dataset.mode = "alt";
|
|
33
33
|
const input = doc.createElement("input");
|
|
34
|
-
input.className = "
|
|
34
|
+
input.className = "blockeditor-link-input";
|
|
35
35
|
input.type = "text";
|
|
36
36
|
input.value = view.state.doc.child(index).attrs.alt || "";
|
|
37
37
|
input.placeholder = "Describe the image";
|
|
@@ -40,8 +40,8 @@ export function openAltEditor(view, id) {
|
|
|
40
40
|
const rect = view.nodeDOM(at)?.getBoundingClientRect?.();
|
|
41
41
|
const shellBox = shell.getBoundingClientRect();
|
|
42
42
|
if (rect) {
|
|
43
|
-
box.style.setProperty("--
|
|
44
|
-
box.style.setProperty("--
|
|
43
|
+
box.style.setProperty("--blockeditor-pop-x", `${rect.left - shellBox.left}px`);
|
|
44
|
+
box.style.setProperty("--blockeditor-pop-y", `${rect.bottom - shellBox.top + 6}px`);
|
|
45
45
|
}
|
|
46
46
|
shell.append(box);
|
|
47
47
|
let done = false;
|
package/src/page/link.js
CHANGED
|
@@ -35,7 +35,7 @@ export function setLinkTr(st, from, to, href) {
|
|
|
35
35
|
return asStep(tr);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
export const linkKey = new PluginKey("
|
|
38
|
+
export const linkKey = new PluginKey("blockeditor-link");
|
|
39
39
|
const popovers = new WeakMap();
|
|
40
40
|
|
|
41
41
|
const svg = (body) => `<svg viewBox="0 0 16 16" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${body}</svg>`;
|
|
@@ -63,14 +63,14 @@ class LinkPopover {
|
|
|
63
63
|
this.mode = null;
|
|
64
64
|
this.range = null;
|
|
65
65
|
const doc = this.doc;
|
|
66
|
-
this.dom = el(doc, "div", "
|
|
67
|
-
this.input = el(doc, "input", "
|
|
68
|
-
this.url = el(doc, "a", "
|
|
69
|
-
this.open = el(doc, "a", "
|
|
66
|
+
this.dom = el(doc, "div", "blockeditor-link", { role: "dialog", "aria-label": "Link", hidden: "" });
|
|
67
|
+
this.input = el(doc, "input", "blockeditor-link-input", { type: "url", "aria-label": "Link address", placeholder: "Paste or type a link", autocomplete: "off", spellcheck: "false" });
|
|
68
|
+
this.url = el(doc, "a", "blockeditor-link-url", { target: "_blank", rel: "noopener noreferrer" });
|
|
69
|
+
this.open = el(doc, "a", "blockeditor-link-btn", { "data-act": "open", target: "_blank", rel: "noopener noreferrer", "aria-label": "Open link in a new tab", title: "Open in a new tab" });
|
|
70
70
|
this.open.innerHTML = ICON_OPEN;
|
|
71
|
-
this.edit = el(doc, "button", "
|
|
71
|
+
this.edit = el(doc, "button", "blockeditor-link-btn", { type: "button", "data-act": "edit" });
|
|
72
72
|
this.edit.textContent = "Edit";
|
|
73
|
-
this.remove = el(doc, "button", "
|
|
73
|
+
this.remove = el(doc, "button", "blockeditor-link-btn", { type: "button", "data-act": "remove", "aria-label": "Remove link", title: "Remove link" });
|
|
74
74
|
this.remove.innerHTML = ICON_REMOVE;
|
|
75
75
|
this.dom.append(this.input, this.url, this.open, this.edit, this.remove);
|
|
76
76
|
this.shell.append(this.dom);
|
|
@@ -153,8 +153,8 @@ class LinkPopover {
|
|
|
153
153
|
if (!r) return;
|
|
154
154
|
const shellBox = this.shell.getBoundingClientRect();
|
|
155
155
|
const a = this.view.coordsAtPos(r.from), b = this.view.coordsAtPos(r.to, -1);
|
|
156
|
-
this.dom.style.setProperty("--
|
|
157
|
-
this.dom.style.setProperty("--
|
|
156
|
+
this.dom.style.setProperty("--blockeditor-pop-x", `${Math.min(a.left, b.left) - shellBox.left}px`);
|
|
157
|
+
this.dom.style.setProperty("--blockeditor-pop-y", `${Math.max(a.bottom, b.bottom) - shellBox.top + 6}px`);
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
update(view) {
|
|
@@ -224,7 +224,7 @@ export function linkPlugin() {
|
|
|
224
224
|
props: {
|
|
225
225
|
decorations(st) {
|
|
226
226
|
const r = linkKey.getState(st);
|
|
227
|
-
return r && r.from < r.to ? DecorationSet.create(st.doc, [Decoration.inline(r.from, r.to, { class: "
|
|
227
|
+
return r && r.from < r.to ? DecorationSet.create(st.doc, [Decoration.inline(r.from, r.to, { class: "blockeditor-link-pending" })]) : null;
|
|
228
228
|
},
|
|
229
229
|
handleKeyDown(view, event) {
|
|
230
230
|
const mod = event.metaKey || event.ctrlKey;
|
package/src/page/media.js
CHANGED
|
@@ -19,7 +19,7 @@ import { safeFileHref } from "./address.js";
|
|
|
19
19
|
const { Plugin, PluginKey } = state;
|
|
20
20
|
const N = schema.nodes;
|
|
21
21
|
|
|
22
|
-
export const mediaKey = new PluginKey("
|
|
22
|
+
export const mediaKey = new PluginKey("blockeditor-media");
|
|
23
23
|
export const EMBED_MAX = 1.5 * 1024 * 1024;
|
|
24
24
|
export const mediaRuntime = new WeakMap();
|
|
25
25
|
|
|
@@ -182,7 +182,7 @@ export function mediaPlugin({ upload, features = null }) {
|
|
|
182
182
|
input.type = "file";
|
|
183
183
|
input.multiple = true;
|
|
184
184
|
input.hidden = true;
|
|
185
|
-
input.className = "
|
|
185
|
+
input.className = "blockeditor-file-input";
|
|
186
186
|
view.dom.parentElement.append(input);
|
|
187
187
|
mediaRuntime.set(view, { upload, aborts: new Map(), input });
|
|
188
188
|
input.addEventListener("change", () => {
|
|
@@ -205,7 +205,7 @@ export function mediaPlugin({ upload, features = null }) {
|
|
|
205
205
|
});
|
|
206
206
|
input.addEventListener("cancel", () => view.dispatch(view.state.tr.setMeta(mediaKey, { picker: null })));
|
|
207
207
|
const onClick = (e) => {
|
|
208
|
-
const b = e.target.closest?.(".
|
|
208
|
+
const b = e.target.closest?.(".blockeditor-upload-btn");
|
|
209
209
|
if (!b) return;
|
|
210
210
|
e.preventDefault();
|
|
211
211
|
const part = mediaParts.get(view);
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// stylesheet of its own, and it takes no focus: the caret and the typed query stay in the
|
|
4
4
|
// document, and the active row is announced through the editor's aria-activedescendant as
|
|
5
5
|
// the slash menu does. A name is only ever text.
|
|
6
|
-
export const PICKER = "
|
|
7
|
-
export const OPTION = "
|
|
6
|
+
export const PICKER = "blockeditor-mention-picker";
|
|
7
|
+
export const OPTION = "blockeditor-menu-item";
|
|
8
8
|
const EMPTY = "No people to mention";
|
|
9
9
|
|
|
10
10
|
let count = 0;
|
|
@@ -28,9 +28,9 @@ export const filterPeople = (people, query) => {
|
|
|
28
28
|
// The shell takes the words a command shows, so a date command reuses the same listbox:
|
|
29
29
|
// same placement, same rows, same keyboard, and its own name for what it lists.
|
|
30
30
|
export function createMentionPicker({ document: doc = globalThis.document, onPick = () => {}, label = "Mention a person", empty = EMPTY } = {}) {
|
|
31
|
-
const id = `
|
|
31
|
+
const id = `blockeditor-mentions-${++count}`;
|
|
32
32
|
const el = doc.createElement("div");
|
|
33
|
-
el.className = `
|
|
33
|
+
el.className = `blockeditor-menu ${PICKER}`;
|
|
34
34
|
el.id = id;
|
|
35
35
|
el.setAttribute("role", "listbox");
|
|
36
36
|
el.setAttribute("aria-label", label);
|
|
@@ -41,7 +41,7 @@ export function createMentionPicker({ document: doc = globalThis.document, onPic
|
|
|
41
41
|
const draw = () => {
|
|
42
42
|
if (!people.length) {
|
|
43
43
|
const none = doc.createElement("div");
|
|
44
|
-
none.className = "
|
|
44
|
+
none.className = "blockeditor-menu-title";
|
|
45
45
|
none.textContent = empty;
|
|
46
46
|
el.replaceChildren(none);
|
|
47
47
|
return;
|
|
@@ -64,8 +64,8 @@ export function createMentionPicker({ document: doc = globalThis.document, onPic
|
|
|
64
64
|
// The caret the list hangs from, in the page's own placement variables: the same ones
|
|
65
65
|
// the block menu writes, so the existing menu stylesheet paints and lifts it.
|
|
66
66
|
const place = (at) => {
|
|
67
|
-
el.style.setProperty("--
|
|
68
|
-
el.style.setProperty("--
|
|
67
|
+
el.style.setProperty("--blockeditor-pop-x", `${at.x}px`);
|
|
68
|
+
el.style.setProperty("--blockeditor-pop-y", `${at.y}px`);
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
return {
|
package/src/page/merge.js
CHANGED
|
@@ -5,7 +5,7 @@ const same = (a, b) => canon(a) === canon(b);
|
|
|
5
5
|
|
|
6
6
|
function inlineOf(item, doc) {
|
|
7
7
|
const article = doc.createElement("article");
|
|
8
|
-
article.setAttribute("data-
|
|
8
|
+
article.setAttribute("data-blockeditor", "");
|
|
9
9
|
article.innerHTML = renderModel([{ id: item.id, t: "paragraph", c: item.c ?? "", ...(item.m ? { m: item.m } : {}) }], { clean: fragmentCleaner(doc) });
|
|
10
10
|
return article;
|
|
11
11
|
}
|
package/src/page/placeholder.js
CHANGED
|
@@ -14,7 +14,7 @@ function titlePlaceholder(doc) {
|
|
|
14
14
|
if (done) return;
|
|
15
15
|
if (node.type !== schema.nodes.heading || node.attrs.level !== 1 || (node.attrs.parent ?? null) !== null) return;
|
|
16
16
|
done = true;
|
|
17
|
-
if (!node.content.size) decoration = Decoration.node(offset, offset + node.nodeSize, { class: "
|
|
17
|
+
if (!node.content.size) decoration = Decoration.node(offset, offset + node.nodeSize, { class: "blockeditor-title-placeholder", "data-placeholder": TITLE_PLACEHOLDER });
|
|
18
18
|
});
|
|
19
19
|
return decoration;
|
|
20
20
|
}
|
|
@@ -26,7 +26,7 @@ function checkPlaceholders(doc) {
|
|
|
26
26
|
doc.forEach((node, offset) => {
|
|
27
27
|
if (node.type !== schema.nodes.list_item || node.attrs.kind !== "check") return;
|
|
28
28
|
if (node.content.size || node.attrs.checked) return;
|
|
29
|
-
decorations.push(Decoration.node(offset, offset + node.nodeSize, { class: "
|
|
29
|
+
decorations.push(Decoration.node(offset, offset + node.nodeSize, { class: "blockeditor-check-placeholder", "data-placeholder": CHECK_PLACEHOLDER }));
|
|
30
30
|
});
|
|
31
31
|
return decorations;
|
|
32
32
|
}
|
|
@@ -45,7 +45,7 @@ export function placeholderPlugin(text = PLACEHOLDER_TEXT) {
|
|
|
45
45
|
const node = $from.parent;
|
|
46
46
|
if (node.type === schema.nodes.paragraph && !node.content.size) {
|
|
47
47
|
const pos = $from.before(1);
|
|
48
|
-
decorations.push(Decoration.node(pos, pos + node.nodeSize, { class: "
|
|
48
|
+
decorations.push(Decoration.node(pos, pos + node.nodeSize, { class: "blockeditor-placeholder", "data-placeholder": text }));
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
}
|
package/src/page/projection.js
CHANGED
|
@@ -25,15 +25,15 @@ const KNOWN = new Set(CODES);
|
|
|
25
25
|
// semantic envelope: canonical JSON, base64url, in one attribute. The block
|
|
26
26
|
// envelope holds the block record, the marks envelope the descriptors of one
|
|
27
27
|
// run, and the visible text stays the readable fallback.
|
|
28
|
-
export const OPAQUE = "data-clay-
|
|
29
|
-
export const VALUE = "data-clay-
|
|
30
|
-
export const MARKS = "data-clay-
|
|
28
|
+
export const OPAQUE = "data-clay-blockeditor-opaque";
|
|
29
|
+
export const VALUE = "data-clay-blockeditor-value";
|
|
30
|
+
export const MARKS = "data-clay-blockeditor-marks";
|
|
31
31
|
// A person mention's span states its id plainly beside the envelope that carries it:
|
|
32
32
|
// the label is the text, and a reader without the editor shows a name, never a link.
|
|
33
|
-
export const MENTION = "data-
|
|
33
|
+
export const MENTION = "data-blockeditor-mention";
|
|
34
34
|
// A date mention reads as a `time` element: the text is the ISO date and `datetime`
|
|
35
35
|
// repeats it, so a reader without the editor shows the day and no zone or reminder.
|
|
36
|
-
export const DATE = "data-
|
|
36
|
+
export const DATE = "data-blockeditor-date";
|
|
37
37
|
const DAY = /^\d{4}-\d{2}-\d{2}$/;
|
|
38
38
|
const ENVELOPE = "1";
|
|
39
39
|
const STRUCTURAL = new Set(["id", "t", "parent", "c", "m"]);
|
|
@@ -60,7 +60,7 @@ export const DEFAULTS = {
|
|
|
60
60
|
};
|
|
61
61
|
const TEXT = new Set(["paragraph", "heading", "list_item", "callout", "quote", "code_block", "toggle"]);
|
|
62
62
|
export const TOC_LABEL = "Table of contents";
|
|
63
|
-
export const TOC_ANCHOR = "
|
|
63
|
+
export const TOC_ANCHOR = "blockeditor-block-";
|
|
64
64
|
export const blockAnchor = (id) => `${TOC_ANCHOR}${b64url(String(id ?? ""))}`;
|
|
65
65
|
const TOC_MAX_LEVEL = 3;
|
|
66
66
|
const tocLevel = (item) => (item.t === "heading"
|
|
@@ -530,9 +530,9 @@ export function renderInline(c, m, marksEnvelopes = true) {
|
|
|
530
530
|
}
|
|
531
531
|
|
|
532
532
|
const inlineOf = (item) => renderInline(item.c ?? "", item.m);
|
|
533
|
-
const titleHtml = (item) => `<header${attr("data-id", item.id)} data-
|
|
533
|
+
const titleHtml = (item) => `<header${attr("data-id", item.id)} data-blockeditor-heading="1"${extrasOfItem(item)}>${item.pageCoverSrc ? `<img data-blockeditor-cover${attr("src", item.pageCoverSrc)}${attr("alt", item.pageCoverAlt ?? "")} style="object-position:${item.pageCoverX ?? 50}% ${item.pageCoverY ?? 50}%">` : ""}${item.pageIcon ? `<span data-blockeditor-icon aria-hidden="true">${escText(item.pageIcon)}</span>` : ""}<h1>${inlineOf(item)}</h1></header>`;
|
|
534
534
|
const toolData = (item) => item.artifact || item.rev || (item.state && Object.keys(item.state).length)
|
|
535
|
-
? `<script type="application/json" data-tool>${canon({ artifact: item.artifact ?? null, rev: item.rev ?? null, state: item.state ?? {} }).replace(/</g, "\\u003c")}</script>`
|
|
535
|
+
? `<script type="application/json" clay="no-data" data-tool>${canon({ artifact: item.artifact ?? null, rev: item.rev ?? null, state: item.state ?? {} }).replace(/</g, "\\u003c")}</script>`
|
|
536
536
|
: "";
|
|
537
537
|
// A header names its column for every cell under it: the table id and the column
|
|
538
538
|
// id together, so a copied column keeps a name no other table shares.
|
|
@@ -547,7 +547,7 @@ function renderLeaf(item, clean, tables) {
|
|
|
547
547
|
switch (item.t) {
|
|
548
548
|
case "paragraph": return `<p${at}>${inlineOf(item)}</p>`;
|
|
549
549
|
case "heading": { const h = `h${item.level ?? 2}`; return `<${h}${at}>${inlineOf(item)}</${h}>`; }
|
|
550
|
-
case "callout": return `<aside${at} class="
|
|
550
|
+
case "callout": return `<aside${at} class="blockeditor-callout">${inlineOf(item)}</aside>`;
|
|
551
551
|
case "quote": return `<blockquote${at}>${inlineOf(item)}</blockquote>`;
|
|
552
552
|
case "code_block": return `<pre${at}${attr("data-lang", item.lang || null)}><code>${escText(item.c ?? "")}</code></pre>`;
|
|
553
553
|
case "divider": return `<hr${at}>`;
|
|
@@ -789,8 +789,8 @@ export function parseArticle(article) {
|
|
|
789
789
|
const onlyImage = tag === "P" && el.children.length === 1 && el.children[0].tagName === "IMG" && !el.textContent.trim();
|
|
790
790
|
if (tag === "P" && !onlyImage) return push(el, "paragraph", parent, { ...omitDefaults("paragraph", P), ...tf(el) });
|
|
791
791
|
if (/^H[1-6]$/.test(tag)) return push(el, "heading", parent, { ...omitDefaults("heading", { ...P, level: +tag[1] }), ...tf(el) });
|
|
792
|
-
if (tag === "HEADER" && el.getAttribute("data-
|
|
793
|
-
const icon = el.querySelector(":scope > [data-
|
|
792
|
+
if (tag === "HEADER" && el.getAttribute("data-blockeditor-heading") === ENVELOPE) {
|
|
793
|
+
const icon = el.querySelector(":scope > [data-blockeditor-icon]");
|
|
794
794
|
const cover = el.querySelector(":scope > img");
|
|
795
795
|
const [, x, y] = /object-position:\s*([-\d.]+)%\s+([-\d.]+)%/.exec(cover?.getAttribute("style") ?? "") ?? [];
|
|
796
796
|
const cover0 = cover ? { pageCoverSrc: safeSrc(cover.getAttribute("src")), pageCoverAlt: cover.getAttribute("alt") ?? "", pageCoverX: focal(x), pageCoverY: focal(y) } : {};
|
package/src/page/reader-patch.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// card id can never match an article block id. An id that appears twice is not
|
|
11
11
|
// reused at all: neither occurrence promises node identity.
|
|
12
12
|
|
|
13
|
-
const ARTICLE = "article[data-
|
|
13
|
+
const ARTICLE = "article[data-blockeditor]";
|
|
14
14
|
const TOOL = 'section[data-type="tool"][data-id]';
|
|
15
15
|
const CONTAINERS = new Set(["UL", "OL", "LI", "DETAILS"]);
|
|
16
16
|
const LISTS = new Set(["UL", "OL"]);
|
|
@@ -60,7 +60,7 @@ export function toolsOf(root) {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
export function toolStateOf(doc) {
|
|
63
|
-
const tag = doc.querySelector('script[type="application/json"][merge="
|
|
63
|
+
const tag = doc.querySelector('script[type="application/json"][merge="blockeditor.tools"]');
|
|
64
64
|
if (!tag) return {};
|
|
65
65
|
try { return JSON.parse(tag.textContent); } catch { return {}; }
|
|
66
66
|
}
|
package/src/page/recover.js
CHANGED
|
@@ -5,26 +5,26 @@ import { mountEditorUI } from "../ui/editor-ui.js";
|
|
|
5
5
|
export const NOTICE_TEXT = "Some text you typed was kept aside when its block moved or was removed.";
|
|
6
6
|
|
|
7
7
|
// The control and its panel sit in one shadow root inside the page shell, so the page's
|
|
8
|
-
// CSS cannot restyle them. The page's --
|
|
8
|
+
// CSS cannot restyle them. The page's --blockeditor-* tokens still reach them, and they keep
|
|
9
9
|
// the page's font and colour.
|
|
10
10
|
const STYLES = `
|
|
11
11
|
:host { font: inherit !important; color: inherit !important; }
|
|
12
|
-
.
|
|
13
|
-
.
|
|
14
|
-
.
|
|
15
|
-
.
|
|
16
|
-
.
|
|
17
|
-
.
|
|
18
|
-
.
|
|
19
|
-
.
|
|
20
|
-
.
|
|
21
|
-
.
|
|
22
|
-
.
|
|
23
|
-
.
|
|
12
|
+
.blockeditor-recover-root { display: contents; }
|
|
13
|
+
.blockeditor-recover { position: fixed; right: 16px; bottom: 16px; z-index: 20; min-height: 36px; padding: 0 14px; font: inherit; font-size: 14px; color: var(--blockeditor-ink); background: var(--blockeditor-pop-bg); border: 1px solid var(--blockeditor-chrome-line-rest); border-radius: 999px; cursor: pointer; }
|
|
14
|
+
.blockeditor-recover[hidden], .blockeditor-recover-panel[hidden] { display: none; }
|
|
15
|
+
.blockeditor-recover-panel { position: fixed; right: 16px; bottom: 64px; z-index: 21; width: min(380px, calc(100vw - 32px)); max-height: 60vh; overflow-y: auto; color: var(--blockeditor-ink); background: var(--blockeditor-pop-bg); border: 1px solid var(--blockeditor-chrome-line-rest); border-radius: var(--blockeditor-chrome-radius); padding: 8px; box-sizing: border-box; }
|
|
16
|
+
.blockeditor-recover-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 4px 6px 8px; font-weight: 600; }
|
|
17
|
+
.blockeditor-recover-note { margin: 0 6px 8px; font-size: 13px; opacity: .72; }
|
|
18
|
+
.blockeditor-recover-row { display: grid; grid-template-columns: 1fr auto; gap: 4px 12px; align-items: center; min-height: 44px; padding: 8px 6px; border-top: 1px solid var(--blockeditor-chrome-line-rest); }
|
|
19
|
+
.blockeditor-recover-row.is-target { outline: 2px solid var(--blockeditor-accent, currentColor); outline-offset: -2px; }
|
|
20
|
+
.blockeditor-recover-meta { grid-column: 1; font-size: 12px; opacity: .72; }
|
|
21
|
+
.blockeditor-recover-text { grid-column: 1; overflow-wrap: anywhere; }
|
|
22
|
+
.blockeditor-recover-text mark { background: var(--blockeditor-mark-bg, rgba(255, 214, 102, .45)); color: inherit; border-radius: 2px; }
|
|
23
|
+
.blockeditor-recover-row button, .blockeditor-recover-head button { grid-column: 2; grid-row: 1 / span 2; min-height: 36px; padding: 0 12px; font: inherit; font-size: 14px; color: inherit; background: transparent; border: 1px solid var(--blockeditor-chrome-line-rest); border-radius: var(--blockeditor-chrome-radius); cursor: pointer; }
|
|
24
24
|
@media (max-width: 560px) {
|
|
25
|
-
.
|
|
26
|
-
.
|
|
27
|
-
.
|
|
25
|
+
.blockeditor-recover { top: 12px; bottom: auto; min-height: 44px; }
|
|
26
|
+
.blockeditor-recover-panel { left: 0; right: 0; bottom: 0; width: 100%; max-height: 70vh; border-radius: var(--blockeditor-chrome-radius) var(--blockeditor-chrome-radius) 0 0; }
|
|
27
|
+
.blockeditor-recover-row button, .blockeditor-recover-head button { min-height: 44px; }
|
|
28
28
|
}
|
|
29
29
|
`;
|
|
30
30
|
|
|
@@ -40,7 +40,7 @@ const el = (doc, tag, className, attrs = {}) => {
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
function previewOf(doc, record) {
|
|
43
|
-
const out = el(doc, "div", "
|
|
43
|
+
const out = el(doc, "div", "blockeditor-recover-text");
|
|
44
44
|
let used = 0;
|
|
45
45
|
for (const block of record.blocks) {
|
|
46
46
|
for (const run of block.runs) {
|
|
@@ -73,13 +73,13 @@ export function focusBlock(view, id) {
|
|
|
73
73
|
export function createRecoverList({ binding, mount, ownTokens = [], onRestored = () => {}, onStale = () => {} }) {
|
|
74
74
|
const doc = mount.ownerDocument;
|
|
75
75
|
const own = new Set(ownTokens.filter(Boolean));
|
|
76
|
-
const button = el(doc, "button", "
|
|
77
|
-
const panel = el(doc, "div", "
|
|
76
|
+
const button = el(doc, "button", "blockeditor-recover", { type: "button", "aria-haspopup": "dialog", "aria-expanded": "false" });
|
|
77
|
+
const panel = el(doc, "div", "blockeditor-recover-panel", { role: "dialog", "aria-label": "Recover changes" });
|
|
78
78
|
button.hidden = true;
|
|
79
79
|
panel.hidden = true;
|
|
80
|
-
const content = el(doc, "div", "
|
|
80
|
+
const content = el(doc, "div", "blockeditor-recover-root");
|
|
81
81
|
content.append(button, panel);
|
|
82
|
-
const ui = mountEditorUI({ name: "
|
|
82
|
+
const ui = mountEditorUI({ name: "blockeditor-recover", content, css: [STYLES], parent: mount });
|
|
83
83
|
|
|
84
84
|
let snapshot = { recoverable: [], notices: [] };
|
|
85
85
|
let target = null;
|
|
@@ -112,19 +112,19 @@ export function createRecoverList({ binding, mount, ownTokens = [], onRestored =
|
|
|
112
112
|
|
|
113
113
|
const draw = () => {
|
|
114
114
|
panel.replaceChildren();
|
|
115
|
-
const head = el(doc, "div", "
|
|
115
|
+
const head = el(doc, "div", "blockeditor-recover-head");
|
|
116
116
|
head.append(doc.createTextNode("Recover changes"));
|
|
117
117
|
const done = el(doc, "button", "", { type: "button" });
|
|
118
118
|
done.textContent = "Close";
|
|
119
119
|
done.addEventListener("click", () => { close(); button.focus(); });
|
|
120
120
|
head.append(done);
|
|
121
|
-
const note = el(doc, "p", "
|
|
121
|
+
const note = el(doc, "p", "blockeditor-recover-note");
|
|
122
122
|
note.textContent = "Text typed while its block was moved or removed. Restore puts it back as a new block.";
|
|
123
123
|
panel.append(head, note);
|
|
124
124
|
for (const record of snapshot.recoverable) {
|
|
125
|
-
const row = el(doc, "div", "
|
|
125
|
+
const row = el(doc, "div", "blockeditor-recover-row", { "data-source": record.source });
|
|
126
126
|
if (record.source === target) row.classList.add("is-target");
|
|
127
|
-
const meta = el(doc, "div", "
|
|
127
|
+
const meta = el(doc, "div", "blockeditor-recover-meta");
|
|
128
128
|
meta.textContent = `${TYPE_LABELS[record.type] ?? "Paragraph"} · ${who(authorsOf(record))}`;
|
|
129
129
|
const action = el(doc, "button", "", { type: "button" });
|
|
130
130
|
action.textContent = "Restore";
|
|
@@ -140,7 +140,7 @@ export function createRecoverList({ binding, mount, ownTokens = [], onRestored =
|
|
|
140
140
|
panel.hidden = false;
|
|
141
141
|
button.setAttribute("aria-expanded", "true");
|
|
142
142
|
draw();
|
|
143
|
-
const rows = [...panel.querySelectorAll(".
|
|
143
|
+
const rows = [...panel.querySelectorAll(".blockeditor-recover-row")];
|
|
144
144
|
const focus = (rows.find((row) => row.dataset.source === source) ?? rows[0])?.querySelector("button");
|
|
145
145
|
focus?.focus();
|
|
146
146
|
};
|