@heycys/gallery 0.1.0 → 0.1.2
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/THIRD-PARTY-NOTICES.md +51 -1
- package/browser/editor/components/callout/index.mjs +40 -15
- package/browser/editor/components/columns/page.mjs +45 -32
- package/browser/editor/components/details/index.mjs +2 -1
- package/browser/editor/components/dialog/index.mjs +2 -1
- package/browser/editor/components/dialog/page.mjs +0 -18
- package/browser/editor/components/divider/index.mjs +1 -1
- package/browser/editor/components/embed/index.mjs +2 -2
- package/browser/editor/components/figure/page.mjs +10 -1
- package/browser/editor/components/file/page.mjs +2 -2
- package/browser/editor/components/flowchart/add.mjs +7 -6
- package/browser/editor/components/flowchart/page.mjs +1 -1
- package/browser/editor/components/heading/index.mjs +2 -0
- package/browser/editor/components/heading/page.mjs +6 -0
- package/browser/editor/components/highlight/index.mjs +4 -20
- package/browser/editor/components/icons.mjs +13 -2
- package/browser/editor/components/image/crop.mjs +6 -9
- package/browser/editor/components/image/page.mjs +2 -2
- package/browser/editor/components/installed/index.mjs +82 -29
- package/browser/editor/components/installed/page.mjs +146 -34
- package/browser/editor/components/installed/served.mjs +6 -5
- package/browser/editor/components/instances.mjs +18 -0
- package/browser/editor/components/kit.mjs +3 -0
- package/browser/editor/components/list/page.mjs +3 -6
- package/browser/editor/components/media/page.mjs +44 -14
- package/browser/editor/components/pages.mjs +2 -2
- package/browser/editor/components/registry.mjs +68 -33
- package/browser/editor/components/section/index.mjs +2 -1
- package/browser/editor/components/set-apart.mjs +24 -0
- package/browser/editor/components/table/index.mjs +64 -5
- package/browser/editor/components/table/page.mjs +30 -19
- package/browser/editor/page/annotate/anchors.mjs +4 -3
- package/browser/editor/page/annotate/card.mjs +3 -6
- package/browser/editor/page/annotate/index.mjs +61 -34
- package/browser/editor/page/autosave.mjs +357 -38
- package/browser/editor/page/beside.mjs +5 -5
- package/browser/editor/page/block-menu/colors.mjs +3 -1
- package/browser/editor/page/block-menu/index.mjs +8 -6
- package/browser/editor/page/blocks.mjs +16 -7
- package/browser/editor/page/board/client.mjs +57 -0
- package/browser/editor/page/board/hint.mjs +145 -0
- package/browser/editor/page/board/history.mjs +119 -0
- package/browser/editor/page/board/index.mjs +970 -0
- package/browser/editor/page/board/settings.mjs +209 -0
- package/browser/editor/page/caret.mjs +5 -2
- package/browser/editor/page/changes/bar.mjs +94 -0
- package/browser/editor/page/changes/ghost.mjs +206 -0
- package/browser/editor/page/changes/gone-words.mjs +94 -0
- package/browser/editor/page/changes/index.mjs +447 -0
- package/browser/editor/page/changes/words.mjs +27 -0
- package/browser/editor/page/clipboard/import/colors.mjs +3 -3
- package/browser/editor/page/clipboard/import/html.mjs +29 -6
- package/browser/editor/page/clipboard/import/inline.mjs +32 -0
- package/browser/editor/page/clipboard/import/markdown.mjs +58 -13
- package/browser/editor/page/clipboard/import/read.mjs +6 -1
- package/browser/editor/page/clipboard/import/to-blocks.mjs +44 -12
- package/browser/editor/page/clipboard/import/yuque.mjs +622 -0
- package/browser/editor/page/clipboard/index.mjs +156 -26
- package/browser/editor/page/clipboard/own/blocks.mjs +25 -16
- package/browser/editor/page/clipboard/own/chart-keys.mjs +41 -28
- package/browser/editor/page/clipboard/own/describe.mjs +16 -7
- package/browser/editor/page/clipboard/own/export.mjs +6 -6
- package/browser/editor/page/clipboard/own/selection.mjs +3 -3
- package/browser/editor/page/clipboard/own/writers.mjs +0 -11
- package/browser/editor/page/columns/index.mjs +48 -46
- package/browser/editor/page/commit.mjs +98 -25
- package/browser/editor/page/conflicts.mjs +13 -33
- package/browser/editor/page/convert.mjs +8 -7
- package/browser/editor/page/core.mjs +81 -27
- package/browser/editor/page/custom-page.mjs +106 -0
- package/browser/editor/page/drag/index.mjs +40 -24
- package/browser/editor/page/drag/preview.mjs +9 -4
- package/browser/editor/page/editor.mjs +120 -28
- package/browser/editor/page/emoji-picker/emoji-tab.mjs +22 -13
- package/browser/editor/page/emoji-picker/grid.mjs +7 -5
- package/browser/editor/page/emoji-picker/icon-tab.mjs +4 -4
- package/browser/editor/page/emoji-picker/icons.mjs +0 -1
- package/browser/editor/page/emoji-picker/index.mjs +11 -9
- package/browser/editor/page/emoji-picker/styles.mjs +156 -2
- package/browser/editor/page/emoji-picker/support.mjs +6 -4
- package/browser/editor/page/emoji-picker/upload.mjs +14 -13
- package/browser/editor/page/fills.mjs +5 -3
- package/browser/editor/page/fold/index.mjs +348 -0
- package/browser/editor/page/fold/rule.mjs +125 -0
- package/browser/editor/page/folded.mjs +23 -0
- package/browser/editor/page/format-bar/bar.mjs +2 -1
- package/browser/editor/page/format-bar/index.mjs +1 -1
- package/browser/editor/page/geometry.mjs +8 -6
- package/browser/editor/page/handle/index.mjs +22 -14
- package/browser/editor/page/hints/index.mjs +1 -1
- package/browser/editor/page/history.mjs +24 -4
- package/browser/editor/page/insert/index.mjs +30 -17
- package/browser/editor/page/links/index.mjs +5 -3
- package/browser/editor/page/links/pages.mjs +27 -9
- package/browser/editor/page/long-runs.mjs +75 -0
- package/browser/editor/page/look.mjs +69 -6
- package/browser/editor/page/margin.mjs +63 -27
- package/browser/editor/page/media-menu/index.mjs +6 -7
- package/browser/editor/page/menu.mjs +86 -31
- package/browser/editor/page/merge.mjs +24 -0
- package/browser/editor/page/notices.mjs +3 -3
- package/browser/editor/page/offered.mjs +1 -1
- package/browser/editor/page/outline/folds.mjs +11 -10
- package/browser/editor/page/outline/index.mjs +131 -45
- package/browser/editor/page/outline/list.mjs +23 -11
- package/browser/editor/page/outline/read.mjs +1 -1
- package/browser/editor/page/outline/strip.mjs +7 -1
- package/browser/editor/page/page-objects.mjs +13 -2
- package/browser/editor/page/panel.mjs +9 -13
- package/browser/editor/page/present-links.mjs +11 -2
- package/browser/editor/page/resize/index.mjs +42 -29
- package/browser/editor/page/selection/delete.mjs +8 -6
- package/browser/editor/page/selection/index.mjs +10 -3
- package/browser/editor/page/served.mjs +14 -0
- package/browser/editor/page/session.mjs +101 -6
- package/browser/editor/page/slash-menu/index.mjs +3 -3
- package/browser/editor/page/table/cell-bar.mjs +4 -1
- package/browser/editor/page/table/cells.mjs +103 -47
- package/browser/editor/page/table/icons.mjs +3 -1
- package/browser/editor/page/table/index.mjs +40 -16
- package/browser/editor/page/table/pictures.mjs +299 -0
- package/browser/editor/page/table/views.mjs +150 -0
- package/browser/editor/page/table/widths.mjs +9 -4
- package/browser/editor/page/text-select/index.mjs +43 -14
- package/browser/editor/page/todo-writes.mjs +75 -0
- package/browser/editor/page/tooltip.mjs +1 -1
- package/browser/editor/page/type-grid.mjs +4 -3
- package/browser/editor/page/typing/code-edges.mjs +63 -17
- package/browser/editor/page/typing/index.mjs +65 -9
- package/browser/editor/page/typing/leave.mjs +1 -1
- package/browser/editor/page/ui.mjs +13 -0
- package/browser/shared/annotations.mjs +8 -10
- package/browser/shared/block-packs.mjs +404 -0
- package/browser/shared/board-places.mjs +224 -0
- package/browser/shared/card-size.mjs +59 -0
- package/browser/shared/code-folds.mjs +5 -1
- package/browser/shared/colors.mjs +17 -14
- package/browser/shared/component-catalog.mjs +345 -54
- package/browser/shared/component-source.mjs +37 -0
- package/browser/shared/components/callout.mjs +4 -2
- package/browser/shared/components/index.mjs +72 -9
- package/browser/shared/components/installed.mjs +110 -8
- package/browser/shared/components/page.mjs +22 -3
- package/browser/shared/components/state.mjs +5 -1
- package/browser/shared/components/table.mjs +1 -1
- package/browser/shared/components/text.mjs +2 -2
- package/browser/shared/document-look.mjs +183 -0
- package/browser/shared/drafts.mjs +432 -0
- package/browser/shared/emoji/data/LICENSE-lucide.txt +43 -0
- package/browser/shared/emoji/data/README.md +4 -2
- package/browser/shared/emoji/data/categories.json +1 -1
- package/browser/shared/emoji/data/keywords-en.json +1 -1
- package/browser/shared/emoji/data/keywords-zh.json +1 -1
- package/browser/shared/emoji/data/names.json +1 -1
- package/browser/shared/emoji/data/positions.json +1 -1
- package/browser/shared/emoji/data/twemoji-index.json +1 -1
- package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
- package/browser/shared/emoji/data.mjs +10 -12
- package/browser/shared/emoji/emoji.mjs +8 -7
- package/browser/shared/emoji/icon-value.mjs +4 -3
- package/browser/shared/extension-sidebar.mjs +126 -0
- package/browser/shared/extensions.mjs +79 -0
- package/browser/shared/file-table.mjs +101 -0
- package/browser/shared/html-tree.mjs +11 -5
- package/browser/shared/i18n/en.mjs +374 -35
- package/browser/shared/json-layout.mjs +47 -0
- package/browser/shared/long-runs.mjs +39 -0
- package/browser/shared/net-cache.mjs +133 -0
- package/browser/shared/net-keys.mjs +32 -0
- package/browser/shared/net-policy.mjs +177 -0
- package/browser/shared/new-names.mjs +5 -2
- package/browser/shared/outline-shape.mjs +128 -0
- package/browser/shared/outline.mjs +458 -0
- package/browser/shared/pack-manifest.mjs +77 -0
- package/browser/shared/page-address.mjs +6 -3
- package/browser/shared/page-cards.mjs +308 -0
- package/browser/shared/page-links.mjs +69 -6
- package/browser/shared/pages.mjs +388 -0
- package/browser/shared/paths.mjs +6 -0
- package/browser/shared/preferences.mjs +10 -4
- package/browser/shared/preview-server.mjs +3 -7
- package/browser/shared/session.mjs +13 -5
- package/browser/shared/shipped-blocks.mjs +299 -0
- package/browser/shared/table-chart.mjs +33 -1
- package/browser/shared/todos.mjs +83 -0
- package/browser/shared/user-directory.mjs +24 -0
- package/browser/shared/versions.mjs +14 -0
- package/browser/shared/web-links.mjs +134 -0
- package/browser/shared/workspace-columns.mjs +120 -0
- package/browser/shared/workspace-look.mjs +91 -0
- package/browser/shared/workspace-name.mjs +154 -0
- package/browser/shared/workspace-query.mjs +125 -0
- package/browser/shared/workspace-registry.mjs +272 -0
- package/browser/shared/workspace.mjs +171 -20
- package/browser/shared/zoom.mjs +5 -5
- package/dist/chunk-2NRBY6AJ.mjs +2 -0
- package/dist/chunk-32ZUEFZ7.mjs +2 -0
- package/dist/chunk-35NQ4PLQ.mjs +2 -0
- package/dist/chunk-3KJHLHUO.mjs +2 -0
- package/dist/chunk-3NJACR4W.mjs +2 -0
- package/dist/chunk-4AV456RQ.mjs +2 -0
- package/dist/chunk-4OZWXZE5.mjs +5 -0
- package/dist/chunk-5XYHDBJ5.mjs +2 -0
- package/dist/chunk-5ZJA7CXT.mjs +2 -0
- package/dist/chunk-6A53MZYZ.mjs +2 -0
- package/dist/chunk-6EXH3ORZ.mjs +166 -0
- package/dist/chunk-6EZ7FNIK.mjs +3 -0
- package/dist/{chunk-UXUK4PMC.mjs → chunk-6QBHU4DF.mjs} +1 -1
- package/dist/{chunk-6U2SLSDN.mjs → chunk-6VTU6KEO.mjs} +1 -1
- package/dist/chunk-B4P2CM2J.mjs +3 -0
- package/dist/chunk-BPL64HGA.mjs +4 -0
- package/dist/chunk-BVEFGE4B.mjs +2 -0
- package/dist/chunk-BZ5RAF7L.mjs +2 -0
- package/dist/chunk-CRJEG7MT.mjs +2 -0
- package/dist/{chunk-B3VTYBYR.mjs → chunk-D4CKRD3V.mjs} +91 -91
- package/dist/chunk-D4EURAX4.mjs +4 -0
- package/dist/chunk-DQCE7TJY.mjs +5 -0
- package/dist/chunk-DR73Y2UJ.mjs +3 -0
- package/dist/{chunk-TMYZB6AV.mjs → chunk-EKNHM3P4.mjs} +1 -1
- package/dist/{chunk-DB4WKGYF.mjs → chunk-ERLAIBOA.mjs} +2 -2
- package/dist/chunk-EURLTOTZ.mjs +4 -0
- package/dist/chunk-FJYN7RTH.mjs +4 -0
- package/dist/chunk-FWNRPMCJ.mjs +12 -0
- package/dist/chunk-FWW4CSAZ.mjs +2 -0
- package/dist/{chunk-2B5E4CDJ.mjs → chunk-GPIWQ4X4.mjs} +1 -1
- package/dist/chunk-GY3FAUVM.mjs +2 -0
- package/dist/chunk-HLYV7RIH.mjs +2 -0
- package/dist/chunk-HMYTM3GT.mjs +15 -0
- package/dist/chunk-IA4PSIMD.mjs +2 -0
- package/dist/chunk-JEUK3ZO7.mjs +2 -0
- package/dist/chunk-JVHHHGEA.mjs +3 -0
- package/dist/chunk-KTKHRC6H.mjs +2 -0
- package/dist/chunk-L7UP52JO.mjs +2 -0
- package/dist/chunk-MHW7ZKOU.mjs +2 -0
- package/dist/chunk-N76HWBA3.mjs +10 -0
- package/dist/chunk-N7AZZLGT.mjs +548 -0
- package/dist/chunk-NAMN3RAF.mjs +2 -0
- package/dist/{chunk-YXAUQPVK.mjs → chunk-NFMCP2HI.mjs} +3 -3
- package/dist/chunk-NG375ILQ.mjs +2 -0
- package/dist/chunk-NVRNLK25.mjs +6 -0
- package/dist/chunk-NWFBE2YA.mjs +2 -0
- package/dist/chunk-NWR2LT5B.mjs +2 -0
- package/dist/chunk-OJKMINIU.mjs +20 -0
- package/dist/chunk-OUUP3WKT.mjs +2 -0
- package/dist/chunk-OW5NWPOJ.mjs +10 -0
- package/dist/chunk-PAREWQGB.mjs +4 -0
- package/dist/chunk-POQSE4C2.mjs +2 -0
- package/dist/chunk-PUOQ65NC.mjs +2 -0
- package/dist/{chunk-Z52HTUW7.mjs → chunk-PVER7LSC.mjs} +2 -2
- package/dist/chunk-PZDLJJTJ.mjs +3 -0
- package/dist/chunk-Q47PLKIJ.mjs +15 -0
- package/dist/chunk-Q4UEPUWF.mjs +2 -0
- package/dist/chunk-QKXMPUXC.mjs +2 -0
- package/dist/chunk-QOUEFUCH.mjs +16 -0
- package/dist/chunk-RFDZXFJF.mjs +13 -0
- package/dist/chunk-RKPWLGZ3.mjs +4 -0
- package/dist/chunk-RMECZA2K.mjs +2 -0
- package/dist/{chunk-EUX7IC5J.mjs → chunk-SQ6Y2ZMA.mjs} +2 -2
- package/dist/chunk-SX4LJYT6.mjs +8 -0
- package/dist/chunk-SXHBYZST.mjs +16 -0
- package/dist/chunk-TANZRINB.mjs +2 -0
- package/dist/chunk-TEZAWDSQ.mjs +2 -0
- package/dist/chunk-UBBRTJ2R.mjs +24 -0
- package/dist/chunk-UFNYFFKO.mjs +20 -0
- package/dist/chunk-UGWYKHBL.mjs +170 -0
- package/dist/chunk-UKSHDZZ6.mjs +2 -0
- package/dist/chunk-UMHUSOPJ.mjs +2 -0
- package/dist/chunk-UNOYVIYR.mjs +2 -0
- package/dist/chunk-V6RIYQZZ.mjs +4 -0
- package/dist/chunk-VJPFVNNW.mjs +15 -0
- package/dist/chunk-VS3ZMVGX.mjs +5 -0
- package/dist/chunk-VTKNEYT3.mjs +6 -0
- package/dist/chunk-VXACTLO3.mjs +3 -0
- package/dist/chunk-W3BGBJQW.mjs +2 -0
- package/dist/chunk-YI43RG4P.mjs +2 -0
- package/dist/chunk-YQGT4AB2.mjs +6 -0
- package/dist/chunk-ZB4H7ZN4.mjs +2 -0
- package/dist/{chunk-ACOPDCNB.mjs → chunk-ZHEHPMBK.mjs} +1 -1
- package/dist/chunk-ZTHICSSF.mjs +2 -0
- package/dist/chunk-ZUNVAXLH.mjs +2 -0
- package/dist/chunk-ZWPMCK7P.mjs +2 -0
- package/dist/cli.mjs +1 -1
- package/dist/server.mjs +1 -1
- package/dist/{chunk-EVJ3BX3M.mjs → update-fetch.mjs} +1 -1
- package/dist/worker.mjs +1 -1
- package/kit/board.css +95 -0
- package/kit/board.js +250 -0
- package/kit/charts.js +5 -71
- package/kit/code.js +14 -14
- package/kit/math.js +18 -2
- package/kit/report.css +500 -151
- package/kit/runtime.js +1720 -170
- package/kit/state.js +10 -1
- package/kit/tables.js +172 -37
- package/kit/ui.js +166 -27
- package/package.json +2 -1
- package/packs/gallery/card/component.json +14 -0
- package/packs/gallery/card/example.html +10 -0
- package/packs/gallery/card/preview.svg +1 -0
- package/packs/gallery/card/style.css +6 -0
- package/packs/gallery/card/template.html +6 -0
- package/packs/gallery/card/writing.md +14 -0
- package/packs/gallery/chart-card/component.json +15 -0
- package/packs/gallery/chart-card/example.html +14 -0
- package/packs/gallery/chart-card/kit.js +130 -0
- package/packs/gallery/chart-card/preview.svg +1 -0
- package/packs/gallery/chart-card/style.css +42 -0
- package/packs/gallery/chart-card/template.html +13 -0
- package/packs/gallery/chart-card/writing.md +20 -0
- package/packs/gallery/chart-view/component.json +20 -0
- package/packs/gallery/chart-view/example.html +13 -0
- package/packs/gallery/chart-view/kit.js +355 -0
- package/packs/gallery/chart-view/preview.svg +1 -0
- package/packs/gallery/chart-view/style.css +94 -0
- package/packs/gallery/chart-view/template.html +3 -0
- package/packs/gallery/chart-view/writing.md +22 -0
- package/packs/gallery/countdown/component.json +18 -0
- package/packs/gallery/countdown/example.html +3 -0
- package/packs/gallery/countdown/kit.js +156 -0
- package/packs/gallery/countdown/preview.svg +1 -0
- package/packs/gallery/countdown/style.css +130 -0
- package/packs/gallery/countdown/template.html +3 -0
- package/packs/gallery/countdown/writing.md +22 -0
- package/packs/gallery/habit/component.json +14 -0
- package/packs/gallery/habit/example.html +3 -0
- package/packs/gallery/habit/kit.js +295 -0
- package/packs/gallery/habit/preview.svg +1 -0
- package/packs/gallery/habit/style.css +246 -0
- package/packs/gallery/habit/template.html +3 -0
- package/packs/gallery/habit/writing.md +21 -0
- package/packs/gallery/heatmap/component.json +18 -0
- package/packs/gallery/heatmap/example.html +3 -0
- package/packs/gallery/heatmap/kit.js +351 -0
- package/packs/gallery/heatmap/preview.svg +1 -0
- package/packs/gallery/heatmap/style.css +201 -0
- package/packs/gallery/heatmap/template.html +3 -0
- package/packs/gallery/heatmap/writing.md +21 -0
- package/packs/gallery/kanban/component.json +18 -0
- package/packs/gallery/kanban/example.html +12 -0
- package/packs/gallery/kanban/kit.js +540 -0
- package/packs/gallery/kanban/preview.svg +1 -0
- package/packs/gallery/kanban/style.css +212 -0
- package/packs/gallery/kanban/template.html +3 -0
- package/packs/gallery/kanban/writing.md +20 -0
- package/packs/gallery/metric/component.json +22 -0
- package/packs/gallery/metric/example.html +15 -0
- package/packs/gallery/metric/kit.js +248 -0
- package/packs/gallery/metric/preview.svg +1 -0
- package/packs/gallery/metric/style.css +92 -0
- package/packs/gallery/metric/template.html +3 -0
- package/packs/gallery/metric/writing.md +23 -0
- package/packs/gallery/note/component.json +14 -0
- package/packs/gallery/note/example.html +3 -0
- package/packs/gallery/note/kit.js +102 -0
- package/packs/gallery/note/preview.svg +1 -0
- package/packs/gallery/note/style.css +76 -0
- package/packs/gallery/note/template.html +3 -0
- package/packs/gallery/note/writing.md +18 -0
- package/packs/gallery/pack.json +8 -0
- package/packs/gallery/recent/component.json +13 -0
- package/packs/gallery/recent/example.html +1 -0
- package/packs/gallery/recent/kit.js +238 -0
- package/packs/gallery/recent/preview.svg +1 -0
- package/packs/gallery/recent/style.css +158 -0
- package/packs/gallery/recent/template.html +1 -0
- package/packs/gallery/recent/writing.md +15 -0
- package/packs/gallery/static/component.json +13 -0
- package/packs/gallery/static/example.html +11 -0
- package/packs/gallery/static/preview.svg +1 -0
- package/packs/gallery/static/style.css +138 -0
- package/packs/gallery/static/template.html +1 -0
- package/packs/gallery/static/writing.md +18 -0
- package/packs/gallery/stats/component.json +13 -0
- package/packs/gallery/stats/example.html +1 -0
- package/packs/gallery/stats/kit.js +166 -0
- package/packs/gallery/stats/preview.svg +1 -0
- package/packs/gallery/stats/style.css +151 -0
- package/packs/gallery/stats/template.html +1 -0
- package/packs/gallery/stats/writing.md +11 -0
- package/packs/gallery/today/component.json +12 -0
- package/packs/gallery/today/example.html +1 -0
- package/packs/gallery/today/kit.js +185 -0
- package/packs/gallery/today/preview.svg +1 -0
- package/packs/gallery/today/style.css +120 -0
- package/packs/gallery/today/template.html +1 -0
- package/packs/gallery/today/writing.md +14 -0
- package/packs/gallery/todos/component.json +19 -0
- package/packs/gallery/todos/example.html +3 -0
- package/packs/gallery/todos/kit.js +342 -0
- package/packs/gallery/todos/preview.svg +1 -0
- package/packs/gallery/todos/style.css +267 -0
- package/packs/gallery/todos/template.html +3 -0
- package/packs/gallery/todos/writing.md +30 -0
- package/packs/gallery/weather/component.json +19 -0
- package/packs/gallery/weather/example.html +3 -0
- package/packs/gallery/weather/kit.js +312 -0
- package/packs/gallery/weather/preview.svg +1 -0
- package/packs/gallery/weather/style.css +258 -0
- package/packs/gallery/weather/template.html +3 -0
- package/packs/gallery/weather/writing.md +26 -0
- package/packs/gallery-soft/pack.json +8 -0
- package/release.json +13 -11
- package/sdk/doc-kit.d.ts +404 -7
- package/sdk/doc-state.d.ts +2 -0
- package/skill/SKILL.md +71 -26
- package/skill/references/block-script.md +140 -0
- package/skill/references/building-blocks.md +257 -0
- package/skill/references/example-report.html +1 -1
- package/skill/references/extensions.md +59 -0
- package/skill/references/pages-and-data.md +221 -0
- package/skill/references/writing-html.md +9 -7
- package/skill/sdk/doc-kit.d.ts +404 -7
- package/skill/sdk/doc-state.d.ts +2 -0
- package/web/assets/index-BK2e_07w.js +13 -0
- package/web/assets/index-CWFI83mF.css +1 -0
- package/web/index.html +2 -2
- package/browser/editor/components/callout/page.mjs +0 -13
- package/dist/chunk-2PBALTR3.mjs +0 -57
- package/dist/chunk-3LA3EMDE.mjs +0 -15
- package/dist/chunk-5FRMCDPY.mjs +0 -16
- package/dist/chunk-5LEK2CBS.mjs +0 -2
- package/dist/chunk-5OFN5AHC.mjs +0 -2
- package/dist/chunk-5SIYS5HN.mjs +0 -2
- package/dist/chunk-5TEK3RAD.mjs +0 -2
- package/dist/chunk-6CYG3Z4V.mjs +0 -2
- package/dist/chunk-7GHT2UCA.mjs +0 -15
- package/dist/chunk-7QQBR7PB.mjs +0 -2
- package/dist/chunk-ATCJYAR4.mjs +0 -2
- package/dist/chunk-C7HWOBIF.mjs +0 -2
- package/dist/chunk-E7VYDG2X.mjs +0 -2
- package/dist/chunk-EZY3WC6Z.mjs +0 -15
- package/dist/chunk-FQGQH4KM.mjs +0 -2
- package/dist/chunk-G7TOXONE.mjs +0 -6
- package/dist/chunk-GPF4YWWB.mjs +0 -9
- package/dist/chunk-GYQV7Y4J.mjs +0 -120
- package/dist/chunk-HMHK3EQ6.mjs +0 -2
- package/dist/chunk-HQQMJCQJ.mjs +0 -10
- package/dist/chunk-IERUOGC3.mjs +0 -6
- package/dist/chunk-ITNLYXXV.mjs +0 -3
- package/dist/chunk-L4DVONOG.mjs +0 -2
- package/dist/chunk-LAE5NQ4B.mjs +0 -2
- package/dist/chunk-LC7YNQFG.mjs +0 -2
- package/dist/chunk-LHTFLRB6.mjs +0 -4
- package/dist/chunk-NFIBI4IP.mjs +0 -26
- package/dist/chunk-NSKUTQ5J.mjs +0 -5
- package/dist/chunk-O52JMOCZ.mjs +0 -2
- package/dist/chunk-P2CAZPDP.mjs +0 -3
- package/dist/chunk-QMQUXTU4.mjs +0 -12
- package/dist/chunk-QVWVFC5K.mjs +0 -6
- package/dist/chunk-QYKCJ7FG.mjs +0 -8
- package/dist/chunk-QZY6Q64C.mjs +0 -2
- package/dist/chunk-TDQP3DKQ.mjs +0 -10
- package/dist/chunk-TX6JH7TR.mjs +0 -2
- package/dist/chunk-UNUEWH4S.mjs +0 -2
- package/dist/chunk-V4CPWKMZ.mjs +0 -2
- package/dist/chunk-VACRB2NE.mjs +0 -3
- package/dist/chunk-W63L7367.mjs +0 -7
- package/dist/chunk-W7CXPCRV.mjs +0 -6
- package/dist/chunk-XINNG4F2.mjs +0 -4
- package/dist/chunk-YL2DPWVS.mjs +0 -4
- package/dist/chunk-YZ5Z6H4W.mjs +0 -4
- package/dist/chunk-ZBIM6ARY.mjs +0 -216
- package/skill/references/building-components.md +0 -327
- package/web/assets/index-B6Ai3wsa.js +0 -13
- package/web/assets/index-SYPC3EZy.css +0 -1
|
@@ -39,7 +39,7 @@ export function readOnlyReason(target) {
|
|
|
39
39
|
if (editable(target) || target.closest("a[href]")) return null; // a link there is one to click on
|
|
40
40
|
const locked = target.closest("[data-ge-lock]");
|
|
41
41
|
if (locked) return lockText(locked.getAttribute("data-ge-lock"));
|
|
42
|
-
const hint = READ_ONLY_HINTS.find(({ at }) => target.closest(at));
|
|
42
|
+
const hint = READ_ONLY_HINTS.find(({ at }) => (typeof at === "function" ? at(target) : target.closest(at)));
|
|
43
43
|
if (hint) return hint.says;
|
|
44
44
|
const ownText = [...target.childNodes].some((node) => node.nodeType === 3 && node.data.trim());
|
|
45
45
|
return ownText ? t("这里暂不能在页面上修改。") : null;
|
|
@@ -148,6 +148,23 @@ export function createHistory({ changed, beforeUndo, blocks, afterText, refuse =
|
|
|
148
148
|
for (const stack of [undoStack, redoStack]) if (stack.includes(step)) stack.splice(stack.indexOf(step), 1);
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
// An attribute the file gave another value than the page had (`changes`: [element, name, from, to],
|
|
152
|
+
// `to` null for none; a key of a table a commit gave a pair anew: page/commit.mjs apply), the page's
|
|
153
|
+
// element set so: the steps that recorded `from` of it record `to` instead, so that an undo or a redo
|
|
154
|
+
// puts back what the file has, never the value it changed (a table's 视图 › redone with the key its view
|
|
155
|
+
// no longer carries).
|
|
156
|
+
function rekeyed(changes) {
|
|
157
|
+
if (changes.length === 0) return;
|
|
158
|
+
for (const step of [...undoStack, ...redoStack]) {
|
|
159
|
+
for (const recorded of [step.attributesBefore, step.attributesAfter]) {
|
|
160
|
+
for (const [element, name, from, to] of changes) {
|
|
161
|
+
const values = recorded?.get(element);
|
|
162
|
+
if (values?.some(([each, value]) => each === name && value === from)) recorded.set(element, values.map(([each, value]) => [each, each === name && value === from ? to : value]));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
151
168
|
// What a step puts into a block (`from`: what the step left there, `to`: what it puts back): as
|
|
152
169
|
// recorded, unless someone else's words were merged into the block since the step; then the step's
|
|
153
170
|
// change three ways against what the block holds now (null: the two touch the same place).
|
|
@@ -174,8 +191,10 @@ export function createHistory({ changed, beforeUndo, blocks, afterText, refuse =
|
|
|
174
191
|
// after undo and redo (a deleted Sheet tab switches the Sheet shown). A step that names no text block
|
|
175
192
|
// it came from keeps where the caret stood, which undo puts back, as notion-lite's selectionBefore.
|
|
176
193
|
// `attributes`: [element, [names]] whose attributes the step records too (a table's cells: their
|
|
177
|
-
// spans and widths, which its operations change: components/table/page.mjs).
|
|
178
|
-
|
|
194
|
+
// spans and widths, which its operations change: components/table/page.mjs). `caret`: where the caret
|
|
195
|
+
// stood in the first text block it touched is kept too, which undo puts back (notion-lite's Enter in the
|
|
196
|
+
// page's title, enter.js: "撤销后光标回到回车前的位置"; typing/ enterBody).
|
|
197
|
+
function struct(parents, touched, mutate, { attributes = [], caret = false } = {}) {
|
|
179
198
|
closeTyping();
|
|
180
199
|
// What the change may leave untidy is tidied after it by the components that know (rows of
|
|
181
200
|
// columns with a column emptied, lists set side by side: tidy), so what they name is recorded
|
|
@@ -189,7 +208,7 @@ export function createHistory({ changed, beforeUndo, blocks, afterText, refuse =
|
|
|
189
208
|
}
|
|
190
209
|
// A text block among the parents (a list item whose lists change) keeps its text through undo too.
|
|
191
210
|
touched = [...new Set([...touched, ...parents.filter(isHost)])];
|
|
192
|
-
const place = touched[0] ? null : caretPlace(parents[0]);
|
|
211
|
+
const place = touched[0] && !caret ? null : caretPlace(parents[0]);
|
|
193
212
|
const before = parents.map(contentOf);
|
|
194
213
|
const htmlBefore = new Map(touched.map((node) => [node, ownHTML(node)]));
|
|
195
214
|
const classesBefore = new Map(touched.map((node) => [node, new Set(node.classList)]));
|
|
@@ -219,7 +238,7 @@ export function createHistory({ changed, beforeUndo, blocks, afterText, refuse =
|
|
|
219
238
|
.filter(({ added, removed }) => added.length > 0 || removed.length > 0),
|
|
220
239
|
attributesBefore,
|
|
221
240
|
attributesAfter: attributesOf(),
|
|
222
|
-
focusBefore: touched[0] ?? place?.host,
|
|
241
|
+
focusBefore: (caret ? place?.host : null) ?? touched[0] ?? place?.host,
|
|
223
242
|
caretBefore: place?.offsets ?? null,
|
|
224
243
|
focusAfter: result.focus,
|
|
225
244
|
select: result.select ?? null,
|
|
@@ -381,6 +400,7 @@ export function createHistory({ changed, beforeUndo, blocks, afterText, refuse =
|
|
|
381
400
|
sourceStep,
|
|
382
401
|
fold,
|
|
383
402
|
drop,
|
|
403
|
+
rekeyed,
|
|
384
404
|
closeTyping,
|
|
385
405
|
struct,
|
|
386
406
|
finish,
|
|
@@ -4,13 +4,13 @@ import { begin, done, made } from "../made.mjs";
|
|
|
4
4
|
import { selectsBeside } from "../beside.mjs";
|
|
5
5
|
import { caretAt, nearestOnLine, placeCaret, selectAt } from "../caret.mjs";
|
|
6
6
|
import { sectionOps } from "../page-objects.mjs";
|
|
7
|
-
import { endOf, hoverAt, innerBox, measure } from "../geometry.mjs";
|
|
7
|
+
import { contentOf, endOf, hoverAt, innerBox, measure } from "../geometry.mjs";
|
|
8
8
|
import { BOXED, HOLDS_ONE, accepts } from "../../components/registry.mjs";
|
|
9
9
|
import { DIALOG } from "../../components/kit.mjs";
|
|
10
10
|
|
|
11
11
|
// Where new blocks come from (docs/editor.md, "New blocks and conversions" and "Selecting
|
|
12
|
-
// blocks"): a click on the empty space below the last block of a box (
|
|
13
|
-
// caret into the empty one already at its end), Enter at the very start of a block (a paragraph
|
|
12
|
+
// blocks"): a click on the empty space below the last block of a box (not one whose end is its
|
|
13
|
+
// padding; a new paragraph there, or the caret into the empty one already at its end), Enter at the very start of a block (a paragraph
|
|
14
14
|
// before it), the handle's "+" (an empty block beside the block: addNear), and the block menu's new section after a block (components/section/page.mjs). A
|
|
15
15
|
// paragraph made here is written once it has text. "在下方新建一块" in a block's menu, like the "/"
|
|
16
16
|
// menu's blocks in a block with text, is the editor's insertBelow; blocks also come from conversions
|
|
@@ -49,16 +49,20 @@ export function createInsert({ struct, blocks }) {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
// A click on empty space (selection/marquee.mjs), below the last block of the box clicked (the
|
|
52
|
-
// page, a Sheet panel, a section, a
|
|
53
|
-
// page): a new paragraph at its end, or the caret into the empty paragraph already there
|
|
54
|
-
// (geometry.mjs endOf).
|
|
55
|
-
//
|
|
56
|
-
//
|
|
52
|
+
// page, a Sheet panel, a section, a column, a detail card's content, a flowchart's node; below the
|
|
53
|
+
// report, the page): a new paragraph at its end, or the caret into the empty paragraph already there
|
|
54
|
+
// (geometry.mjs endOf). Under the last block of a box whose end is its own padding (endIsPadding: a
|
|
55
|
+
// highlight block, a callout, a disclosure's content; the user's, 2026-11-06, as notion-lite's click-blank.js
|
|
56
|
+
// makes a block only below the page and in a column) it is a gap like any other, below. Right of
|
|
57
|
+
// the text area a boxed block (a code block, a callout, a file…: not text) or a row of columns
|
|
58
|
+
// stands in, at its height (boxedBeside), that block selected, so Delete takes it and Enter puts a
|
|
59
|
+
// paragraph after it; between a narrower block's right edge and its column's, as beside any block
|
|
60
|
+
// of no text (below). Elsewhere beside text, the caret goes into the text block on that line (the nearest of those
|
|
57
61
|
// side by side), where the line is nearest the click (Notion's way); in the gap between two
|
|
58
62
|
// blocks, or beside a block of no text, into the nearer of the blocks around it that is text, in the
|
|
59
63
|
// innermost box at that height (boxBeside: the press may be on the page's margin, the block in a
|
|
60
64
|
// Sheet's panel or a section), else in the boxes around that one, at the place nearest the click on
|
|
61
|
-
// its nearest line (
|
|
65
|
+
// its nearest line (somewhere in the box clicked or around it, when any is text). The page stays where it
|
|
62
66
|
// is, that text out of sight too (caretNear; notion-lite's click-blank.js scrolls no page either).
|
|
63
67
|
function clickBlank(x, y, target) {
|
|
64
68
|
// In an open detail card, its content is the page: never a block behind it (marquee.mjs topOf).
|
|
@@ -77,7 +81,7 @@ export function createInsert({ struct, blocks }) {
|
|
|
77
81
|
if (end?.focus) return caretAt(end.focus, "end");
|
|
78
82
|
if (end) return newParagraph(end.box, end.after);
|
|
79
83
|
const top = y + scrollY;
|
|
80
|
-
const beside = boxedBeside(main, x, y);
|
|
84
|
+
const beside = boxedBeside(main, x, y, target);
|
|
81
85
|
if (beside) return blocks().select(beside);
|
|
82
86
|
const host = hoverAt(measure(main, { top, bottom: top }), x + scrollX, top, { reach: Infinity, skip: (unit) => !unit.text });
|
|
83
87
|
if (host) return caretNear(host, x, y);
|
|
@@ -144,8 +148,8 @@ export function createInsert({ struct, blocks }) {
|
|
|
144
148
|
return Math.max(rect.top - y, y - rect.bottom, 0);
|
|
145
149
|
};
|
|
146
150
|
// A block that is no text of its own (its category: a card, a container of its own or a whole
|
|
147
|
-
// block
|
|
148
|
-
// boxes text flows in (a list, a quote, a section, columns).
|
|
151
|
+
// block, a highlight block, a callout; a code block, a formula block, a divider), as opposed to text
|
|
152
|
+
// blocks and the boxes text flows in (a list, a quote, a section, columns).
|
|
149
153
|
const boxed = (unit) => BOXED.has(unit.getAttribute("data-ge-unit-kind"));
|
|
150
154
|
// The text block of `unit` at its bottom (`last`) or its top: itself, or the last (first) of those it holds; none in a boxed block.
|
|
151
155
|
function textEdge(unit, last) {
|
|
@@ -153,14 +157,23 @@ export function createInsert({ struct, blocks }) {
|
|
|
153
157
|
const texts = [unit, ...unit.querySelectorAll("[data-ge-block], [data-ge-new]")].filter((node) => node.isContentEditable && node.getClientRects().length > 0 && !node.closest("details:not([open]) > :not(summary)"));
|
|
154
158
|
return (last ? texts.at(-1) : texts[0]) ?? null;
|
|
155
159
|
}
|
|
156
|
-
// A boxed block or a row of columns at height `y` with (x, y)
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
|
|
160
|
+
// A boxed block or a row of columns at height `y` with (x, y) right of the text area it stands in
|
|
161
|
+
// (the content box of its box: the page's column, a column of 分栏, a section's, a quote's, a
|
|
162
|
+
// highlight block's or a callout's, a disclosure's content) and right of the block itself (one
|
|
163
|
+
// wider than that area), or null: in the page's margin, or in the padding of the box it stands in;
|
|
164
|
+
// never between a narrower block's right edge and its area's (a table, a picture: the user's,
|
|
165
|
+
// 2026-11-07, a click there selected it), nor in another text area (the blank box `target` the
|
|
166
|
+
// press was on holds the block: a column further right is no place beside one in the column left
|
|
167
|
+
// of it). The innermost, but never a block inside a row of columns the click is to the right of too
|
|
168
|
+
// (the row is selected whole): past a column's edge is the gap to the next column, whose press is
|
|
169
|
+
// the gap's (columns/: it drags, a click alone changes nothing), or past the row, which is selected.
|
|
170
|
+
function boxedBeside(main, x, y, target) {
|
|
160
171
|
let found = null;
|
|
161
172
|
const right = (unit) => {
|
|
162
173
|
const rect = unit.getBoundingClientRect();
|
|
163
|
-
|
|
174
|
+
if (y < rect.top || y > rect.bottom || (target?.contains && !target.contains(unit))) return false;
|
|
175
|
+
const box = unit.parentElement;
|
|
176
|
+
return x > Math.max(rect.right, contentOf(box.getBoundingClientRect(), getComputedStyle(box)).right);
|
|
164
177
|
};
|
|
165
178
|
for (const unit of main.querySelectorAll(`[data-ge-unit-kind]`)) {
|
|
166
179
|
if (!selectsBeside(unit) || !unit.parentElement?.hasAttribute("data-ge-box") || unit.parentElement.closest("details:not([open])")) continue;
|
|
@@ -9,7 +9,7 @@ import { placeBox } from "../placement.mjs";
|
|
|
9
9
|
import { tooltip } from "../tooltip.mjs";
|
|
10
10
|
import { addStyle, copyAddress, element, fadeIn, mount, swallowNext } from "../ui.mjs";
|
|
11
11
|
import { typedHref } from "./address.mjs";
|
|
12
|
-
import { findPages, heldList, pageRows, placeIn, readPages, titleIn, trashed } from "./pages.mjs";
|
|
12
|
+
import { findPages, heldList, pageRows, placeIn, readPages, titleIn, trashed, webLinkIn } from "./pages.mjs";
|
|
13
13
|
import { DIALOG_TRIGGER } from "../../components/dialog/index.mjs";
|
|
14
14
|
import { DIALOG_ICON } from "../../components/icons.mjs";
|
|
15
15
|
import { VIEWS, closeOffer, closeViews, hasViews, hrefOf, isPageChip, offerViews, openViews, pageChip, refetch, viewNodes, viewOf, viewsHold } from "./views.mjs";
|
|
@@ -668,12 +668,14 @@ async function listedPage(address) {
|
|
|
668
668
|
|
|
669
669
|
/**
|
|
670
670
|
* Whether a page alone in a tab may leave for a workbench's `hash`, which only the list reads: not for
|
|
671
|
-
* one that names no document, said as the workbench says it, the page staying.
|
|
671
|
+
* one that names no document, said as the workbench says it, the page staying. A web link of the sidebar,
|
|
672
|
+
* or an entry of an extension's column with an address (#~<id>/<entry id>), is a place the workbench
|
|
673
|
+
* opens (in its content area), so it goes there. With no answer it goes,
|
|
672
674
|
* for the workbench to say.
|
|
673
675
|
*/
|
|
674
676
|
export async function leadsToPage(hash) {
|
|
675
677
|
const list = await readPages(use.own());
|
|
676
|
-
if (!list || placeIn(list, `#${hash}`)) return true;
|
|
678
|
+
if (!list || placeIn(list, `#${hash}`) || webLinkIn(list, hash)) return true;
|
|
677
679
|
use.say(inTrash(list.trash, hash) ? t("这个页面已删除。") : t("没有找到这个页面。"));
|
|
678
680
|
return false;
|
|
679
681
|
}
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { iconUrl } from "../../../shared/emoji/icon-value.mjs";
|
|
2
2
|
import { escapeAttribute } from "../../../shared/escape.mjs";
|
|
3
3
|
import { addressOn, decoded, hashAddress } from "../../../shared/page-address.mjs";
|
|
4
|
+
import { DOCS, isTop, topOf } from "../../../shared/outline-shape.mjs";
|
|
5
|
+
import { entryOfKey } from "../../../shared/extension-sidebar.mjs";
|
|
4
6
|
import { inTrash, namedLinks, pageLink, pageLinks } from "../../../shared/page-links.mjs";
|
|
5
7
|
import { PAGE_ICON } from "../../components/icons.mjs";
|
|
8
|
+
import { t } from "../../../shared/i18n/index.mjs";
|
|
6
9
|
|
|
7
10
|
// The documents of the workspace, as a link's card, a page block's box and "@" look for them
|
|
8
11
|
// (docs/editor.md, "Links"): one search for the three. The list is read once for each opening from
|
|
9
12
|
// what the workbench reads itself (GET /__gallery/workspace/outline: no route of its own, nothing
|
|
10
|
-
// pushed), in the sidebar's order,
|
|
11
|
-
//
|
|
12
|
-
//
|
|
13
|
+
// pushed), in the sidebar's order, column after column (栏: shared/outline-shape.mjs), each document with
|
|
14
|
+
// the title of the one above it in the sidebar; 写作偏好 is no page to link to, nor is a web link of the
|
|
15
|
+
// sidebar (kind "link": no file of its own to link to; the documents under one are pages all the same) or a
|
|
16
|
+
// draft of another workspace (kind "draft": its file is that workspace's, which no relative link reaches),
|
|
17
|
+
// and this page has the title it shows now, not the one last saved. A list that cannot be read is no
|
|
18
|
+
// results, and the field goes on taking addresses.
|
|
13
19
|
//
|
|
14
20
|
// What a copy writes is an address by a page's link, and a copy cannot wait for an answer: the
|
|
15
21
|
// clipboard takes a write only in the click itself. So the page holds the list ready, the last one
|
|
@@ -31,8 +37,8 @@ let shown = () => null; // this page, as readPages takes it
|
|
|
31
37
|
|
|
32
38
|
/**
|
|
33
39
|
* The workspace's documents: { pages: [{ slug, title, icon, parent }] (`parent`: the title of the one
|
|
34
|
-
* it is under, or null), links: their links (shared/page-links.mjs), trash: what the trash holds }, or
|
|
35
|
-
* null when the list cannot be read. `own`: this page, { slug, title } as it shows it.
|
|
40
|
+
* it is under, or null), links: their links (shared/page-links.mjs), trash: what the trash holds but web links }, or
|
|
41
|
+
* null when the list cannot be read (`webs`: the links of the sidebar's web links, which are no pages). `own`: this page, { slug, title } as it shows it.
|
|
36
42
|
*/
|
|
37
43
|
export async function readPages(own = null) {
|
|
38
44
|
const listed = await fetch(OUTLINE).then((answer) => answer.json()).catch(() => null);
|
|
@@ -41,13 +47,18 @@ export async function readPages(own = null) {
|
|
|
41
47
|
const pages = [];
|
|
42
48
|
const walk = (parent) => {
|
|
43
49
|
for (const slug of listed.outline?.children?.[parent] ?? []) {
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
const report = listed.reports[slug];
|
|
51
|
+
if (!report || report.instructions) continue;
|
|
52
|
+
// An untitled document is named 未命名文档, as the workbench names it (its link's words: its page id alone).
|
|
53
|
+
if (report.kind !== "link" && report.kind !== "draft") pages.push({ slug, title: titleOf(slug) || t("未命名文档"), icon: report.icon ?? null, parent: isTop(parent) ? null : titleOf(parent) || t("未命名文档") });
|
|
46
54
|
walk(slug);
|
|
47
55
|
}
|
|
48
56
|
};
|
|
49
|
-
walk(
|
|
50
|
-
|
|
57
|
+
for (const { id } of listed.outline?.groups ?? [{ id: DOCS }]) walk(topOf(id));
|
|
58
|
+
// The sidebar's web links, by their links as a workbench's hash holds them: no page to link to, but an address the workbench opens.
|
|
59
|
+
const web = Object.values(listed.reports).filter((report) => report.kind === "link").map(({ slug, title }) => ({ slug, title }));
|
|
60
|
+
// And the extensions' columns (their entries: an address #~<id>/<entry id> the workbench opens too).
|
|
61
|
+
held = { pages, links: pageLinks(pages.map(({ slug }) => ({ slug, title: titleOf(slug) }))), webs: pageLinks(web), extensions: listed.extensions ?? [], trash: (listed.trash ?? []).filter(({ kind }) => kind !== "link") };
|
|
51
62
|
return held;
|
|
52
63
|
}
|
|
53
64
|
|
|
@@ -118,6 +129,13 @@ export function placeIn(list, text) {
|
|
|
118
129
|
return page ? { ...page, block: place.block } : null;
|
|
119
130
|
}
|
|
120
131
|
|
|
132
|
+
/**
|
|
133
|
+
* Whether workbench hash `hash` (no #) names a web link of the sidebar, or an entry of an extension's
|
|
134
|
+
* column that has an address (#~<id>/<entry id>): the workbench opens it in its content area, though it
|
|
135
|
+
* is no page to link to.
|
|
136
|
+
*/
|
|
137
|
+
export const webLinkIn = (list, hash) => Boolean(hashAddress(decoded(hash), list.webs) || entryOfKey(list.extensions, decoded(hash))?.url);
|
|
138
|
+
|
|
121
139
|
/** The title of the page `text` is an address of, of `list` or of its trash, or null: what stands for a link to it where its address would be a folder's. */
|
|
122
140
|
export function titleIn(list, text) {
|
|
123
141
|
const binned = addressOn(text, pageLinks(list.trash), globalThis.location?.origin)?.slug;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { holdsLongRun } from "../../shared/long-runs.mjs";
|
|
2
|
+
import { textFilters } from "../components/registry.mjs";
|
|
3
|
+
import { addStyle } from "./ui.mjs";
|
|
4
|
+
|
|
5
|
+
// A long run in the text the page editor edits (src/shared/long-runs.mjs: a path, a URL, a long
|
|
6
|
+
// identifier, more than 20 characters with no place to break inside it) breaks where its line ends,
|
|
7
|
+
// as the kit breaks it in the page a reader sees (runtime/spacing.js, a span that breaks anywhere,
|
|
8
|
+
// .doc-long-run). No span goes into text the editor keeps equal to the file, so a text block whose
|
|
9
|
+
// own text holds such a run breaks anywhere as a whole (data-ge-long-run: word-break: break-all),
|
|
10
|
+
// and an ordinary word in that block may then be parted at a line's end too, which no other block's
|
|
11
|
+
// is (the compromise docs/editor.md names). The rule's weight is none: a block's own (a table's
|
|
12
|
+
// header keep-all, a short field normal, a code block's lines) wins; what the block holds that is a
|
|
13
|
+
// block or an atom of its own ([contenteditable="false"]: a nested list, a formula) breaks as it would
|
|
14
|
+
// without it, and an item of that list is judged by its own text. Never a block of plain text (a code
|
|
15
|
+
// block's lines, a tab's name: textFilters false), which keeps its own rule; a text part of an
|
|
16
|
+
// instance of a component package is judged as any text block (its component's own word-break, where
|
|
17
|
+
// it says one, wins), though the kit holds no run in an instance's own region.
|
|
18
|
+
//
|
|
19
|
+
// Judged as editing starts, for every text block, and again for the blocks whose text changed, as it
|
|
20
|
+
// changes, whatever changed it (typing, a paste, undo, a rebuild from the file, a block made or made
|
|
21
|
+
// editable): the page's mutations are watched (childList, characterData, contenteditable), and only
|
|
22
|
+
// the blocks they stand in are judged, each by its own text (a regular expression over a block's
|
|
23
|
+
// words: no scan of the page per keystroke). The marker is no text of the file's: a data-ge-* attribute
|
|
24
|
+
// on the block itself (core.mjs), set or taken off only where it changes.
|
|
25
|
+
|
|
26
|
+
const MARK = "data-ge-long-run";
|
|
27
|
+
const HOST = '[contenteditable="true"]';
|
|
28
|
+
|
|
29
|
+
const STYLE = `
|
|
30
|
+
/* A text block holding a long run breaks anywhere (long-runs.mjs), of no weight: a block's own rule wins. */
|
|
31
|
+
:where([data-ge-editing] [data-ge-long-run]) { word-break: break-all; }
|
|
32
|
+
/* What it holds of its own (a nested list, a formula) breaks as the page's text does. */
|
|
33
|
+
:where([data-ge-editing] [data-ge-long-run] [contenteditable="false"]) { word-break: normal; }
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
// The text of `host` its own: not a block or an atom it holds (contenteditable="false"), a line break a space.
|
|
37
|
+
function ownText(host) {
|
|
38
|
+
const walker = host.ownerDocument.createTreeWalker(host, 5, { // NodeFilter.SHOW_ELEMENT | SHOW_TEXT
|
|
39
|
+
acceptNode: (node) => (node.nodeType === 1 && node !== host && node.hasAttribute("contenteditable") ? 2 : 1), // FILTER_REJECT, FILTER_ACCEPT
|
|
40
|
+
});
|
|
41
|
+
let text = "";
|
|
42
|
+
for (let node = walker.nextNode(); node; node = walker.nextNode()) {
|
|
43
|
+
if (node.nodeType === 3) text += node.data;
|
|
44
|
+
else if (node.localName === "br") text += " ";
|
|
45
|
+
}
|
|
46
|
+
return text;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Marks `element` as a text block holding a long run, or takes the mark off: whether it holds one. */
|
|
50
|
+
export function judgeLongRuns(element) {
|
|
51
|
+
const long = element.isConnected && element.matches(HOST) && textFilters(element) && holdsLongRun(ownText(element));
|
|
52
|
+
if (long !== element.hasAttribute(MARK)) element.toggleAttribute(MARK, long);
|
|
53
|
+
return long;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Judges every text block under `root` now, and each again as its text changes. */
|
|
57
|
+
export function followLongRuns(root) {
|
|
58
|
+
addStyle(STYLE);
|
|
59
|
+
for (const host of root.querySelectorAll(`${HOST}, [${MARK}]`)) judgeLongRuns(host);
|
|
60
|
+
new MutationObserver((records) => {
|
|
61
|
+
const judged = new Set();
|
|
62
|
+
for (const record of records) {
|
|
63
|
+
if (record.type === "attributes") judged.add(record.target); // made editable, or no longer
|
|
64
|
+
const at = record.target.nodeType === 1 ? record.target : record.target.parentElement;
|
|
65
|
+
const host = at?.closest(HOST);
|
|
66
|
+
if (host) judged.add(host);
|
|
67
|
+
for (const node of record.addedNodes) {
|
|
68
|
+
if (node.nodeType !== 1) continue;
|
|
69
|
+
if (node.matches(HOST)) judged.add(node);
|
|
70
|
+
for (const inner of node.querySelectorAll(HOST)) judged.add(inner);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
judged.forEach(judgeLongRuns);
|
|
74
|
+
}).observe(root, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: ["contenteditable"] });
|
|
75
|
+
}
|
|
@@ -1,25 +1,61 @@
|
|
|
1
1
|
// What every popup of the editor is painted with, written once: Notion's neutral palette, its blue
|
|
2
2
|
// and its two shadows, light and dark by light-dark() (the page's color-scheme decides). A sheet of
|
|
3
|
-
// `:root` custom properties, put in every document the editor draws in (ui.mjs addStyleTo), so a
|
|
3
|
+
// `:root` custom properties and the one button look (BUTTONS), put in every document the editor draws in (ui.mjs addStyleTo), so a
|
|
4
4
|
// menu, a card, a bar, a notice reads them wherever it stands and none declares a palette of its
|
|
5
5
|
// own. Values are Notion's own as notion-lite carries them (view/theme/notion-vars.css), which this
|
|
6
6
|
// editor follows; the page's content colors (--doc-*, the kit's tokens.css) are another matter.
|
|
7
7
|
//
|
|
8
8
|
// The blue is two tokens because notion-lite has two, for two jobs: --ge-accent (its
|
|
9
|
-
// --c-bluBacAccPri: a
|
|
10
|
-
// and --c-inpBluFocRin: the ring round a focused field).
|
|
9
|
+
// --c-bluBacAccPri: a switch, a chosen icon, a table's tools, the bars that mark a place) and
|
|
10
|
+
// --ge-focus (its --c-butBluFocRin and --c-inpBluFocRin: the ring round a focused field). A button is
|
|
11
|
+
// neither: the one button look is BUTTONS below, whose primary is a pale blue (--ge-btn-primary*), the
|
|
12
|
+
// workbench's, never the solid --ge-accent.
|
|
11
13
|
//
|
|
12
14
|
// Two shadows, because Notion has two surfaces: --ge-shadow, a card standing over the text (the
|
|
13
15
|
// format bar, the formula and link cards, the conflicts, a notice), and --ge-shadow-pop, a menu
|
|
14
|
-
// (Notion's large outer shadow). The
|
|
15
|
-
//
|
|
16
|
+
// (Notion's large outer shadow). The icon picker reads this palette too (emoji-picker/styles.mjs);
|
|
17
|
+
// emoji-picker/support.mjs keeps notion-lite's --c-* variables only for the media menu and the image's
|
|
18
|
+
// alignment bar.
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* The one look of a button the editor draws on a page (the Agent changes' bar, the conflict card and the lost
|
|
22
|
+
* texts' panel, the crop window, a list's number, the icon picker's upload, the media menu): rules in the
|
|
23
|
+
* palette's sheet, so that every document the editor draws in has them from the first paint and no style
|
|
24
|
+
* repeats them. `.ge-btn` is a text button (ui.mjs textButton): no line and no fill, a gray under the
|
|
25
|
+
* pointer and while the keys are on it, a deeper one pressed; `data-primary` the pale blue (add, confirm,
|
|
26
|
+
* save), with `data-danger` the pale red (a delete); `data-quiet` a small one for looking, not deciding
|
|
27
|
+
* (收起, 定位). `.disabled` and `aria-disabled` are how a button made of a div says it cannot be pressed.
|
|
28
|
+
* `.ge-icon-btn` is the look of an icon button standing alone (a 批注's marker and its delete): no fill under
|
|
29
|
+
* the pointer (the icon goes darker), a gray only while it is pressed. The tools of a bar (the format bar's,
|
|
30
|
+
* the link card's) and a menu's rows are gray under the pointer, as Notion's are. Text fields are not
|
|
31
|
+
* buttons: they keep their thin outline.
|
|
32
|
+
*/
|
|
33
|
+
const OFF = ":disabled, .disabled, [aria-disabled=\"true\"]";
|
|
34
|
+
export const BUTTONS = `
|
|
35
|
+
.ge-btn { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; height: 28px; margin: 0; padding: 0 10px; border: 0; border-radius: 6px; box-shadow: none; background: transparent; color: var(--ge-tx); font: inherit; font-weight: 500; line-height: 1; white-space: nowrap; cursor: pointer; user-select: none; transition: background 20ms ease-in; }
|
|
36
|
+
.ge-btn:is(:hover, :focus-visible):not(${OFF}) { outline: none; background: var(--ge-hover); }
|
|
37
|
+
.ge-btn:active:not(${OFF}) { background: var(--ge-press); }
|
|
38
|
+
.ge-btn[data-primary] { background: var(--ge-btn-primary); color: var(--ge-btn-primary-text); }
|
|
39
|
+
.ge-btn[data-primary]:is(:hover, :focus-visible):not(${OFF}) { background: var(--ge-btn-primary-hover); }
|
|
40
|
+
.ge-btn[data-primary]:active:not(${OFF}) { background: var(--ge-btn-primary-press); }
|
|
41
|
+
.ge-btn[data-primary][data-danger] { background: var(--ge-btn-danger); color: var(--ge-btn-danger-text); }
|
|
42
|
+
.ge-btn[data-primary][data-danger]:is(:hover, :focus-visible):not(${OFF}) { background: var(--ge-btn-danger-hover); }
|
|
43
|
+
.ge-btn[data-primary][data-danger]:active:not(${OFF}) { background: var(--ge-btn-danger-press); }
|
|
44
|
+
.ge-btn[data-quiet] { height: 24px; padding: 0 6px; color: var(--ge-tx2); font-weight: 400; }
|
|
45
|
+
.ge-btn[data-quiet]:is(:hover, :focus-visible):not(${OFF}) { color: var(--ge-tx); }
|
|
46
|
+
.ge-btn:is(${OFF}) { opacity: .45; cursor: default; }
|
|
47
|
+
.ge-icon-btn { border: 0; box-shadow: none; background: transparent; cursor: pointer; transition: background 20ms ease-in, color 20ms ease-in; }
|
|
48
|
+
.ge-icon-btn:hover:not(:disabled) { color: var(--ge-ico); }
|
|
49
|
+
.ge-icon-btn:active:not(:disabled) { background: var(--ge-press); }
|
|
50
|
+
`;
|
|
16
51
|
|
|
17
52
|
export const TOKENS = `
|
|
18
53
|
:root {
|
|
19
54
|
--ge-tx: light-dark(#2c2c2b, #f0efed);
|
|
20
55
|
--ge-tx2: light-dark(#7d7a75, #ada9a3);
|
|
21
56
|
--ge-tx3: light-dark(#a19e99, #7d7a75);
|
|
22
|
-
--
|
|
57
|
+
/* The workbench's --icoPri (FinHarness-Demo's --ink-2). */
|
|
58
|
+
--ge-ico: light-dark(#5c5a55, #a9a69e);
|
|
23
59
|
--ge-ico2: light-dark(#8e8b86, #ada9a3);
|
|
24
60
|
/* The quietest icon gray (notion-lite's --c-icoTer): the block handle's dots, its bar and its +. */
|
|
25
61
|
--ge-ico3: light-dark(#ada9a3, #7d7a75);
|
|
@@ -38,6 +74,17 @@ export const TOKENS = `
|
|
|
38
74
|
--ge-focus: #2383e2;
|
|
39
75
|
--ge-red: light-dark(#eb5757, #ff6b6b);
|
|
40
76
|
--ge-quote: light-dark(rgb(28 19 1 / 16%), rgb(255 255 235 / 16%));
|
|
77
|
+
/* Buttons (BUTTONS below; the user's rule, restated 2026-11-09): a primary is a pale blue fill, always shown, its words the
|
|
78
|
+
deeper blue; a primary that cannot be taken back a pale red; every other button has no fill and no line, a gray under
|
|
79
|
+
the pointer (--ge-hover) and a deeper one pressed (--ge-press). The workbench's own values (--btnPriBg, --btnDanBg: tokens.css). */
|
|
80
|
+
--ge-btn-primary: light-dark(rgb(35 131 226 / 14%), rgb(67 155 255 / 24%));
|
|
81
|
+
--ge-btn-primary-hover: light-dark(rgb(35 131 226 / 22%), rgb(67 155 255 / 34%));
|
|
82
|
+
--ge-btn-primary-press: light-dark(rgb(35 131 226 / 30%), rgb(67 155 255 / 44%));
|
|
83
|
+
--ge-btn-primary-text: light-dark(#1a69bd, #7ab8ff);
|
|
84
|
+
--ge-btn-danger: light-dark(rgb(235 87 87 / 14%), rgb(255 104 92 / 24%));
|
|
85
|
+
--ge-btn-danger-hover: light-dark(rgb(235 87 87 / 22%), rgb(255 104 92 / 34%));
|
|
86
|
+
--ge-btn-danger-press: light-dark(rgb(235 87 87 / 30%), rgb(255 104 92 / 44%));
|
|
87
|
+
--ge-btn-danger-text: light-dark(#c4403c, #ff9a90);
|
|
41
88
|
--ge-fill: light-dark(rgb(35 131 226 / 14%), rgb(35 131 226 / 28%));
|
|
42
89
|
--ge-halo: rgb(35 131 226 / 14%);
|
|
43
90
|
--ge-select: light-dark(rgb(35 131 226 / 28%), rgb(35 131 226 / 45%));
|
|
@@ -53,6 +100,11 @@ export const TOKENS = `
|
|
|
53
100
|
--ge-toast-bg: light-dark(#0f0f0f, #2f2f2f);
|
|
54
101
|
/* The quiet gray a heading is lit with for a moment when the outline goes to it (outline/), never a blue. */
|
|
55
102
|
--ge-outline-flash: light-dark(rgb(33 27 23 / 7%), rgb(255 255 255 / 8%));
|
|
103
|
+
/* The lines a size is dragged by (resize/, columns/), grays like Notion's column resizer (its border.primaryTranslucent), never a
|
|
104
|
+
bright blue (the user, 2026-11-07): where a drag may start, the line being dragged, and that line where it snaps. */
|
|
105
|
+
--ge-guide: light-dark(rgb(55 53 47 / 16%), rgb(255 255 255 / 14%));
|
|
106
|
+
--ge-guide-hot: light-dark(rgb(55 53 47 / 36%), rgb(255 255 255 / 32%));
|
|
107
|
+
--ge-guide-snap: light-dark(rgb(55 53 47 / 62%), rgb(255 255 255 / 58%));
|
|
56
108
|
/* 批注 (annotate/): a warm mark on the words an annotation is about, its 2px underline leading (a faint fill, so it is never
|
|
57
109
|
taken for the report's own yellow background), a block anchor's bar; stronger for the one shown. */
|
|
58
110
|
--ge-note: light-dark(rgb(255 212 0 / 6%), rgb(255 212 0 / 6%));
|
|
@@ -61,5 +113,16 @@ export const TOKENS = `
|
|
|
61
113
|
--ge-note-hot-line: light-dark(rgb(222 160 0 / 90%), rgb(255 204 64 / 80%));
|
|
62
114
|
/* A card of 批注 in the margin under the pointer (notion-lite's --c-hovMarDisBac): a shade of the page. */
|
|
63
115
|
--ge-note-shade: light-dark(#f9f9f8, #202020);
|
|
116
|
+
/* The Agent's changes (changes/, 设置 › 显示变更): Notion's green and red backgrounds, the conflict card's two versions (conflicts.mjs);
|
|
117
|
+
words added get a 批注's look (a faint fill under a 2px underline) in green, blocks a fainter fill; words
|
|
118
|
+
taken out stand in red struck through on the red, deleted blocks' ghost on a fainter red. */
|
|
119
|
+
--ge-diff-add: light-dark(rgb(0 100 45 / 9%), rgb(108 255 172 / 15.7%));
|
|
120
|
+
--ge-diff-add-line: light-dark(rgb(68 131 97 / 60%), rgb(111 197 150 / 55%));
|
|
121
|
+
--ge-diff-add-fill: light-dark(rgb(0 100 45 / 5.5%), rgb(108 255 172 / 9%));
|
|
122
|
+
--ge-diff-add-text: light-dark(#448361, #6fc596);
|
|
123
|
+
--ge-diff-del: light-dark(rgb(223 22 0 / 9.4%), rgb(255 104 92 / 24%));
|
|
124
|
+
--ge-diff-del-fill: light-dark(rgb(223 22 0 / 4.5%), rgb(255 104 92 / 10%));
|
|
125
|
+
--ge-diff-del-text: light-dark(#cf5148, #ff8f85);
|
|
64
126
|
}
|
|
127
|
+
${BUTTONS}
|
|
65
128
|
`;
|