@panphora/clayjs 1.16.0 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/all.js +1 -1
- package/dist/clay-dom.js +1 -1
- package/dist/clay-events.js +1 -1
- package/dist/clay-internals.js +1 -1
- package/dist/clay-options.js +1 -1
- package/dist/clay-router.js +1 -1
- package/dist/clay-ui.js +1 -1
- package/dist/clay-utils.js +1 -1
- package/dist/clay.js +1 -1
- package/dist/clay.standalone.js +72519 -59839
- package/dist/m/attrs/refetch-on-save-ZUE7PSCI.js +1 -0
- package/dist/m/attrs/save-freeze-LWGF6XUN.js +1 -0
- package/dist/m/c-2GRUM77Q.js +30 -0
- package/dist/m/c-2KIEGNC4.js +1 -0
- package/dist/m/{c-5R4PTRG2.js → c-2KL3BD52.js} +1 -1
- package/dist/m/c-2YYDMLNZ.js +1 -0
- package/dist/m/c-2ZZBC45O.js +1 -0
- package/dist/m/c-372N6H3B.js +1 -0
- package/dist/m/{c-4WKFKEKF.js → c-3G2DGZUP.js} +1 -1
- package/dist/m/c-3LDGIBMN.js +1 -0
- package/dist/m/c-3O7OBDCM.js +1 -0
- package/dist/m/c-4ASQPRQL.js +1 -0
- package/dist/m/c-4TXNLX4K.js +6 -0
- package/dist/m/c-4YU3BR4D.js +6 -0
- package/dist/m/c-5734MF2P.js +1 -0
- package/dist/m/c-57XDY6HC.js +1 -0
- package/dist/m/{c-VFX45IZQ.js → c-5B4YBZXC.js} +1 -1
- package/dist/m/c-5ONTYIUI.js +1 -0
- package/dist/m/c-5OOVFCJM.js +1 -0
- package/dist/m/c-5T6NZHNM.js +1 -0
- package/dist/m/{c-YDH7Q3NY.js → c-5ZQV7KC4.js} +1 -1
- package/dist/m/{c-Z36J63PP.js → c-6DB2OLRJ.js} +1 -1
- package/dist/m/c-6DNRCPNM.js +1 -0
- package/dist/m/c-6UGWFMQC.js +2 -0
- package/dist/m/c-7K4SCQB7.js +1 -0
- package/dist/m/c-7MG5RU63.js +1 -0
- package/dist/m/c-7PRJCA3E.js +1 -0
- package/dist/m/c-A6L3FMUS.js +1 -0
- package/dist/m/c-AMU3BPPR.js +4 -0
- package/dist/m/c-AMYEFA2E.js +1 -0
- package/dist/m/c-AQYCG7QW.js +1 -0
- package/dist/m/c-ATKAOH23.js +1 -0
- package/dist/m/c-B3JM5ZXC.js +1 -0
- package/dist/m/c-B5CS55WR.js +1 -0
- package/dist/m/c-B5UJQT7W.js +1 -0
- package/dist/m/c-B7J4K2AE.js +3 -0
- package/dist/m/c-BHZYSHW4.js +1 -0
- package/dist/m/c-BIJALSRD.js +1 -0
- package/dist/m/c-BJ7YQ5QZ.js +1 -0
- package/dist/m/c-BPF2NSPV.js +1 -0
- package/dist/m/{c-KIPQJX4B.js → c-BRLCTNMC.js} +1 -1
- package/dist/m/c-BUAYFEV5.js +1 -0
- package/dist/m/c-C6IPRG34.js +1 -0
- package/dist/m/{c-2JL6E75N.js → c-CAS3NND4.js} +1 -1
- package/dist/m/{c-4DRMS4QG.js → c-CCQ25GFY.js} +1 -1
- package/dist/m/c-CJFDLD43.js +1 -0
- package/dist/m/c-COPTL5WB.js +1 -0
- package/dist/m/c-D3E4WJ4M.js +166 -0
- package/dist/m/c-D5IKEKXW.js +7 -0
- package/dist/m/c-DHBRA6DL.js +1 -0
- package/dist/m/c-DKLS74XB.js +72 -0
- package/dist/m/c-DVYGFTSK.js +3 -0
- package/dist/m/c-E3ZXARWA.js +1 -0
- package/dist/m/c-EK63G3CG.js +1 -0
- package/dist/m/c-ERQSNR6K.js +13 -0
- package/dist/m/c-EVYAISP3.js +1 -0
- package/dist/m/c-EXKHPOVC.js +3 -0
- package/dist/m/{c-7VGZ7RU5.js → c-FWKHM4E7.js} +1 -1
- package/dist/m/{c-4Q2XTQ2N.js → c-GBKB5WDL.js} +1 -1
- package/dist/m/c-GNDL3TKB.js +1 -0
- package/dist/m/c-GRWMD6O5.js +1 -0
- package/dist/m/c-GRXHHFPO.js +1 -0
- package/dist/m/{c-OYTFP5QN.js → c-GY422N3Q.js} +1 -1
- package/dist/m/c-HAWFNBYG.js +1 -0
- package/dist/m/c-HG2C77BM.js +4 -0
- package/dist/m/c-HHGJBU4D.js +1 -0
- package/dist/m/c-HMV6P4RX.js +1 -0
- package/dist/m/c-HMYWIHFG.js +1 -0
- package/dist/m/c-HT2DKBV2.js +1 -0
- package/dist/m/c-I2SCCUEW.js +1 -0
- package/dist/m/{c-HRDCD3WN.js → c-ICJYHABF.js} +2 -2
- package/dist/m/c-IMZCWYHR.js +7 -0
- package/dist/m/c-IVMD3FEM.js +1 -0
- package/dist/m/c-IVTRVENZ.js +1 -0
- package/dist/m/c-IW6GGOU2.js +1 -0
- package/dist/m/c-JKZJIUIP.js +1 -0
- package/dist/m/{c-NZMNXVF6.js → c-JNLX3RJB.js} +1 -1
- package/dist/m/c-JRKY44DK.js +1 -0
- package/dist/m/c-K3ADYNLU.js +1 -0
- package/dist/m/c-KBS3UV6B.js +1 -0
- package/dist/m/c-KGHVFRR3.js +1 -0
- package/dist/m/c-KJJPV77R.js +1 -0
- package/dist/m/{c-CZUSOB7V.js → c-KNPDOMDY.js} +1 -1
- package/dist/m/{c-5Y6TNX5W.js → c-KP64LT2A.js} +2 -2
- package/dist/m/c-KQ7E3PYY.js +1 -0
- package/dist/m/c-L3F5ZLIV.js +1 -0
- package/dist/m/{c-LR4CGEPT.js → c-L42OLXWM.js} +3 -2
- package/dist/m/c-L5VFATT6.js +1 -0
- package/dist/m/c-L7JL5TL3.js +3 -0
- package/dist/m/c-LKSL4AUJ.js +1 -0
- package/dist/m/c-M6FNQCTQ.js +1 -0
- package/dist/m/c-MCOOHCSG.js +1 -0
- package/dist/m/c-MHI3GYKF.js +1 -0
- package/dist/m/c-MWXFLW4J.js +1 -0
- package/dist/m/c-NEL7HQW3.js +1 -0
- package/dist/m/c-NQJRVJ56.js +1 -0
- package/dist/m/c-NWX3MFT4.js +1 -0
- package/dist/m/{c-HPURYVZS.js → c-OJYM642Q.js} +1 -1
- package/dist/m/c-OKXI52N7.js +1 -0
- package/dist/m/{c-MMUIUUZG.js → c-OPLUZR3A.js} +1 -1
- package/dist/m/{c-J7CA54IP.js → c-OTMKN2OO.js} +1 -1
- package/dist/m/{c-LTGMXXKO.js → c-OYRZ7XG2.js} +1 -1
- package/dist/m/c-P3OFYUMA.js +1 -0
- package/dist/m/c-PLN76GF3.js +6 -0
- package/dist/m/c-PLP4JKFC.js +1 -0
- package/dist/m/c-Q26MME6N.js +1 -0
- package/dist/m/{c-S7H2DRCB.js → c-Q3XOWZEV.js} +1 -1
- package/dist/m/{c-SWRJFCNN.js → c-QIKT6SKM.js} +1 -1
- package/dist/m/c-QIXT3Q7C.js +28 -0
- package/dist/m/c-QO4HNGCQ.js +1 -0
- package/dist/m/c-R27DWQKX.js +1 -0
- package/dist/m/{c-HVYXIS72.js → c-R2XUODVY.js} +1 -1
- package/dist/m/{c-QNKREOL6.js → c-R7LBFMF5.js} +1 -1
- package/dist/m/c-RND3G2S2.js +1 -0
- package/dist/m/c-S2U6NJU4.js +1 -0
- package/dist/m/c-SPZPGD3R.js +1 -0
- package/dist/m/c-SW4YEG2D.js +8 -0
- package/dist/m/c-SZGYW5HT.js +1 -0
- package/dist/m/c-T637T7SN.js +1 -0
- package/dist/m/c-TJAXGIRV.js +1 -0
- package/dist/m/{c-KKWLDOPM.js → c-TNEM3RNM.js} +1 -1
- package/dist/m/c-TTB5EK4S.js +32 -0
- package/dist/m/c-U7SHNWDH.js +1 -0
- package/dist/m/c-UDHIVLYH.js +20 -0
- package/dist/m/{c-BBVGTQG7.js → c-UGNV5MFB.js} +1 -1
- package/dist/m/{c-TQZ2JYHD.js → c-UORXLSD3.js} +1 -1
- package/dist/m/c-UPD33ZPE.js +1 -0
- package/dist/m/c-URSMSFCB.js +1 -0
- package/dist/m/c-UY4QX42B.js +1 -0
- package/dist/m/c-V44KWI2L.js +4 -0
- package/dist/m/c-VG5XIN4T.js +1 -0
- package/dist/m/c-VILENZTD.js +1 -0
- package/dist/m/{c-33HUYEDI.js → c-VJYEVRYK.js} +1 -1
- package/dist/m/c-VR2BJ4AN.js +1 -0
- package/dist/m/c-W4JCVLAB.js +1 -0
- package/dist/m/c-W6DQSHXI.js +135 -0
- package/dist/m/c-WBGWGOM7.js +1 -0
- package/dist/m/{c-4L3BTFRK.js → c-WCXLG3MV.js} +1 -1
- package/dist/m/c-WGW764WX.js +1 -0
- package/dist/m/c-WMRJKQ2V.js +5 -0
- package/dist/m/c-WNTYKCDG.js +1 -0
- package/dist/m/c-WQWIRWO3.js +72 -0
- package/dist/m/c-X5LNHET5.js +1 -0
- package/dist/m/c-X5TSXZYJ.js +2 -0
- package/dist/m/c-XGH4GS2T.js +1 -0
- package/dist/m/c-Y6F2FORL.js +1 -0
- package/dist/m/c-YBKHUAK7.js +10 -0
- package/dist/m/c-YBSS55KU.js +20 -0
- package/dist/m/c-YCLU4UNT.js +2 -0
- package/dist/m/c-YVZ2L7CE.js +1 -0
- package/dist/m/c-ZK4GIZH2.js +1 -0
- package/dist/m/c-ZRXJD4G6.js +1 -0
- package/dist/m/c-ZWBI4HYK.js +1 -0
- package/dist/m/{c-HT33EQRN.js → c-ZWIOJGMT.js} +1 -1
- package/dist/m/core/admin-attrs-YY7T5FGU.js +1 -0
- package/dist/m/core/autosave-S6OMNDCK.js +1 -0
- package/dist/m/core/conflict-notice-IWHMHH43.js +1 -0
- package/dist/m/core/host-permission-6EVJGNPL.js +1 -0
- package/dist/m/core/is-edit-mode-GCX6767E.js +1 -0
- package/dist/m/core/{persist-HKHA66IY.js → persist-UKXV5KLA.js} +1 -1
- package/dist/m/core/recovery-DRFZRJED.js +1 -0
- package/dist/m/core/save-LYY7K6U7.js +1 -0
- package/dist/m/core/save-core-MKRPSEEO.js +1 -0
- package/dist/m/core/snapshot-NU3YM6GR.js +1 -0
- package/dist/m/core/unsaved-warning-7QTKEN7Z.js +1 -0
- package/dist/m/events/index-RN2JNGBV.js +1 -0
- package/dist/m/internals/index-TGLQINN3.js +1 -0
- package/dist/m/lib/cache-bust-MUMFXZK6.js +1 -0
- package/dist/m/loader-3BBNZZGM.js +1 -0
- package/dist/m/manifest-F449FF98.js +1 -0
- package/dist/m/manifest-edit-4396A009.js +1 -0
- package/dist/m/manifest.json +2509 -1474
- package/dist/m/options/options-EJMS3K24.js +1 -0
- package/dist/m/page/editor-6LRB3GE4.js +304 -0
- package/dist/m/plugins/ai-edit-UTV7YO2I.js +6 -0
- package/dist/m/plugins/{cms-HP3LSTPN.js → cms-LRAOZHT7.js} +9 -9
- package/dist/m/plugins/demo-OYO5GCAO.js +1 -0
- package/dist/m/plugins/{derive-UAAA4V4S.js → derive-FRE5JJQE.js} +1 -1
- package/dist/m/plugins/indicator-4VDXWYTD.js +1 -0
- package/dist/m/plugins/live-AD4H6XSL.js +1 -0
- package/dist/m/plugins/menu-M5WW7DBF.js +1 -0
- package/dist/m/plugins/page-MD3T2ZX3.js +2 -0
- package/dist/m/plugins/page-view-PAWVZNFY.js +1 -0
- package/dist/m/plugins/people-JCHVPF7P.js +1 -0
- package/dist/m/plugins/quickcrop-BQ5YYFCH.js +26 -0
- package/dist/m/plugins/{richclay-RC3L2F6X.js → richclay-KLGETK77.js} +2 -2
- package/dist/m/plugins/sortable-4S6SQC3D.js +1 -0
- package/dist/m/plugins/source-TJXOIOYY.js +1 -0
- package/dist/m/plugins/undo-NLPGCJQY.js +1 -0
- package/dist/m/plugins/{unsent-HJFLQJ2O.js → unsent-OA4RGBUT.js} +1 -1
- package/dist/m/plugins/upgrade-HSUNDNJD.js +1 -0
- package/dist/m/plugins/upload-NHGJXZK2.js +1 -0
- package/dist/m/plugins/visitor-drafts-BW43DGY3.js +20 -0
- package/dist/m/plugins/visitor-drafts-owner-7ODQG7JX.js +1 -0
- package/dist/m/plugins/wire-VBWXEXU2.js +1 -0
- package/dist/m/reader-core-4W2KYEWQ.js +77 -0
- package/dist/m/route/route-62CHXL5B.js +1 -0
- package/dist/m/sync/live-sync-MO5DH33W.js +1 -0
- package/dist/m/ui/index-IVWN2QC4.js +1 -0
- package/dist/m/vendor/sap-core.vendor-RN4ZVY4X.js +6 -0
- package/dist/offline-manifest.json +1560 -889
- package/dist/page/themes/light-1.css +33 -8
- package/dist/server/core.cjs +1554 -311
- package/dist/server/offline-runtime.cjs +63 -63
- package/dist/server/offline-runtime.mjs +63 -63
- package/dist/server/page-compaction-worker.cjs +3710 -0
- package/dist/server/rooms.mjs +5 -0
- package/docs/guide.md +653 -101
- package/entries/sap.js +5 -5
- package/package.json +1 -1
- package/src/core/admin-contenteditable.js +5 -2
- package/src/core/admin-inputs.js +1 -0
- package/src/core/admin-onclick.js +2 -1
- package/src/core/boot-phase.js +2 -1
- package/src/core/conflict-download.js +3 -29
- package/src/core/conflict-notice-ui.js +4 -7
- package/src/core/download.js +32 -0
- package/src/core/host-meta.js +56 -0
- package/src/core/is-edit-mode.js +17 -1
- package/src/core/mode-key.js +125 -19
- package/src/core/mode-support.js +5 -0
- package/src/core/mode-transition.js +20 -6
- package/src/core/preserve-authored.js +4 -4
- package/src/core/recovery.js +121 -33
- package/src/core/save-accepted.js +33 -0
- package/src/core/save-core.js +111 -32
- package/src/core/save-job.js +108 -0
- package/src/core/save-prepare.js +53 -0
- package/src/core/save-size-notice.js +3 -1
- package/src/core/save-slices.js +15 -0
- package/src/core/save.js +557 -127
- package/src/core/serialize-steps.js +109 -0
- package/src/core/snapshot.js +209 -40
- package/src/core/source-map.js +83 -38
- package/src/core/stale-host-notice.js +1 -0
- package/src/core/upgrade-run.js +59 -8
- package/src/dom/active-element.js +5 -0
- package/src/lib/assets.js +1 -0
- package/src/lib/autosave-scheduler.js +3 -4
- package/src/lib/slice.js +65 -0
- package/src/lib/uimotion.js +774 -0
- package/src/lib/unsaved-state.js +2 -2
- package/src/live/fast-lane.js +10 -3
- package/src/live/local-lane.js +202 -11
- package/src/live/ops.js +16 -0
- package/src/live/page-compaction.js +162 -0
- package/src/live/server-lane.js +1 -0
- package/src/live/store.js +11 -3
- package/src/loader-logic.js +3 -1
- package/src/loader.js +14 -4
- package/src/page/adopt-boot.js +2 -1
- package/src/page/awareness.js +33 -2
- package/src/page/blocks.js +122 -27
- package/src/page/board-views.js +2 -16
- package/src/page/boot-pack.js +1 -1
- package/src/page/chart-tables.js +29 -0
- package/src/page/chart.js +411 -72
- package/src/page/checklist.js +10 -135
- package/src/page/checkpoint-proof.js +295 -0
- package/src/page/chrome.js +257 -40
- package/src/page/clipboard-shape.js +126 -0
- package/src/page/document-title-dom.js +12 -0
- package/src/page/document-title-runtime.js +15 -1
- package/src/page/document-title.js +4 -1
- package/src/page/drag.js +33 -3
- package/src/page/editor.js +207 -31
- package/src/page/emoji-data.js +162 -0
- package/src/page/export-assets.js +357 -0
- package/src/page/export-html.js +209 -0
- package/src/page/export-markdown.js +361 -0
- package/src/page/features/board.js +12 -3
- package/src/page/features/chart.js +11 -0
- package/src/page/features/checklist.js +428 -0
- package/src/page/features/dates.js +180 -0
- package/src/page/features/emoji.js +187 -0
- package/src/page/features/export-html.js +189 -0
- package/src/page/features/export-markdown.js +169 -0
- package/src/page/features/import-markdown.js +349 -0
- package/src/page/features/media.js +61 -5
- package/src/page/features/mentions.js +188 -0
- package/src/page/features/registry.js +24 -1
- package/src/page/features/table.js +375 -85
- package/src/page/features/title-cover.js +331 -0
- package/src/page/features/title-icon.js +213 -0
- package/src/page/features/toc.js +87 -0
- package/src/page/format-command.js +33 -0
- package/src/page/format-gate.js +68 -18
- package/src/page/format-host.js +71 -0
- package/src/page/format-native-commands.js +158 -0
- package/src/page/format-native.js +42 -0
- package/src/page/image-actions.js +64 -0
- package/src/page/import-markdown.js +262 -0
- package/src/page/inline.js +32 -8
- package/src/page/items.js +141 -11
- package/src/page/markdown.js +30 -2
- package/src/page/media.js +35 -119
- package/src/page/mention-picker.js +99 -0
- package/src/page/merge.js +1 -1
- package/src/page/placeholder.js +14 -1
- package/src/page/projection.js +156 -25
- package/src/page/recover.js +10 -12
- package/src/page/recovery-ui.js +464 -0
- package/src/page/rich/chart.js +63 -7
- package/src/page/save-projection.js +67 -0
- package/src/page/save-states.js +14 -4
- package/src/page/schema.js +52 -3
- package/src/page/table-paste.js +3 -1
- package/src/page/table-style.js +4 -4
- package/src/page/table.js +44 -2
- package/src/page/themes/content.css +25 -1
- package/src/page/themes/light-1.css +33 -8
- package/src/page/themes/light-1.source.css +8 -7
- package/src/page/toc-link.js +31 -0
- package/src/page/toc.js +5 -0
- package/src/page/view-hooks.js +58 -0
- package/src/page/view.js +13 -0
- package/src/page/ybind/binding.js +116 -6
- package/src/page/ybind/bridge.js +187 -20
- package/src/page/ybind/containment.js +162 -0
- package/src/page/ybind/doc.js +17 -9
- package/src/page/ybind/file-debt.js +63 -0
- package/src/page/ybind/layout.js +7 -2
- package/src/page/ybind/marks.js +2 -1
- package/src/page/ybind/moves.js +5 -4
- package/src/page/ybind/origins.js +106 -4
- package/src/page/ybind/parts.js +8 -1
- package/src/page/ybind/provider.js +125 -18
- package/src/page/ybind/recovery-proof.js +32 -9
- package/src/page/ybind/recovery-replay.js +905 -4
- package/src/page/ybind/recovery.js +174 -45
- package/src/page/ybind/table.js +67 -11
- package/src/page/ybind/walk-delta.js +258 -0
- package/src/page/ybind/walk.js +54 -29
- package/src/page/ybind/writer.js +1 -1
- package/src/plugins/ai-edit.js +13 -9
- package/src/plugins/indicator-chip.js +91 -0
- package/src/plugins/indicator.js +13 -80
- package/src/plugins/live.js +126 -15
- package/src/plugins/menu/actions.js +196 -0
- package/src/plugins/menu/people.js +279 -0
- package/src/plugins/menu/placement.js +121 -0
- package/src/plugins/menu/preferences.js +9 -0
- package/src/plugins/menu/seo.js +316 -397
- package/src/plugins/menu/style.js +171 -0
- package/src/plugins/menu/variants.js +296 -0
- package/src/plugins/menu.js +186 -183
- package/src/plugins/page-view.js +3 -2
- package/src/plugins/page.js +362 -43
- package/src/plugins/sortable.js +8 -1
- package/src/plugins/source.js +6 -0
- package/src/plugins/upgrade.js +51 -17
- package/src/plugins/upload-ui.js +12 -17
- package/src/plugins/visitor-drafts/bottom-ui.js +12 -4
- package/src/plugins/visitor-drafts/intro-style.js +7 -2
- package/src/plugins/visitor-drafts/intro.js +7 -4
- package/src/plugins/visitor-drafts/owner-chip.js +8 -12
- package/src/plugins/visitor-drafts/prompt.js +11 -9
- package/src/plugins/visitor-drafts/source.js +4 -3
- package/src/plugins/visitor-drafts/store.js +138 -9
- package/src/plugins/visitor-drafts/ui-memory.js +2 -2
- package/src/plugins/visitor-drafts-owner.js +4 -6
- package/src/plugins/visitor-drafts.js +5 -3
- package/src/recovery/store.js +1 -1
- package/src/route/route.js +4 -0
- package/src/server/checkpoint/index.js +2 -2
- package/src/server/rooms/index.js +5 -1
- package/src/server/rooms/live-data-rooms.js +302 -50
- package/src/server/rooms/page-compaction-worker.js +12 -0
- package/src/server/rooms/page-compactor.js +92 -0
- package/src/server/rooms/page-room-conformance.js +461 -0
- package/src/source/parse-steps.js +94 -0
- package/src/source/session.js +233 -57
- package/src/sync/editing-sender.js +12 -0
- package/src/sync/live-sync-edit.js +22 -2
- package/src/sync/live-sync.js +150 -23
- package/src/sync/page-relay.js +52 -0
- package/src/sync/presence-store.js +44 -4
- package/src/sync/presence.js +6 -3
- package/src/sync/saved-stream.js +28 -14
- package/src/ui/bevel-controls.js +1 -0
- package/src/ui/bevel-dialog.js +5 -2
- package/src/ui/editor-ui.js +77 -0
- package/src/ui/page-colour.js +281 -0
- package/src/ui/toast.js +16 -7
- package/src/vendor/hyper-html-api-upgrade.vendor.js +2 -2
- package/src/vendor/hyper-undo.vendor.js +1 -1
- package/src/vendor/hypercms.vendor.js +9 -9
- package/src/vendor/parse5.vendor.js +2 -2
- package/src/vendor/sap-core.vendor.js +5 -5
- package/dist/m/attrs/refetch-on-save-NWPPXOCZ.js +0 -1
- package/dist/m/attrs/save-freeze-FUP4Q4X3.js +0 -1
- package/dist/m/c-2M73252O.js +0 -1
- package/dist/m/c-2SPVQSHC.js +0 -1
- package/dist/m/c-35NBGMZB.js +0 -1
- package/dist/m/c-3IQRECYS.js +0 -1
- package/dist/m/c-4B6H4G5V.js +0 -1
- package/dist/m/c-4FFHZM32.js +0 -1
- package/dist/m/c-4YSCRICO.js +0 -1
- package/dist/m/c-54RCDCBU.js +0 -1
- package/dist/m/c-5M4YEKCX.js +0 -4
- package/dist/m/c-5V3MOVJT.js +0 -1
- package/dist/m/c-66O32MV3.js +0 -28
- package/dist/m/c-6HMB24EV.js +0 -1
- package/dist/m/c-7O6AFR65.js +0 -1
- package/dist/m/c-ANQTJ3B5.js +0 -2
- package/dist/m/c-AYVOREBE.js +0 -1
- package/dist/m/c-B2ZXPOS3.js +0 -3
- package/dist/m/c-BMIZKMPV.js +0 -1
- package/dist/m/c-BTDI4Y23.js +0 -1
- package/dist/m/c-CJZSLMVQ.js +0 -1
- package/dist/m/c-DBE6ORSI.js +0 -1
- package/dist/m/c-EDHUR4MX.js +0 -1
- package/dist/m/c-EY6UOM54.js +0 -1
- package/dist/m/c-F3CKJTJS.js +0 -1
- package/dist/m/c-F7Y6FLPY.js +0 -1
- package/dist/m/c-FA4DZVTC.js +0 -1
- package/dist/m/c-G2BUZITR.js +0 -1
- package/dist/m/c-GB3JTV6E.js +0 -1
- package/dist/m/c-GBGWXTX4.js +0 -1
- package/dist/m/c-GHBCCVG4.js +0 -1
- package/dist/m/c-GJAEGGXY.js +0 -1
- package/dist/m/c-GOWBDM6J.js +0 -1
- package/dist/m/c-IB52R237.js +0 -1
- package/dist/m/c-IKWNE4R4.js +0 -1
- package/dist/m/c-IU3IYEU6.js +0 -1
- package/dist/m/c-IZ2EBRAJ.js +0 -1
- package/dist/m/c-KR4UW4KW.js +0 -1
- package/dist/m/c-KY3VJGUA.js +0 -8
- package/dist/m/c-LFPHCXY3.js +0 -1
- package/dist/m/c-LRPUO2MX.js +0 -1
- package/dist/m/c-LXENEBV7.js +0 -1
- package/dist/m/c-NMJRXKPC.js +0 -8
- package/dist/m/c-OIBUTDXI.js +0 -1
- package/dist/m/c-PPOSCAQD.js +0 -1
- package/dist/m/c-QIX5BJYN.js +0 -1
- package/dist/m/c-QQHEX6HA.js +0 -1
- package/dist/m/c-R7RMANJI.js +0 -9
- package/dist/m/c-RI4NT75Y.js +0 -1
- package/dist/m/c-RM7J7BV2.js +0 -1
- package/dist/m/c-RUJKSUQW.js +0 -1
- package/dist/m/c-SGCCC4FW.js +0 -25
- package/dist/m/c-T4VO4OCB.js +0 -1
- package/dist/m/c-TQEMVJCS.js +0 -1
- package/dist/m/c-TR6RMDQ7.js +0 -3
- package/dist/m/c-UKHTLWUW.js +0 -1
- package/dist/m/c-UNN7LWCT.js +0 -1
- package/dist/m/c-UXBMRDZB.js +0 -235
- package/dist/m/c-V7PZZRG7.js +0 -1
- package/dist/m/c-VL52ADDR.js +0 -1
- package/dist/m/c-WNYBLIOZ.js +0 -1
- package/dist/m/c-WWDBYXLK.js +0 -1
- package/dist/m/c-XNNW2CWK.js +0 -1
- package/dist/m/c-Y6USGTS5.js +0 -5
- package/dist/m/c-YG2NJYS6.js +0 -135
- package/dist/m/c-Z4VRC7GU.js +0 -7
- package/dist/m/c-Z6K52OLP.js +0 -19
- package/dist/m/c-ZDY2MDAA.js +0 -21
- package/dist/m/c-ZUCOKOHT.js +0 -1
- package/dist/m/core/admin-attrs-VGNLAUDK.js +0 -1
- package/dist/m/core/autosave-E4PEFPZ6.js +0 -1
- package/dist/m/core/conflict-notice-VQ6Y64PH.js +0 -1
- package/dist/m/core/host-permission-XN3K2IW3.js +0 -1
- package/dist/m/core/is-edit-mode-JXHDVGUL.js +0 -1
- package/dist/m/core/recovery-TBBSICE2.js +0 -1
- package/dist/m/core/save-WUCHTQBE.js +0 -1
- package/dist/m/core/save-core-FJVHT5M3.js +0 -1
- package/dist/m/core/snapshot-F3SWDZMM.js +0 -1
- package/dist/m/core/unsaved-warning-STKBHE6G.js +0 -1
- package/dist/m/events/index-23DPTUT4.js +0 -1
- package/dist/m/internals/index-WOVAP3RU.js +0 -1
- package/dist/m/lib/cache-bust-CGWT6ZJI.js +0 -1
- package/dist/m/loader-HXX6YNH5.js +0 -1
- package/dist/m/manifest-F22DEDAC.js +0 -1
- package/dist/m/manifest-edit-C3C7376B.js +0 -1
- package/dist/m/options/options-2LH76JQ3.js +0 -1
- package/dist/m/page/editor-XUTB2HB2.js +0 -189
- package/dist/m/plugins/ai-edit-ZQ4CGWIP.js +0 -6
- package/dist/m/plugins/demo-ZIBFAA3R.js +0 -1
- package/dist/m/plugins/indicator-PV4YW2ID.js +0 -1
- package/dist/m/plugins/live-NUTTXSBS.js +0 -1
- package/dist/m/plugins/menu-HCKO3DSP.js +0 -138
- package/dist/m/plugins/page-KSUH7G6J.js +0 -2
- package/dist/m/plugins/page-view-W73OW7WI.js +0 -1
- package/dist/m/plugins/people-AJJ32YCG.js +0 -1
- package/dist/m/plugins/quickcrop-QNY3PKLD.js +0 -26
- package/dist/m/plugins/sortable-YRMQX3ZU.js +0 -1
- package/dist/m/plugins/source-KHK5UUSK.js +0 -1
- package/dist/m/plugins/undo-OF2L3CXU.js +0 -1
- package/dist/m/plugins/upgrade-ZNYODP5Y.js +0 -1
- package/dist/m/plugins/upload-XSGNILUY.js +0 -1
- package/dist/m/plugins/visitor-drafts-XK5GW55Q.js +0 -21
- package/dist/m/plugins/visitor-drafts-owner-KSSH75EV.js +0 -1
- package/dist/m/plugins/wire-ZWVWKF76.js +0 -1
- package/dist/m/reader-core-ILWLXVMP.js +0 -68
- package/dist/m/route/route-KOCZSEGN.js +0 -1
- package/dist/m/sync/live-sync-4AUVXVJU.js +0 -1
- package/dist/m/ui/index-EVHKMKBL.js +0 -1
- package/dist/m/vendor/sap-core.vendor-A7BMUYZT.js +0 -6
- /package/dist/m/{c-FILLTJA7.js → c-QTTJYJMA.js} +0 -0
- /package/dist/m/plugins/{quickcrop-QNY3PKLD.js.LEGAL.txt → quickcrop-BQ5YYFCH.js.LEGAL.txt} +0 -0
- /package/dist/m/plugins/{richclay-RC3L2F6X.js.LEGAL.txt → richclay-KLGETK77.js.LEGAL.txt} +0 -0
|
@@ -15,6 +15,18 @@ export function customTitle(root) {
|
|
|
15
15
|
return false;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
// Mark this document's title as its author's own, the way the SEO editor's custom
|
|
19
|
+
// title does. Returns whether it wrote the marker.
|
|
20
|
+
export function markCustomTitle(root) {
|
|
21
|
+
const head = headOf(root);
|
|
22
|
+
if (!head || customTitle(root)) return false;
|
|
23
|
+
const meta = head.ownerDocument.createElement("meta");
|
|
24
|
+
meta.setAttribute("name", TITLE_MODE);
|
|
25
|
+
meta.setAttribute("content", "custom");
|
|
26
|
+
head.insertBefore(meta, head.querySelector("title") ?? head.firstChild);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
export function titleText(root) {
|
|
19
31
|
return headOf(root)?.querySelector("title")?.textContent ?? "";
|
|
20
32
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { state } from "../vendor/prosemirror.vendor.js";
|
|
2
2
|
import Mutation from "../lib/mutation.js";
|
|
3
|
-
import {
|
|
3
|
+
import { UNTITLED } from "./document-title.js";
|
|
4
|
+
import { customTitle, markCustomTitle, titleFor, titleText, writeTitle } from "./document-title-dom.js";
|
|
4
5
|
|
|
5
6
|
const ATOM = "\uFFFC";
|
|
6
7
|
|
|
@@ -38,6 +39,18 @@ export function refreshDocumentTitle(view) {
|
|
|
38
39
|
return title;
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
// A file written before titles followed the first H1 can carry a title its author
|
|
43
|
+
// typed with no H1 behind it. The first time an editor opens such a file, that title
|
|
44
|
+
// becomes the author's own (the SEO custom marker), so deriving never replaces it;
|
|
45
|
+
// a file that has an H1 keeps following it, and deleting that H1 later reads Untitled.
|
|
46
|
+
export function adoptAuthoredTitle(view) {
|
|
47
|
+
const doc = view?.dom?.ownerDocument ?? null;
|
|
48
|
+
if (!doc || customTitle(doc) || titleItemsOfDoc(view.state.doc).length || [ "", UNTITLED ].includes(titleText(doc).trim())) return false;
|
|
49
|
+
Mutation.pause();
|
|
50
|
+
try { return markCustomTitle(doc); }
|
|
51
|
+
finally { Mutation.resume(); }
|
|
52
|
+
}
|
|
53
|
+
|
|
41
54
|
export function titlePlugin() {
|
|
42
55
|
return new state.Plugin({
|
|
43
56
|
view(editorView) {
|
|
@@ -46,6 +59,7 @@ export function titlePlugin() {
|
|
|
46
59
|
doc = editorView.state.doc;
|
|
47
60
|
refreshDocumentTitle(editorView);
|
|
48
61
|
};
|
|
62
|
+
adoptAuthoredTitle(editorView);
|
|
49
63
|
refresh();
|
|
50
64
|
return {
|
|
51
65
|
update(next) {
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export const UNTITLED = "Untitled";
|
|
2
2
|
|
|
3
|
-
export function documentTitle(items, { custom = false, currentTitle = "" } = {}) {
|
|
3
|
+
export function documentTitle(items, { custom = false, currentTitle = "", keepWithoutHeading = false } = {}) {
|
|
4
4
|
if (custom) return currentTitle;
|
|
5
5
|
const first = items.find(item =>
|
|
6
6
|
item.t === "heading" && (item.level ?? 2) === 1 && item.parent == null
|
|
7
7
|
);
|
|
8
|
+
// A file the editor has not adopted yet (see adoptAuthoredTitle) may carry a title
|
|
9
|
+
// its author wrote with no H1 behind it; a renderer that cannot ask keeps it.
|
|
10
|
+
if (!first && keepWithoutHeading && !["", UNTITLED].includes(String(currentTitle).trim())) return currentTitle;
|
|
8
11
|
return String(first?.c ?? "").replace(/[\s\uFFFC]+/gu, " ").trim() || UNTITLED;
|
|
9
12
|
}
|
package/src/page/drag.js
CHANGED
|
@@ -5,6 +5,8 @@ import { gapTargets, summaryTarget, pickTarget, moveSpanTo } from "./drop.js";
|
|
|
5
5
|
import { announce } from "./announce.js";
|
|
6
6
|
|
|
7
7
|
const SLOP = 4;
|
|
8
|
+
const HOLD = 250;
|
|
9
|
+
const HOLD_SLOP = 8;
|
|
8
10
|
const EDGE = 56;
|
|
9
11
|
const MAX_SPEED = 18;
|
|
10
12
|
|
|
@@ -70,6 +72,9 @@ export class BlockDrag {
|
|
|
70
72
|
this.cancel();
|
|
71
73
|
}
|
|
72
74
|
};
|
|
75
|
+
this.onOther = (e) => { if (this.state && e.pointerId !== this.state.pointer) this.cancel(); };
|
|
76
|
+
this.onBlur = () => this.cancel();
|
|
77
|
+
this.onScroll = () => { if (this.state && !this.state.active) this.stop(); };
|
|
73
78
|
grip.addEventListener("pointerdown", (e) => this.start(e));
|
|
74
79
|
}
|
|
75
80
|
|
|
@@ -82,24 +87,43 @@ export class BlockDrag {
|
|
|
82
87
|
this.state = {
|
|
83
88
|
index, span: captureSpan(ents, lo, hi), touch: event.pointerType === "touch",
|
|
84
89
|
pointer: event.pointerId, x0: event.clientX, y0: event.clientY, x: event.clientX, y: event.clientY,
|
|
85
|
-
active: false, raf: 0, gap: undefined, targets: [], target: null,
|
|
90
|
+
hold: 0, active: false, raf: 0, gap: undefined, targets: [], target: null,
|
|
86
91
|
};
|
|
87
92
|
this.grip.setPointerCapture?.(event.pointerId);
|
|
88
93
|
this.grip.addEventListener("pointermove", this.onMove);
|
|
89
94
|
this.grip.addEventListener("pointerup", this.onUp);
|
|
90
95
|
this.grip.addEventListener("pointercancel", this.onCancel);
|
|
91
96
|
this.grip.addEventListener("lostpointercapture", this.onCancel);
|
|
97
|
+
if (this.state.touch) {
|
|
98
|
+
const s = this.state;
|
|
99
|
+
s.hold = setTimeout(() => this.held(s), HOLD);
|
|
100
|
+
window.addEventListener("pointerdown", this.onOther, true);
|
|
101
|
+
window.addEventListener("blur", this.onBlur);
|
|
102
|
+
window.addEventListener("scroll", this.onScroll, true);
|
|
103
|
+
}
|
|
92
104
|
event.preventDefault();
|
|
93
105
|
}
|
|
94
106
|
|
|
107
|
+
// A touch keeps still for a quarter second before it drags: the press the mouse
|
|
108
|
+
// starts on its first move only reaches the same place once a scroll would have
|
|
109
|
+
// begun, so the hold tells the two apart. A tap before then is the menu.
|
|
110
|
+
held(s) {
|
|
111
|
+
if (this.state !== s || s.active) return;
|
|
112
|
+
s.hold = 0;
|
|
113
|
+
if (Math.hypot(s.x - s.x0, s.y - s.y0) > HOLD_SLOP || !this.view.editable) return this.stop();
|
|
114
|
+
this.begin();
|
|
115
|
+
}
|
|
116
|
+
|
|
95
117
|
move(event) {
|
|
96
118
|
const s = this.state;
|
|
97
119
|
if (!s || event.pointerId !== s.pointer) return;
|
|
98
120
|
s.x = event.clientX;
|
|
99
121
|
s.y = event.clientY;
|
|
122
|
+
if (s.touch && !this.view.editable) return s.active ? this.cancel() : this.stop();
|
|
100
123
|
if (!s.active) {
|
|
101
|
-
|
|
102
|
-
if (s.touch)
|
|
124
|
+
const reach = Math.hypot(s.x - s.x0, s.y - s.y0);
|
|
125
|
+
if (s.touch) { if (reach > HOLD_SLOP) this.stop(); return; }
|
|
126
|
+
if (reach <= SLOP) return;
|
|
103
127
|
this.begin();
|
|
104
128
|
}
|
|
105
129
|
this.track();
|
|
@@ -167,6 +191,7 @@ export class BlockDrag {
|
|
|
167
191
|
const step = () => {
|
|
168
192
|
const s = this.state;
|
|
169
193
|
if (!s?.active) return;
|
|
194
|
+
if (s.touch && !this.view.editable) return this.cancel();
|
|
170
195
|
const sc = this.scroller;
|
|
171
196
|
const box = sc === sc.ownerDocument.scrollingElement ? { top: 0, bottom: window.innerHeight } : sc.getBoundingClientRect();
|
|
172
197
|
let v = 0;
|
|
@@ -204,6 +229,7 @@ export class BlockDrag {
|
|
|
204
229
|
&& (ents[lo].node.type.name !== "list_item" || target.indent === ents[lo].node.attrs.indent);
|
|
205
230
|
if (same) return;
|
|
206
231
|
this.view.dispatch(asStep(moveSpanTo(st, ents, lo, hi, target)).scrollIntoView());
|
|
232
|
+
if (this.view.state.doc === st.doc) return announce(this.view, "Move cancelled");
|
|
207
233
|
const n = hi - lo + 1;
|
|
208
234
|
announce(this.view, `Moved ${n} ${n === 1 ? "block" : "blocks"}`);
|
|
209
235
|
this.view.focus();
|
|
@@ -218,12 +244,16 @@ export class BlockDrag {
|
|
|
218
244
|
const s = this.state;
|
|
219
245
|
if (!s) return;
|
|
220
246
|
this.state = null;
|
|
247
|
+
clearTimeout(s.hold);
|
|
221
248
|
cancelAnimationFrame(s.raf);
|
|
222
249
|
this.grip.removeEventListener("pointermove", this.onMove);
|
|
223
250
|
this.grip.removeEventListener("pointerup", this.onUp);
|
|
224
251
|
this.grip.removeEventListener("pointercancel", this.onCancel);
|
|
225
252
|
this.grip.removeEventListener("lostpointercapture", this.onCancel);
|
|
226
253
|
this.grip.releasePointerCapture?.(s.pointer);
|
|
254
|
+
window.removeEventListener("pointerdown", this.onOther, true);
|
|
255
|
+
window.removeEventListener("blur", this.onBlur);
|
|
256
|
+
window.removeEventListener("scroll", this.onScroll, true);
|
|
227
257
|
window.removeEventListener("keydown", this.onKey, true);
|
|
228
258
|
this.shell.classList.remove("is-dragging");
|
|
229
259
|
delete this.shell.dataset.drop;
|
package/src/page/editor.js
CHANGED
|
@@ -15,20 +15,20 @@ import { announcementPlugin } from "./announce.js";
|
|
|
15
15
|
import { linkPlugin } from "./link.js";
|
|
16
16
|
import { blockSelectionPlugin, asStep } from "./blocksel.js";
|
|
17
17
|
import { markdownPlugin, markdownKeys, backspaceToParagraph, composing } from "./markdown.js";
|
|
18
|
+
import { markable } from "./format-native.js";
|
|
18
19
|
import { placeholderPlugin } from "./placeholder.js";
|
|
19
20
|
import { titlePlugin } from "./document-title-runtime.js";
|
|
20
21
|
import { mediaPlugin } from "./media.js";
|
|
21
22
|
import { highlightSlot } from "./highlight-slot.js";
|
|
22
23
|
import { tableKeys, tablePlugin } from "./table.js";
|
|
23
24
|
import { tableSelectPlugin } from "./table-select.js";
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import { checklistPlugin, checklistKeys } from "./checklist.js";
|
|
25
|
+
import { viewFeatures, viewHookPlugin } from "./view-hooks.js";
|
|
26
|
+
import { checklistKeys } from "./checklist.js";
|
|
27
27
|
import { csvImportPlugin } from "./csv-import.js";
|
|
28
28
|
import { styleWithLegacyId } from "../lib/style.js";
|
|
29
29
|
import { historyIntentPlugin } from "./history-intent.js";
|
|
30
30
|
import { createFeatureLoader } from "./feature-loader.js";
|
|
31
|
-
import { COMMAND_FEATURES, FEATURES,
|
|
31
|
+
import { COMMAND_FEATURES, FEATURES, featureForNode } from "./features/registry.js";
|
|
32
32
|
import { toolViews } from "./tool-views.js";
|
|
33
33
|
|
|
34
34
|
const STYLE_ID = "page-editor-style";
|
|
@@ -39,6 +39,11 @@ const LIGHT = `
|
|
|
39
39
|
--page-rule: rgba(35, 34, 31, 0.10); --page-accent: #2F5E9E; --page-link: #164583; --page-selection: rgba(88, 120, 170, 0.20);
|
|
40
40
|
--page-check-border: rgba(35, 34, 31, 0.35); --page-check-fill: #23221F; --page-check-ink: #F7F6F2;
|
|
41
41
|
--page-callout-bg: rgba(35, 34, 31, 0.04); --page-code-bg: rgba(35, 34, 31, 0.05);
|
|
42
|
+
--page-color-gray: #5B5953; --page-color-brown: #8A5A1E; --page-color-orange: #B4531A; --page-color-yellow: #7A6210; --page-color-green: #3E6A28;
|
|
43
|
+
--page-color-blue: #1F5A8A; --page-color-purple: #5E4596; --page-color-pink: #A23E6E; --page-color-red: #9E3B2F;
|
|
44
|
+
--page-mark-bg-gray: rgba(35, 34, 31, 0.12); --page-mark-bg-brown: rgba(138, 90, 30, 0.20); --page-mark-bg-orange: rgba(180, 83, 26, 0.20);
|
|
45
|
+
--page-mark-bg-yellow: rgba(122, 98, 16, 0.22); --page-mark-bg-green: rgba(62, 106, 40, 0.20); --page-mark-bg-blue: rgba(31, 90, 138, 0.18);
|
|
46
|
+
--page-mark-bg-purple: rgba(94, 69, 150, 0.18); --page-mark-bg-pink: rgba(162, 62, 110, 0.18); --page-mark-bg-red: rgba(158, 59, 47, 0.18);
|
|
42
47
|
--page-code-token-keyword: #8A3B6E; --page-code-token-constant: #1F5A8A; --page-code-token-string: #3E6A28; --page-code-token-string-expression: #3E6A28; --page-code-token-comment: #8B877E; --page-code-token-function: #5E4596; --page-code-token-parameter: #8A5A1E; --page-code-token-punctuation: var(--page-ink-soft); --page-code-token-link: var(--page-link);
|
|
43
48
|
--page-chrome-ink-rest: rgba(35, 34, 31, 0.20); --page-chrome-ink-moved: rgba(35, 34, 31, 0.34);
|
|
44
49
|
--page-chrome-bg-rest: rgba(35, 34, 31, 0.02); --page-chrome-bg-moved: rgba(35, 34, 31, 0.04);
|
|
@@ -53,6 +58,11 @@ const DARK = `
|
|
|
53
58
|
--page-rule: rgba(231, 228, 220, 0.10); --page-accent: #8DB0E6; --page-link: #8DB0E6; --page-selection: rgba(120, 155, 210, 0.28);
|
|
54
59
|
--page-check-border: rgba(231, 228, 220, 0.35); --page-check-fill: #E7E4DC; --page-check-ink: #1A1A18;
|
|
55
60
|
--page-callout-bg: rgba(231, 228, 220, 0.05); --page-code-bg: rgba(231, 228, 220, 0.06);
|
|
61
|
+
--page-color-gray: #A3A098; --page-color-brown: #E0B47A; --page-color-orange: #E8A177; --page-color-yellow: #DEC97A; --page-color-green: #A9C98B;
|
|
62
|
+
--page-color-blue: #8DB0E6; --page-color-purple: #BBA6E6; --page-color-pink: #E3A3C4; --page-color-red: #E08A7A;
|
|
63
|
+
--page-mark-bg-gray: rgba(231, 228, 220, 0.14); --page-mark-bg-brown: rgba(224, 180, 122, 0.22); --page-mark-bg-orange: rgba(232, 161, 119, 0.22);
|
|
64
|
+
--page-mark-bg-yellow: rgba(222, 201, 122, 0.24); --page-mark-bg-green: rgba(169, 201, 139, 0.22); --page-mark-bg-blue: rgba(141, 176, 230, 0.22);
|
|
65
|
+
--page-mark-bg-purple: rgba(187, 166, 230, 0.22); --page-mark-bg-pink: rgba(227, 163, 196, 0.22); --page-mark-bg-red: rgba(224, 138, 122, 0.22);
|
|
56
66
|
--page-code-token-keyword: #D9A0C8; --page-code-token-constant: #8DB0E6; --page-code-token-string: #A9C98B; --page-code-token-string-expression: #A9C98B; --page-code-token-comment: #75726B; --page-code-token-function: #BBA6E6; --page-code-token-parameter: #E0B47A; --page-code-token-punctuation: var(--page-ink-soft); --page-code-token-link: var(--page-link);
|
|
57
67
|
--page-chrome-ink-rest: rgba(231, 228, 220, 0.18); --page-chrome-ink-moved: rgba(231, 228, 220, 0.30);
|
|
58
68
|
--page-chrome-bg-rest: rgba(231, 228, 220, 0.02); --page-chrome-bg-moved: rgba(231, 228, 220, 0.04);
|
|
@@ -100,6 +110,9 @@ export const PAGE_EDITOR_CSS = `
|
|
|
100
110
|
.page-editor pre:hover .page-code-lang, .page-editor pre:focus-within .page-code-lang, .page-code-lang:focus-visible, .page-editor pre[data-lang] .page-code-lang { opacity: 1; }
|
|
101
111
|
.page-code-lang:hover, .page-code-lang:focus-visible { background: var(--page-pop-hover); color: var(--page-ink-soft); }
|
|
102
112
|
:where(article[data-page], .page-editor) .page-callout { background: var(--page-callout-bg); border: 1px solid var(--page-callout-line); border-radius: 8px; padding: 10px 14px; }
|
|
113
|
+
/* The four floor-1 formats. A quote is set apart by its own inset and ink, with
|
|
114
|
+
no left-border accent; the palette's keys are fixed tokens, in both themes. */
|
|
115
|
+
:where(article[data-page], .page-editor) blockquote { padding-inline-start: var(--page-indent); color: var(--page-ink-soft); }
|
|
103
116
|
:where(article[data-page], .page-editor) hr { border: 0; border-top: 1px solid var(--page-rule); margin-block: 1.2em; }
|
|
104
117
|
:where(article[data-page], .page-editor) .page-hidden { display: none; }
|
|
105
118
|
:where(article[data-page], .page-editor) .page-li { position: relative; --li-indent: 0; padding-inline-start: calc((var(--li-indent) + 1) * var(--page-indent)); }
|
|
@@ -126,8 +139,8 @@ ${INDENTS.map((n) => `:where(article[data-page], .page-editor) .page-li[data-ind
|
|
|
126
139
|
.page-tool { display: inline-flex; align-items: center; justify-content: center; min-width: 28px; height: 28px; padding: 0 6px; border: 0; border-radius: 5px; background: none; color: inherit; font: 500 13px/1 var(--page-font); cursor: pointer; }
|
|
127
140
|
.page-tool:hover, .page-tool[aria-pressed="true"] { background: var(--page-pop-hover); }
|
|
128
141
|
.page-tool-turn { gap: 4px; padding: 0 8px; }
|
|
129
|
-
/* The phone's fourth control
|
|
130
|
-
|
|
142
|
+
/* The phone's fourth control folds away everything the narrow bar hides; on a desktop it
|
|
143
|
+
holds what has no button of its own (colors, icon and cover, the exports). */
|
|
131
144
|
.page-tool-sep { width: 1px; height: 16px; margin: 0 3px; background: currentColor; opacity: 0.5; }
|
|
132
145
|
.page-safe-probe { position: fixed; left: 0; bottom: 0; width: 0; height: 0; padding-bottom: env(safe-area-inset-bottom); visibility: hidden; pointer-events: none; }
|
|
133
146
|
.page-plus { position: absolute; z-index: 2; top: calc(var(--page-plus-top, 0px) - var(--page-plus-size) / 2); left: calc(var(--page-plus-left, 0px) - var(--page-plus-size) - 12px); width: var(--page-plus-size); height: var(--page-plus-size); display: grid; place-items: center; padding: 0; cursor: pointer; }
|
|
@@ -137,10 +150,23 @@ ${INDENTS.map((n) => `:where(article[data-page], .page-editor) .page-li[data-ind
|
|
|
137
150
|
.page-bubble, .page-menu { position: absolute; z-index: 4; background: var(--page-pop-bg); color: var(--page-pop-ink); border: 1px solid var(--page-pop-line); box-shadow: var(--page-pop-shadow); border-radius: var(--page-pop-radius); }
|
|
138
151
|
.page-bubble { display: flex; gap: 1px; padding: 3px; left: var(--page-pop-x, 0px); top: var(--page-pop-y, 0px); transform: translate(-50%, calc(-100% - 8px)); }
|
|
139
152
|
.page-menu { left: var(--page-pop-x, 0px); top: var(--page-pop-y, 0px); width: 260px; max-height: 340px; overflow-y: auto; padding: 6px; font-size: 14px; }
|
|
153
|
+
.page-settings { position: absolute; z-index: 4; box-sizing: border-box; left: var(--page-pop-x, 0px); top: var(--page-pop-y, 0px); width: min(264px, calc(100vw - 28px)); padding: 9px 11px; background: var(--page-pop-bg); color: var(--page-pop-ink); border: 1px solid var(--page-pop-line); border-radius: var(--page-pop-radius); box-shadow: var(--page-pop-shadow); font-size: 13px; }
|
|
154
|
+
.page-settings-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding-bottom: 6px; margin-bottom: 2px; border-bottom: 1px solid var(--page-pop-line); }
|
|
155
|
+
.page-settings-title { font-size: 12.5px; font-weight: 600; color: var(--page-pop-ink); }
|
|
156
|
+
.page-settings-close { display: inline-grid; place-content: center; width: 20px; height: 20px; padding: 0; border: 1px solid transparent; border-radius: 5px; background: none; color: var(--page-pop-muted); cursor: pointer; }
|
|
157
|
+
.page-settings-close:hover { background: var(--page-pop-hover); color: var(--page-pop-ink); }
|
|
158
|
+
.page-settings-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 6px 0; }
|
|
159
|
+
.page-settings-name { min-width: 0; font-weight: 500; line-height: 1.3; }
|
|
160
|
+
.page-settings-switch { position: relative; flex: 0 0 30px; box-sizing: border-box; width: 30px; height: 18px; padding: 0; border: 0; border-radius: 9px; background: var(--page-chrome-line-moved); cursor: pointer; transition: background-color var(--page-fade); }
|
|
161
|
+
.page-settings-switch[aria-checked="true"] { background: var(--page-accent); }
|
|
162
|
+
.page-settings-knob { position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--page-pop-bg); transition: transform var(--page-fade); }
|
|
163
|
+
.page-settings-switch[aria-checked="true"] .page-settings-knob { transform: translateX(12px); }
|
|
164
|
+
.page-settings-note { margin: 4px 0 2px; color: var(--page-pop-muted); font-size: 11px; line-height: 1.4; }
|
|
140
165
|
.page-menu-title { padding: 4px 10px 6px; color: var(--page-pop-muted); font-size: 12px; }
|
|
141
166
|
.page-menu-item { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 34px; padding: 4px 10px; border: 0; border-radius: 7px; background: none; color: inherit; font: inherit; text-align: start; cursor: pointer; }
|
|
142
167
|
.page-menu-item[aria-selected="true"], .page-menu-item.is-active, .page-menu-item:hover { background: var(--page-pop-hover); }
|
|
143
168
|
.page-menu-icon { display: grid; place-items: center; width: 24px; height: 24px; border: 1px solid var(--page-pop-line); border-radius: 6px; color: var(--page-pop-muted); font-size: 12px; flex: none; }
|
|
169
|
+
.page-menu-icon svg { display: block; }
|
|
144
170
|
.page-menu-hint { margin-inline-start: auto; color: var(--page-pop-muted); font-size: 12px; }
|
|
145
171
|
.page-menu-text { display: flex; flex-direction: column; min-width: 0; }
|
|
146
172
|
.page-menu-desc { color: var(--page-pop-muted); font-size: 12px; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
@@ -164,11 +190,48 @@ ${INDENTS.map((n) => `:where(article[data-page], .page-editor) .page-li[data-ind
|
|
|
164
190
|
.page-editor .page-title-placeholder::before { content: attr(data-placeholder); float: left; height: 0; color: var(--page-ink-faint); pointer-events: none; }
|
|
165
191
|
.page-csv-error { margin: 8px 0; color: var(--page-danger); font-size: 14px; }
|
|
166
192
|
.page-editor .page-table { max-width: 100%; min-width: 0; border: 1px solid var(--page-rule); border-radius: 8px; }
|
|
167
|
-
.page-editor .page-chart { position: relative; max-width: 100%; min-width: 0; margin-inline: 0; color: var(--page-ink); }
|
|
193
|
+
.page-editor .page-chart { position: relative; max-width: 100%; min-width: 0; margin-inline: 0; border: 1px solid var(--page-rule); border-radius: var(--page-chrome-radius); color: var(--page-ink); }
|
|
168
194
|
.page-chart-plot svg { display: block; width: 100%; height: auto; color: var(--chart-text, var(--page-ink-soft)); font: 12px var(--page-font); }
|
|
169
|
-
.page-chart
|
|
170
|
-
.page-chart-
|
|
171
|
-
.page-chart-title-
|
|
195
|
+
.page-chart-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 10px 12px; border-bottom: 1px solid var(--page-rule); }
|
|
196
|
+
.page-chart-title { min-width: 0; margin-inline-end: auto; font-size: 14px; font-weight: 600; line-height: 1.3; }
|
|
197
|
+
.page-chart-title.is-empty { color: var(--page-ink-faint); font-weight: 500; }
|
|
198
|
+
.page-chart-source { display: inline-flex; align-items: center; gap: 5px; box-sizing: border-box; height: 22px; padding: 0 7px; border: 1px solid var(--page-pop-line); border-radius: var(--page-chrome-radius); background: var(--page-pop-bg); color: var(--page-pop-muted); font: inherit; font-size: 11.5px; cursor: pointer; }
|
|
199
|
+
.page-chart-source:hover { color: var(--page-ink); border-color: var(--page-chrome-line-moved); }
|
|
200
|
+
.page-chart-source svg, .page-chart-edit svg, .page-chart-remove svg { flex: none; }
|
|
201
|
+
.page-chart-edit { display: inline-flex; align-items: center; gap: 6px; box-sizing: border-box; height: 28px; padding: 0 10px; border: 1px solid var(--page-rule); border-radius: var(--page-chrome-radius); background: none; color: var(--page-ink); font: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer; }
|
|
202
|
+
.page-chart-edit:hover, .page-chart-edit[aria-expanded="true"] { background: var(--page-pop-hover); }
|
|
203
|
+
.page-chart-panel { position: absolute; z-index: 5; top: 46px; inset-inline-end: 10px; box-sizing: border-box; width: 304px; padding: 12px; border: 1px solid var(--page-pop-line); border-radius: var(--page-pop-radius); background: var(--page-pop-bg); box-shadow: var(--page-pop-shadow); color: var(--page-pop-ink); font-family: var(--page-font); font-size: 13px; text-align: start; }
|
|
204
|
+
.page-chart-panel:focus { outline: none; }
|
|
205
|
+
.page-chart-row { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
|
|
206
|
+
.page-chart-row:last-child { margin-bottom: 0; }
|
|
207
|
+
.page-chart-label { color: var(--page-pop-muted); font-size: 12px; font-weight: 500; }
|
|
208
|
+
.page-chart-types { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; }
|
|
209
|
+
.page-chart-type, .page-chart-remove, .page-chart-done { display: inline-flex; align-items: center; justify-content: center; gap: 6px; box-sizing: border-box; height: 28px; padding: 0 10px; border: 1px solid var(--page-pop-line); border-radius: var(--page-chrome-radius); background: none; color: var(--page-pop-ink); font: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer; }
|
|
210
|
+
.page-chart-type:hover, .page-chart-remove:hover, .page-chart-done:hover { background: var(--page-pop-hover); }
|
|
211
|
+
.page-chart-type[aria-pressed="true"] { border-color: var(--page-chrome-line-moved); background: var(--page-pop-hover); font-weight: 600; }
|
|
212
|
+
.page-chart-select, .page-chart-title-input { box-sizing: border-box; width: 100%; height: 28px; padding: 0 8px; border: 1px solid var(--page-pop-line); border-radius: var(--page-chrome-radius); background: var(--page-pop-bg); color: var(--page-pop-ink); font: inherit; font-size: 12.5px; }
|
|
213
|
+
.page-chart-values { display: flex; flex-direction: column; gap: 1px; padding: 5px 6px; border: 1px solid var(--page-pop-line); border-radius: var(--page-chrome-radius); }
|
|
214
|
+
.page-chart-value { display: flex; align-items: center; gap: 7px; padding: 2px 4px; font-size: 12.5px; cursor: pointer; }
|
|
215
|
+
.page-chart-value:hover { background: var(--page-pop-hover); }
|
|
216
|
+
.page-chart-value input { margin: 0; accent-color: var(--page-accent); }
|
|
217
|
+
.page-chart-swatch { flex: none; width: 10px; height: 10px; border-radius: 2px; }
|
|
218
|
+
.page-chart-hint { color: var(--page-pop-muted); font-size: 11px; line-height: 1.4; }
|
|
219
|
+
.page-chart-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--page-pop-line); }
|
|
220
|
+
.page-chart-remove { color: var(--page-danger); }
|
|
221
|
+
.page-chart-broken { box-sizing: border-box; padding: 16px; border: 1px solid var(--page-pop-line); border-radius: var(--page-chrome-radius); background: var(--page-pop-hover); font-family: var(--page-font); text-align: start; }
|
|
222
|
+
.page-chart-broken[hidden] { display: none; }
|
|
223
|
+
.page-chart-plot[hidden] { display: none; }
|
|
224
|
+
.page-chart-broken-head { margin-bottom: 4px; font-size: 13.5px; font-weight: 600; line-height: 1.3; }
|
|
225
|
+
.page-chart-broken-text { margin: 0 0 12px; color: var(--page-pop-muted); font-size: 12.5px; line-height: 1.45; }
|
|
226
|
+
.page-chart-broken-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
|
227
|
+
.page-chart-use, .page-chart-delete { display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; height: 28px; padding: 0 10px; border: 1px solid var(--page-pop-line); border-radius: var(--page-chrome-radius); background: var(--page-pop-bg); color: var(--page-pop-ink); font: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer; }
|
|
228
|
+
.page-chart-use:hover, .page-chart-delete:hover { background: var(--page-pop-bg); border-color: var(--page-chrome-line-moved); }
|
|
229
|
+
.page-chart-delete { color: var(--page-danger); }
|
|
230
|
+
.page-chart-broken-actions .page-chart-select { width: auto; min-width: 0; flex: 1 1 140px; }
|
|
231
|
+
@media (max-width: 560px) {
|
|
232
|
+
.page-chart-panel { position: static; inset-inline-end: auto; width: auto; border: 0; border-top: 1px solid var(--page-pop-line); border-radius: 0; box-shadow: none; }
|
|
233
|
+
.page-chart-use, .page-chart-delete, .page-chart-broken-actions .page-chart-select { height: 44px; }
|
|
234
|
+
}
|
|
172
235
|
.page-table-scroll { max-width: 100%; overflow-x: auto; }
|
|
173
236
|
.page-table table { border-collapse: collapse; min-width: max-content; width: 100%; table-layout: auto; }
|
|
174
237
|
.page-table th, .page-table td { min-width: 120px; padding: 6px 10px; border-inline-end: 1px solid var(--page-rule); border-block-end: 1px solid var(--page-rule); text-align: start; white-space: pre-wrap; }
|
|
@@ -176,16 +239,62 @@ ${INDENTS.map((n) => `:where(article[data-page], .page-editor) .page-li[data-ind
|
|
|
176
239
|
.page-table th[data-kind="number"], .page-table td[data-kind="number"] { text-align: end; }
|
|
177
240
|
.page-table th[aria-sort="ascending"] button::after { content: " ↑"; }
|
|
178
241
|
.page-table th[aria-sort="descending"] button::after { content: " ↓"; }
|
|
179
|
-
.page-table th button, .page-table-row-menu
|
|
180
|
-
.page-table th button:hover, .page-table-row-menu:hover
|
|
181
|
-
.page-
|
|
242
|
+
.page-table th button, .page-table-row-menu { border: 0; border-radius: 5px; background: none; color: inherit; font: inherit; cursor: pointer; }
|
|
243
|
+
.page-table th button:hover, .page-table-row-menu:hover { background: var(--page-pop-hover); }
|
|
244
|
+
.page-editor td > span { display: block; }
|
|
245
|
+
.page-table-row-menu { float: inline-end; margin-inline-start: 4px; opacity: 0; font-size: 12px; color: var(--page-ink-soft); display: inline-grid; place-items: center; width: 22px; height: 22px; padding: 0; }
|
|
182
246
|
.page-table tr:hover .page-table-row-menu, .page-table tr:focus-within .page-table-row-menu, .page-table-row-menu:focus-visible { opacity: 1; }
|
|
183
|
-
|
|
184
|
-
.
|
|
185
|
-
|
|
247
|
+
/* The tags float to the end of the item's first line, so long text wraps beside and
|
|
248
|
+
below them without the text's own marks being pulled apart. The item's whole line
|
|
249
|
+
stays the click target for an empty item, which has no text of its own. */
|
|
250
|
+
.page-li.page-check-placeholder::after { content: attr(data-placeholder); position: absolute; inset-inline-start: calc((var(--li-indent) + 1) * var(--page-indent)); color: var(--page-ink-faint); pointer-events: none; }
|
|
251
|
+
.page-check-controls { display: inline-flex; float: inline-end; flex-wrap: wrap; align-items: center; gap: 5px; margin-inline-start: 10px; text-decoration: none; }
|
|
252
|
+
.page-check-chip { display: inline-flex; align-items: center; gap: 4px; box-sizing: border-box; height: 23px; padding: 0 7px; border: 1px solid var(--page-rule); border-radius: var(--page-check-radius); background: transparent; color: var(--page-ink-soft); font: 400 12px/1 var(--page-font); white-space: nowrap; cursor: pointer; }
|
|
253
|
+
.page-check-chip svg { flex: none; }
|
|
254
|
+
.page-check-chip:hover { background: var(--page-pop-hover); }
|
|
255
|
+
.page-check-chip[data-filled="true"] { border-color: transparent; background: var(--page-chrome-bg-moved); color: var(--page-ink); font-weight: 500; }
|
|
256
|
+
.page-check-chip[data-overdue="true"] { border-color: var(--page-danger); color: var(--page-danger); }
|
|
257
|
+
.page-li[data-checked="true"] .page-check-controls { opacity: 0.62; }
|
|
258
|
+
[data-assignees="false"] .page-check-chip[data-check="owner"], [data-dates="false"] .page-check-chip[data-check="date"] { display: none; }
|
|
259
|
+
[data-assignees="false"][data-dates="false"] .page-check-controls { display: none; }
|
|
186
260
|
.page-check-popup { display: inline-flex; gap: 4px; padding: 4px; background: var(--page-pop-bg); color: var(--page-pop-ink); border: 1px solid var(--page-pop-line); border-radius: var(--page-pop-radius); box-shadow: var(--page-pop-shadow); }
|
|
187
261
|
.page-check-popup input { font: inherit; color: inherit; background: var(--page-pop-bg); border: 1px solid var(--page-pop-line); }
|
|
188
|
-
.page-check-popup.page-check-owner { display:
|
|
262
|
+
.page-check-popup.page-check-owner, .page-check-popup.page-check-date { position: absolute; z-index: 5; display: block; box-sizing: border-box; width: min(264px, calc(100vw - 28px)); padding: 8px; background: var(--page-pop-bg); color: var(--page-pop-ink); border: 1px solid var(--page-pop-line); border-radius: var(--page-pop-radius); box-shadow: var(--page-pop-shadow); font-family: var(--page-font); }
|
|
263
|
+
.page-check-search { box-sizing: border-box; width: 100%; height: 28px; padding: 0 8px; border: 1px solid var(--page-pop-line); border-radius: 7px; background: var(--page-pop-bg); color: var(--page-pop-ink); font: inherit; font-size: 12.5px; }
|
|
264
|
+
.page-check-search::placeholder { color: var(--page-ink-faint); }
|
|
265
|
+
.page-check-subhead { padding: 7px 4px 4px; color: var(--page-pop-muted); font-size: 11.5px; font-weight: 500; }
|
|
266
|
+
.page-check-people { display: flex; flex-direction: column; gap: 1px; }
|
|
267
|
+
.page-check-person { display: flex; align-items: center; gap: 7px; width: 100%; padding: 5px 6px; border: 0; background: none; color: var(--page-pop-ink); font: inherit; font-size: 12.5px; text-align: start; cursor: pointer; }
|
|
268
|
+
.page-check-person:hover { background: var(--page-pop-hover); }
|
|
269
|
+
.page-check-person[aria-pressed="true"] { font-weight: 500; }
|
|
270
|
+
.page-check-person .page-board-face { flex: 0 0 18px; width: 18px; height: 18px; }
|
|
271
|
+
.page-check-person-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
272
|
+
.page-check-person-meta { margin-inline-start: auto; color: var(--page-pop-muted); font-size: 11px; }
|
|
273
|
+
.page-check-person svg { flex: none; }
|
|
274
|
+
.page-check-divider { height: 1px; margin: 6px 0; background: var(--page-pop-line); }
|
|
275
|
+
.page-check-danger { color: var(--page-danger); }
|
|
276
|
+
.page-check-danger:hover { background: var(--page-pop-hover); }
|
|
277
|
+
.page-check-danger[disabled] { opacity: 0.45; background: none; cursor: default; }
|
|
278
|
+
.page-check-quick { display: flex; flex-direction: column; gap: 1px; }
|
|
279
|
+
.page-check-quick-row { display: flex; align-items: center; gap: 7px; width: 100%; padding: 5px 6px; border: 0; background: none; color: var(--page-pop-ink); font: inherit; font-size: 12.5px; text-align: start; cursor: pointer; }
|
|
280
|
+
.page-check-quick-row:hover { background: var(--page-pop-hover); }
|
|
281
|
+
.page-check-quick-row svg { flex: none; }
|
|
282
|
+
.page-check-quick-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
283
|
+
.page-check-quick-meta { margin-inline-start: auto; color: var(--page-pop-muted); font-family: var(--page-font-mono); font-size: 11px; font-variant-numeric: tabular-nums; }
|
|
284
|
+
.page-check-cal { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--page-pop-line); }
|
|
285
|
+
.page-check-cal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 5px; padding: 0 2px; }
|
|
286
|
+
.page-check-cal-month { color: var(--page-pop-ink); font-size: 12px; font-weight: 600; }
|
|
287
|
+
.page-check-cal-year { font-family: var(--page-font-mono); font-size: 11.5px; font-variant-numeric: tabular-nums; }
|
|
288
|
+
.page-check-cal-nav { display: inline-flex; gap: 3px; }
|
|
289
|
+
.page-check-cal-btn { display: inline-grid; place-content: center; width: 22px; height: 22px; padding: 0; border: 1px solid var(--page-pop-line); border-radius: var(--page-check-radius); background: none; color: var(--page-pop-ink); cursor: pointer; }
|
|
290
|
+
.page-check-cal-btn:hover { background: var(--page-pop-hover); }
|
|
291
|
+
.page-check-cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; text-align: center; }
|
|
292
|
+
.page-check-cal-dow { padding: 2px 0; color: var(--page-pop-muted); font-size: 10.5px; font-weight: 500; }
|
|
293
|
+
.page-check-cal-day { height: 28px; padding: 0; border: 1px solid transparent; border-radius: var(--page-check-radius); background: transparent; color: var(--page-pop-ink); font-family: var(--page-font-mono); font-size: 11.5px; font-variant-numeric: tabular-nums; cursor: pointer; }
|
|
294
|
+
.page-check-cal-day:hover { background: var(--page-pop-hover); }
|
|
295
|
+
.page-check-cal-day[data-outside="true"] { opacity: 0.5; }
|
|
296
|
+
.page-check-cal-day[data-today="true"] { border-color: var(--page-accent); font-weight: 500; }
|
|
297
|
+
.page-check-cal-day[aria-pressed="true"] { background: var(--page-chrome-bg-moved); font-weight: 500; }
|
|
189
298
|
.page-board-owners { display: flex; flex-direction: column; gap: 6px; min-width: 0; padding-inline: 8px; }
|
|
190
299
|
.page-board-people { display: flex; flex-wrap: wrap; gap: 4px; }
|
|
191
300
|
.page-board-person { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px 0 4px; border: 1px solid var(--page-rule); border-radius: 14px; background: var(--page-pop-bg); color: var(--page-pop-ink); font: inherit; font-size: 13px; cursor: pointer; transition: background-color var(--page-fade), border-color var(--page-fade); }
|
|
@@ -211,6 +320,7 @@ ${INDENTS.map((n) => `:where(article[data-page], .page-editor) .page-li[data-ind
|
|
|
211
320
|
.page-bubble { display: none; }
|
|
212
321
|
.page-scrim { display: block; position: fixed; inset: 0; z-index: 4; background: var(--page-scrim); }
|
|
213
322
|
.page-menu { position: fixed; left: 0; top: 0; width: var(--page-pop-width, min(280px, calc(100vw - 16px))); max-height: min(70vh, var(--page-pop-max, 70vh)); overflow-y: auto; transform: translate(var(--page-pop-x, 0px), var(--page-pop-y, 0px)); z-index: 5; }
|
|
323
|
+
.page-settings { position: fixed; left: 0; top: 0; transform: translate(var(--page-pop-x, 0px), var(--page-pop-y, 0px)); z-index: 5; }
|
|
214
324
|
.page-menu-item { min-height: 48px; font-size: 16px; }
|
|
215
325
|
.page-link { position: fixed; left: 0; right: 0; top: auto; bottom: 0; max-width: none; padding: 8px 16px calc(8px + env(safe-area-inset-bottom)); border-radius: 0; border-width: 1px 0 0; }
|
|
216
326
|
.page-link-input { min-width: 0; height: 44px; font-size: 16px; }
|
|
@@ -218,7 +328,12 @@ ${INDENTS.map((n) => `:where(article[data-page], .page-editor) .page-li[data-ind
|
|
|
218
328
|
.page-image-frame { width: 100% !important; }
|
|
219
329
|
.page-image-handle { display: none; }
|
|
220
330
|
.page-table th button, .page-table-row-menu, .page-check-chip, .page-check-popup button, .page-menu-item { min-height: 44px; }
|
|
331
|
+
.page-check-person { min-height: 44px; }
|
|
332
|
+
.page-check-popup .page-check-quick-row { min-height: 44px; }
|
|
333
|
+
.page-check-popup .page-check-cal-day { height: 40px; min-height: 40px; }
|
|
221
334
|
.page-board-owner-input { font-size: 16px; height: 44px; }
|
|
335
|
+
.page-check-search { font-size: 16px; height: 44px; }
|
|
336
|
+
.page-check-popup .page-check-cal-btn { width: 44px; height: 44px; }
|
|
222
337
|
.page-board-person { height: 44px; border-radius: 22px; }
|
|
223
338
|
}
|
|
224
339
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -232,6 +347,18 @@ const insertHardBreak = (st, dispatch) => {
|
|
|
232
347
|
return true;
|
|
233
348
|
};
|
|
234
349
|
|
|
350
|
+
// Mod-u belongs to an editable page selection only: anywhere else the browser
|
|
351
|
+
// keeps its own meaning for the key. The write itself goes through the format
|
|
352
|
+
// gate, so a refused activation leaves the document exactly as it was.
|
|
353
|
+
const underlineShortcut = (st, dispatch, view) => {
|
|
354
|
+
if (!dispatch || !view?.editable || !markable(st, schema.marks.underline)) return false;
|
|
355
|
+
import("./format-native-commands.js")
|
|
356
|
+
.then(({ formatMark, refuse }) => formatMark(view, "underline").then((result) => {
|
|
357
|
+
if (result?.status !== "applied") refuse(view, result?.message ?? "That format isn\u2019t available here.");
|
|
358
|
+
}), () => null);
|
|
359
|
+
return true;
|
|
360
|
+
};
|
|
361
|
+
|
|
235
362
|
const editKeys = ({ history: useHistory = true, undo, redo } = {}) => ({
|
|
236
363
|
"Mod-z": useHistory ? history.undo : () => { undo?.(); return true; },
|
|
237
364
|
"Shift-Mod-z": useHistory ? history.redo : () => { redo?.(); return true; },
|
|
@@ -239,6 +366,7 @@ const editKeys = ({ history: useHistory = true, undo, redo } = {}) => ({
|
|
|
239
366
|
"Shift-Enter": insertHardBreak,
|
|
240
367
|
"Mod-b": commands.toggleMark(schema.marks.strong),
|
|
241
368
|
"Mod-i": commands.toggleMark(schema.marks.em),
|
|
369
|
+
"Mod-u": underlineShortcut,
|
|
242
370
|
});
|
|
243
371
|
|
|
244
372
|
const restoreShortcut = (st, dispatch, view) => {
|
|
@@ -325,7 +453,7 @@ function featureWatchPlugin(features) {
|
|
|
325
453
|
const walk = () => {
|
|
326
454
|
for (const id of failed) if (features.has(id)) failed.delete(id);
|
|
327
455
|
editorView.state.doc.forEach((node) => {
|
|
328
|
-
const id =
|
|
456
|
+
const id = featureForNode(node);
|
|
329
457
|
if (!id || features.has(id) || failed.has(id)) return;
|
|
330
458
|
features.ensure(id).catch(() => { failed.add(id); });
|
|
331
459
|
});
|
|
@@ -419,11 +547,15 @@ function createCommandHost({ load = () => Promise.reject(new Error("page: this e
|
|
|
419
547
|
}
|
|
420
548
|
}
|
|
421
549
|
|
|
422
|
-
function
|
|
550
|
+
function quiesce() {
|
|
423
551
|
if (!active) return;
|
|
424
552
|
active = false;
|
|
425
553
|
for (const waiter of waiters) waiter.controller.abort({ ok: false, code: "not-editing" });
|
|
426
554
|
waiters.clear();
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
function leave() {
|
|
558
|
+
quiesce();
|
|
427
559
|
loader?.dispose();
|
|
428
560
|
loader = null;
|
|
429
561
|
}
|
|
@@ -433,6 +565,7 @@ function createCommandHost({ load = () => Promise.reject(new Error("page: this e
|
|
|
433
565
|
observe,
|
|
434
566
|
run,
|
|
435
567
|
enter() { if (!disposed) active = true; },
|
|
568
|
+
quiesce,
|
|
436
569
|
leave,
|
|
437
570
|
dispose() {
|
|
438
571
|
leave();
|
|
@@ -447,10 +580,19 @@ const commandHosts = new WeakMap();
|
|
|
447
580
|
// A command asks for its module with the state it was asked in, so the host has to hear
|
|
448
581
|
// about every transaction: one that moves the document revision or the selection refuses
|
|
449
582
|
// a command whose module is still arriving rather than running it where the person has
|
|
450
|
-
// since left.
|
|
583
|
+
// since left. It also holds the one typed key a command owns: `@` asks for the mention
|
|
584
|
+
// picker, and the host types the character itself so the command is handed the bookmark it
|
|
585
|
+
// belongs to, with everything else about that picker left to the module that arrives for
|
|
586
|
+
// it. It is asked before the plugin that records ordinary typing, since it types it.
|
|
451
587
|
function commandWatchPlugin(host) {
|
|
452
588
|
return new state.Plugin({
|
|
453
589
|
view: () => ({ update: (editorView, prevState) => host.observe(editorView.state, prevState) }),
|
|
590
|
+
props: { handleTextInput(v, from, to, text) {
|
|
591
|
+
if (text !== "@" || v.composing || !Object.hasOwn(COMMAND_FEATURES, "mentions")) return false;
|
|
592
|
+
v.dispatch(v.state.tr.insertText("@", from, to));
|
|
593
|
+
host.run("mentions", { from, to: from + 1 });
|
|
594
|
+
return true;
|
|
595
|
+
} },
|
|
454
596
|
});
|
|
455
597
|
}
|
|
456
598
|
|
|
@@ -479,6 +621,7 @@ export function pagePlugins({ upload = defaultUpload, highlight, history: useHis
|
|
|
479
621
|
return [
|
|
480
622
|
announcementPlugin(),
|
|
481
623
|
chromePlugin({ onAiTool }),
|
|
624
|
+
commandHost ? commandWatchPlugin(commandHost) : null,
|
|
482
625
|
slashRangePlugin(),
|
|
483
626
|
toolFollowPlugin(toolHost),
|
|
484
627
|
linkPlugin(),
|
|
@@ -497,9 +640,7 @@ export function pagePlugins({ upload = defaultUpload, highlight, history: useHis
|
|
|
497
640
|
structurePlugin(),
|
|
498
641
|
identityPlugin(),
|
|
499
642
|
tablePlugin(),
|
|
500
|
-
|
|
501
|
-
boardPlugin(),
|
|
502
|
-
checklistPlugin(),
|
|
643
|
+
viewHookPlugin(),
|
|
503
644
|
csvImportPlugin({ upload }),
|
|
504
645
|
collapsePlugin(),
|
|
505
646
|
mediaPlugin({ upload, features }),
|
|
@@ -510,7 +651,6 @@ export function pagePlugins({ upload = defaultUpload, highlight, history: useHis
|
|
|
510
651
|
gapcursor.gapCursor(),
|
|
511
652
|
lazyViewsPlugin(),
|
|
512
653
|
features ? featureWatchPlugin(features) : null,
|
|
513
|
-
commandHost ? commandWatchPlugin(commandHost) : null,
|
|
514
654
|
].filter(Boolean);
|
|
515
655
|
}
|
|
516
656
|
|
|
@@ -531,14 +671,16 @@ export function refreshMountedView(view) {
|
|
|
531
671
|
|
|
532
672
|
// Admission on a mounted editor, in one place: the commit that enters edit opens it,
|
|
533
673
|
// and the exit that holds the session closed shuts it without touching a buffer.
|
|
534
|
-
export function setEditorActive(view, active) {
|
|
674
|
+
export function setEditorActive(view, active, { quiesce = false } = {}) {
|
|
535
675
|
if (!view || view.isDestroyed) return false;
|
|
536
676
|
const open = active === true;
|
|
537
677
|
view.setProps({ editable: () => open });
|
|
538
678
|
// A refused exit closes admission without destroying the view, so the commands are told
|
|
539
|
-
// here:
|
|
679
|
+
// here: a quiesce keeps what they installed and their pending registrations for the
|
|
680
|
+
// resume, and only a committed exit disposes them.
|
|
540
681
|
const host = commandHosts.get(view);
|
|
541
682
|
if (open) host?.enter();
|
|
683
|
+
else if (quiesce) host?.quiesce();
|
|
542
684
|
else host?.leave();
|
|
543
685
|
return open;
|
|
544
686
|
}
|
|
@@ -563,7 +705,7 @@ function checkboxClick(view, event) {
|
|
|
563
705
|
// Mounts the editor in `mount`, inside a .page-shell wrapper (the surface a
|
|
564
706
|
// theme styles). `onChange(record)` gets the block record (blockMap) after
|
|
565
707
|
// every transaction that changed the document.
|
|
566
|
-
export function createPageEditor(mount, { blocks = null, onChange = null, upload, highlight, doc: initialDoc, dispatch, history: useHistory = true, undo, redo, editable = true, toolHost = null, onAiTool = null, reviseTool = null, board = null, features: providedFeatures = null } = {}) {
|
|
708
|
+
export function createPageEditor(mount, { blocks = null, onChange = null, upload, highlight, doc: initialDoc, dispatch, history: useHistory = true, undo, redo, editable = true, toolHost = null, onAiTool = null, reviseTool = null, board = null, features: providedFeatures = null, formatGate = null } = {}) {
|
|
567
709
|
const doc = mount.ownerDocument;
|
|
568
710
|
// Editor chrome, injected on every edit-mode boot and kept out of the saved file:
|
|
569
711
|
// the reader theme <link> styles the page for visitors.
|
|
@@ -586,9 +728,7 @@ export function createPageEditor(mount, { blocks = null, onChange = null, upload
|
|
|
586
728
|
context: (editorView) => ({ view: editorView, upload }),
|
|
587
729
|
});
|
|
588
730
|
const nodeViewRegistry = new Map();
|
|
589
|
-
const nodeViews = {
|
|
590
|
-
chart: (node, v, getPos) => new ChartView(node, v, getPos),
|
|
591
|
-
};
|
|
731
|
+
const nodeViews = {};
|
|
592
732
|
for (const feature of Object.values(FEATURES)) for (const type of feature.views ?? feature.types) {
|
|
593
733
|
nodeViews[type] = (node, v, getPos, decorations, inner) => {
|
|
594
734
|
const make = nodeViewRegistry.get(node.type.name);
|
|
@@ -598,6 +738,10 @@ export function createPageEditor(mount, { blocks = null, onChange = null, upload
|
|
|
598
738
|
view = new pmView.EditorView(shell, {
|
|
599
739
|
state: pageState(blocks, { upload, highlight, doc: initialDoc, history: useHistory, undo, redo, onAiTool, toolHost, features, commandHost }),
|
|
600
740
|
attributes: { class: "page-editor" },
|
|
741
|
+
// The phone keeps a fixed bar and the plus and grip at the bottom: a caret scrolled into
|
|
742
|
+
// view stops clear of them.
|
|
743
|
+
scrollMargin: { top: 16, bottom: 96, left: 5, right: 5 },
|
|
744
|
+
scrollThreshold: { top: 16, bottom: 96, left: 0, right: 0 },
|
|
601
745
|
editable: () => editable,
|
|
602
746
|
nodeViews,
|
|
603
747
|
handleDOMEvents: {
|
|
@@ -622,9 +766,41 @@ export function createPageEditor(mount, { blocks = null, onChange = null, upload
|
|
|
622
766
|
},
|
|
623
767
|
});
|
|
624
768
|
nodeViewRegistries.set(view, nodeViewRegistry);
|
|
769
|
+
viewFeatures.set(view, features);
|
|
625
770
|
commandHost.attach(view);
|
|
626
771
|
commandHosts.set(view, commandHost);
|
|
627
772
|
const destroy = view.destroy.bind(view);
|
|
628
|
-
|
|
773
|
+
// A new-format command asks the format gate, which the page plugin hands over as a
|
|
774
|
+
// loader of its own: neither the gate nor its host adapter is on the editor's ready
|
|
775
|
+
// path, so a reader who never uses a newer format never fetches them. The gate is
|
|
776
|
+
// created once, on the first command, and belongs to this view.
|
|
777
|
+
let gateHeld = null;
|
|
778
|
+
let disposed = false;
|
|
779
|
+
const heldGate = () => {
|
|
780
|
+
if (!gateHeld) {
|
|
781
|
+
gateHeld = Promise.resolve().then(() => formatGate()).catch((error) => {
|
|
782
|
+
gateHeld = null;
|
|
783
|
+
throw error;
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
return gateHeld;
|
|
787
|
+
};
|
|
788
|
+
view.runFormatCommand = async (apply) => {
|
|
789
|
+
if (disposed) return { status: "disposed", retry: false };
|
|
790
|
+
if (!formatGate) return { status: "unsupported-host", code: "page-format-unsupported", retry: false };
|
|
791
|
+
const gate = await heldGate();
|
|
792
|
+
if (disposed) {
|
|
793
|
+
gate.dispose?.();
|
|
794
|
+
return { status: "disposed", retry: false };
|
|
795
|
+
}
|
|
796
|
+
return gate.run({ apply });
|
|
797
|
+
};
|
|
798
|
+
view.destroy = () => {
|
|
799
|
+
disposed = true;
|
|
800
|
+
if (gateHeld) gateHeld.then((gate) => gate?.dispose?.(), () => {});
|
|
801
|
+
commandHost.dispose();
|
|
802
|
+
features.dispose();
|
|
803
|
+
destroy();
|
|
804
|
+
};
|
|
629
805
|
return view;
|
|
630
806
|
}
|