@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
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { IN_LAYER } from "../../../shared/layers.mjs";
|
|
2
|
+
import { FOLD_ARROW } from "../../../shared/code-folds.mjs";
|
|
3
|
+
import { t } from "../../../shared/i18n/index.mjs";
|
|
4
|
+
import { ELEMENT_ID, UNIT, identityOf, unitsOf, withLeads } from "../core.mjs";
|
|
5
|
+
import { caretAt } from "../caret.mjs";
|
|
6
|
+
import { HEADING } from "../outline/read.mjs";
|
|
7
|
+
import { foldsOf, keepFolds } from "../outline/folds.mjs";
|
|
8
|
+
import { drawAt, shapeOf } from "../overlay-layer.mjs";
|
|
9
|
+
import { own } from "../overlays.mjs";
|
|
10
|
+
import { local } from "../storage.mjs";
|
|
11
|
+
import { shortcut, tooltip } from "../tooltip.mjs";
|
|
12
|
+
import { addStyle, element } from "../ui.mjs";
|
|
13
|
+
import { FOLDED, hiddenByFold, setFoldOpener } from "../folded.mjs";
|
|
14
|
+
import { foldable, headingOf, keyOf, sectionAfter, stepOver, takenWith } from "./rule.mjs";
|
|
15
|
+
|
|
16
|
+
// Folding a heading's section (docs/editor.md, "Folding a heading's section"): a small rounded triangle
|
|
17
|
+
// a gap right of a heading's last line, shown while the pointer is at the heading (always while it is
|
|
18
|
+
// folded), folds what the heading's section is (rule.mjs: the outline's nesting, in its box) out of
|
|
19
|
+
// sight; Ctrl/⌘+Enter in its words does the same (components/heading/page.mjs). A fold is the reader's
|
|
20
|
+
// view, never the file's: no undo step, no commit; kept per report in the browser
|
|
21
|
+
// (gallery-edit:heading-folds, as the outline's folds are), so the page shown again after an Agent's
|
|
22
|
+
// write folds what was folded. While the page lives, what is folded is the headings' identities
|
|
23
|
+
// (data-ge-id: a heading turned into another level, or put back by undo, stays folded); what a fold
|
|
24
|
+
// hides is marked data-ge-folded (the outermost folded heading's identity), shown as nothing.
|
|
25
|
+
//
|
|
26
|
+
// What asks it: the block tools (blocks.mjs) draw the triangles each frame (place, beside the handle:
|
|
27
|
+
// handle.pointed), and take a folded heading's section with it wherever blocks are taken away whole
|
|
28
|
+
// (takenWith: drag/, selection/delete.mjs, clipboard/, block-menu/'s 组成新分区; groupsOf and
|
|
29
|
+
// stepOver: drag/ moveBy; withHidden: a row of columns made around it, columns/ and drag/);
|
|
30
|
+
// selection/ keeps what is hidden out of the selection; typing/ opens a fold before Backspace or
|
|
31
|
+
// Delete would join hidden words; editor.mjs opens the folds around the caret, and
|
|
32
|
+
// every path that opens what hides a block goes through reveal() (page/folded.mjs). One rule opens a fold
|
|
33
|
+
// of itself: a block a change of the page puts into a folded section (or one that was in sight and is not
|
|
34
|
+
// now) opens it, unless the block came onto the page with its heading in that same change (undo
|
|
35
|
+
// putting a folded section back, a folded section dragged).
|
|
36
|
+
|
|
37
|
+
const STORE = "gallery-edit:heading-folds";
|
|
38
|
+
// The button is what a press finds, drawn as nothing but its triangle; 16px (it was 20, filled under the
|
|
39
|
+
// pointer: the user's, 2026-11-07), its triangle's middle 14px past the words as before.
|
|
40
|
+
const SIZE = 16;
|
|
41
|
+
const GAP = 6; // from the end of the heading's last line to the button
|
|
42
|
+
// A press held that began off the triangles (words being selected, a box drawn, a block dragged): the
|
|
43
|
+
// triangles take no pointer until it ends. Under the pointer one stood for the place of the drag: the
|
|
44
|
+
// browser, finding a node outside the heading's editable text, put the selection's moving end at the
|
|
45
|
+
// heading's start (the whole heading selected while the pointer crossed the triangle, the user's
|
|
46
|
+
// 2026-11-07 第 6 条), and it darkened as if it were to be pressed.
|
|
47
|
+
const HELD = "data-ge-fold-held";
|
|
48
|
+
// What a fold hides is display: none !important: none of it shows, whatever display its blocks have
|
|
49
|
+
// of their own (a row of columns' grid, a card's flex, a rule of the report's own).
|
|
50
|
+
const STYLE = `
|
|
51
|
+
[data-ge-editing] [${FOLDED}] { display: none !important; }
|
|
52
|
+
.ge-fold { position: absolute; left: 0; top: 0; z-index: ${IN_LAYER.button}; box-sizing: border-box; display: flex; align-items: center; justify-content: center; width: ${SIZE}px; height: ${SIZE}px; border-radius: 4px; color: var(--ge-ico3); cursor: pointer; pointer-events: auto; user-select: none; }
|
|
53
|
+
html[${HELD}] .ge-fold { pointer-events: none; }
|
|
54
|
+
/* No fill under the pointer, the triangle darker (as the outline's), a short one while pressed (as a code block's arrow). */
|
|
55
|
+
.ge-fold:hover { color: var(--ge-ico2); }
|
|
56
|
+
.ge-fold:active { background: var(--ge-press); }
|
|
57
|
+
/* Open it points down; folded, left, at the heading's words (it stands right of them), turned clockwise. */
|
|
58
|
+
.ge-fold svg { display: block; width: 12px; height: 12px; fill: currentColor; transition: transform .2s ease-out; }
|
|
59
|
+
.ge-fold[aria-expanded="false"] svg { transform: rotate(90deg); }
|
|
60
|
+
@media (prefers-reduced-motion: reduce) { .ge-fold svg { transition: none; } }
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
/** Where a heading's button stands (window coordinates): 6px right of its last line's end, on that line's middle; null where it shows no words. */
|
|
64
|
+
export function foldRectOf(heading) {
|
|
65
|
+
const range = document.createRange();
|
|
66
|
+
range.selectNodeContents(heading);
|
|
67
|
+
const end = [...range.getClientRects()].filter((rect) => rect.width > 0 && rect.height > 0).at(-1);
|
|
68
|
+
if (!end) return null;
|
|
69
|
+
const left = end.right + GAP;
|
|
70
|
+
const top = (end.top + end.bottom) / 2 - SIZE / 2;
|
|
71
|
+
return { left, top, right: left + SIZE, bottom: top + SIZE };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* slug: the report's. selection: selection/index.mjs (what is hidden leaves it). active(): whether
|
|
76
|
+
* the block tools may show. schedule(): the block tools' next frame.
|
|
77
|
+
*/
|
|
78
|
+
export function createFolds({ slug, selection, active, schedule }) {
|
|
79
|
+
addStyle(STYLE);
|
|
80
|
+
const folded = new Set(); // the identities of the headings folded
|
|
81
|
+
let heads = []; // the folded headings on the page at the last apply, in document order
|
|
82
|
+
let hidden = new Set(); // the units hidden at the last apply
|
|
83
|
+
let started = false;
|
|
84
|
+
let observer = null;
|
|
85
|
+
const buttons = new Map(); // heading -> its button
|
|
86
|
+
const holds = (node) => [...buttons.values()].some((button) => button.contains(node));
|
|
87
|
+
|
|
88
|
+
const main = () => document.querySelector("main");
|
|
89
|
+
const idOf = (node) => node?.getAttribute?.(ELEMENT_ID) ?? null;
|
|
90
|
+
const isFolded = (node) => node?.nodeType === 1 && folded.has(idOf(node)) && foldable(node);
|
|
91
|
+
const headings = () => [...(main()?.querySelectorAll(HEADING) ?? [])].filter(foldable);
|
|
92
|
+
// The units a folded heading hides (with those of folds inside it): those of its box marked with it.
|
|
93
|
+
const hiddenBy = (heading) => (heading.parentElement ? unitsOf(heading.parentElement).filter((unit) => unit.getAttribute(FOLDED) === idOf(heading)) : []);
|
|
94
|
+
|
|
95
|
+
function load() {
|
|
96
|
+
const keys = foldsOf(local, slug, STORE);
|
|
97
|
+
if (keys.size === 0) return;
|
|
98
|
+
const all = headings();
|
|
99
|
+
for (const key of keys) {
|
|
100
|
+
const heading = headingOf(key, all);
|
|
101
|
+
if (heading) folded.add(identityOf(heading));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// What is folded, kept by the keys the headings have now (only those still on the page).
|
|
106
|
+
function save() {
|
|
107
|
+
if (!started) return;
|
|
108
|
+
const all = headings();
|
|
109
|
+
keepFolds(local, slug, new Set(all.filter((heading) => folded.has(idOf(heading))).map((heading) => keyOf(heading, all))), null, STORE);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// What each folded heading hides now: unit -> the outermost folded heading over it. A folded heading
|
|
113
|
+
// with no words is folded no more; one hidden by a fold around it starts no section of its own.
|
|
114
|
+
function wanted(root) {
|
|
115
|
+
const want = new Map();
|
|
116
|
+
const found = [];
|
|
117
|
+
for (const heading of root.querySelectorAll(HEADING)) {
|
|
118
|
+
const id = idOf(heading);
|
|
119
|
+
if (!folded.has(id)) continue;
|
|
120
|
+
if (!foldable(heading)) {
|
|
121
|
+
folded.delete(id);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
found.push(heading);
|
|
125
|
+
let under = false;
|
|
126
|
+
for (let node = heading; node && node !== root && !under; node = node.parentElement) under = want.has(node);
|
|
127
|
+
if (under) continue;
|
|
128
|
+
for (const unit of sectionAfter(heading)) want.set(unit, heading);
|
|
129
|
+
}
|
|
130
|
+
return { want, found };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* The marks set again as the folds are now. `added`: the elements a change of the page put in (null:
|
|
135
|
+
* a fold toggled, or the page begun), for the rule that opens a fold: a unit hidden now that was not
|
|
136
|
+
* opens the folds over it, unless it came in with its heading.
|
|
137
|
+
*/
|
|
138
|
+
function apply({ added = null } = {}) {
|
|
139
|
+
const root = main();
|
|
140
|
+
if (!root) return;
|
|
141
|
+
const within = (node) => {
|
|
142
|
+
for (let at = node; at && at !== root; at = at.parentElement) if (added.has(at)) return true;
|
|
143
|
+
return false;
|
|
144
|
+
};
|
|
145
|
+
const count = folded.size;
|
|
146
|
+
let result;
|
|
147
|
+
for (let round = 0; round < 16; round++) {
|
|
148
|
+
result = wanted(root);
|
|
149
|
+
if (added === null) break;
|
|
150
|
+
const opened = new Set();
|
|
151
|
+
for (const [unit, heading] of result.want) {
|
|
152
|
+
if (!hidden.has(unit) && !(within(unit) && within(heading))) opened.add(heading);
|
|
153
|
+
}
|
|
154
|
+
if (opened.size === 0) break;
|
|
155
|
+
for (const heading of opened) folded.delete(idOf(heading));
|
|
156
|
+
}
|
|
157
|
+
const marks = new Map();
|
|
158
|
+
for (const [unit, heading] of result.want) for (const part of withLeads(unit)) marks.set(part, idOf(heading));
|
|
159
|
+
for (const node of root.querySelectorAll(`[${FOLDED}]`)) if (!marks.has(node)) node.removeAttribute(FOLDED);
|
|
160
|
+
for (const [node, id] of marks) if (node.getAttribute(FOLDED) !== id) node.setAttribute(FOLDED, id);
|
|
161
|
+
heads = result.found;
|
|
162
|
+
hidden = new Set(result.want.keys());
|
|
163
|
+
if (added !== null && folded.size !== count) save(); // a fold opened of itself
|
|
164
|
+
schedule();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// A change of the page: blocks put in or taken out (a container's children, or a node that is or
|
|
168
|
+
// holds a block) apply the folds again; words typed in a heading too (emptied, its fold opens; a
|
|
169
|
+
// heading in a box may now end a section). Words typed elsewhere are nothing to it.
|
|
170
|
+
function changed(records) {
|
|
171
|
+
if (folded.size === 0 && hidden.size === 0) return;
|
|
172
|
+
const added = new Set();
|
|
173
|
+
let again = false;
|
|
174
|
+
for (const record of records) {
|
|
175
|
+
const target = record.target.nodeType === 1 ? record.target : record.target.parentElement;
|
|
176
|
+
if (target?.closest?.(HEADING)) again = true;
|
|
177
|
+
if (record.type !== "childList") continue;
|
|
178
|
+
if (target?.hasAttribute?.("data-ge-box")) again = true;
|
|
179
|
+
for (const node of record.addedNodes) {
|
|
180
|
+
if (node.nodeType !== 1) continue;
|
|
181
|
+
added.add(node);
|
|
182
|
+
if (!again && (node.matches(UNIT) || node.querySelector(UNIT))) again = true;
|
|
183
|
+
}
|
|
184
|
+
if (!again) for (const node of record.removedNodes) if (node.nodeType === 1 && (node.matches(UNIT) || node.querySelector(UNIT))) again = true;
|
|
185
|
+
}
|
|
186
|
+
if (again) apply({ added });
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// The caret, or an end of a text selection, in what a fold now hides goes to the end of its heading;
|
|
190
|
+
// what is selected of it leaves the selection.
|
|
191
|
+
function stepOut(heading) {
|
|
192
|
+
const picked = selection.picked;
|
|
193
|
+
const kept = picked.filter((node) => !hiddenByFold(node));
|
|
194
|
+
if (kept.length !== picked.length) {
|
|
195
|
+
if (kept.length) selection.select(kept, { quiet: true });
|
|
196
|
+
else selection.clear();
|
|
197
|
+
}
|
|
198
|
+
const text = getSelection();
|
|
199
|
+
if (text?.rangeCount && (hiddenByFold(text.anchorNode) || hiddenByFold(text.focusNode))) caretAt(heading, "end");
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Fold or unfold a heading's section. Whether it is one that folds. */
|
|
203
|
+
function toggle(heading) {
|
|
204
|
+
if (!started || !foldable(heading)) return false;
|
|
205
|
+
const id = identityOf(heading);
|
|
206
|
+
if (!folded.delete(id)) folded.add(id);
|
|
207
|
+
apply();
|
|
208
|
+
if (folded.has(id)) stepOut(heading);
|
|
209
|
+
save();
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/** The folds over `node` opened, outermost first, until it shows. Whether any was. */
|
|
214
|
+
function showAround(node) {
|
|
215
|
+
let opened = false;
|
|
216
|
+
for (let round = 0; round < 16 && hiddenByFold(node); round++) {
|
|
217
|
+
const marked = (node.nodeType === 1 ? node : node.parentElement).closest(`[${FOLDED}]`);
|
|
218
|
+
if (!folded.delete(marked.getAttribute(FOLDED))) marked.removeAttribute(FOLDED); // no fold of this page's
|
|
219
|
+
opened = true;
|
|
220
|
+
apply();
|
|
221
|
+
}
|
|
222
|
+
if (opened) save();
|
|
223
|
+
return opened;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ---------- the buttons ----------
|
|
227
|
+
|
|
228
|
+
// A press held that began off the triangles (HELD): set on the window before any tool sees the
|
|
229
|
+
// press, gone with the press (let go, cancelled, the window left, or a move with no button down
|
|
230
|
+
// where its end was missed). The triangles shown stay shown, as the handle's block stays while a
|
|
231
|
+
// button is down (handle/ onMove), and take the pointer again once it is let go.
|
|
232
|
+
let held = false;
|
|
233
|
+
const hold = (on) => {
|
|
234
|
+
if (held === on) return;
|
|
235
|
+
held = on;
|
|
236
|
+
document.documentElement.toggleAttribute(HELD, on);
|
|
237
|
+
};
|
|
238
|
+
addEventListener("pointerdown", (event) => hold(!holds(event.target)), true);
|
|
239
|
+
for (const type of ["pointerup", "pointercancel"]) addEventListener(type, () => hold(false), true);
|
|
240
|
+
addEventListener("blur", () => hold(false));
|
|
241
|
+
addEventListener("pointermove", (event) => { if (held && event.buttons === 0) hold(false); }, { capture: true, passive: true });
|
|
242
|
+
|
|
243
|
+
function make(heading) {
|
|
244
|
+
const node = element("div", { class: "ge-fold", role: "button", html: FOLD_ARROW });
|
|
245
|
+
tooltip(node, () => (isFolded(heading) ? t("展开") : t("折叠")), shortcut("mod+enter"));
|
|
246
|
+
// No caret moves, no box selection starts, the focus stays (blocks.mjs passes presses on it by).
|
|
247
|
+
node.addEventListener("pointerdown", (event) => event.preventDefault());
|
|
248
|
+
node.addEventListener("click", (event) => {
|
|
249
|
+
event.preventDefault();
|
|
250
|
+
toggle(heading);
|
|
251
|
+
});
|
|
252
|
+
own(node, "heading fold", { owner: heading, alive: () => buttons.get(heading) === node && heading.isConnected && started && active(), expected: () => foldRectOf(heading) });
|
|
253
|
+
return node;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function drop(heading) {
|
|
257
|
+
buttons.get(heading)?.remove();
|
|
258
|
+
buttons.delete(heading);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/** A frame: a button by each folded heading in sight, and by the heading the pointer is at (`pointed`). */
|
|
262
|
+
function place(pointed) {
|
|
263
|
+
const want = new Set(started ? heads.filter((heading) => heading.isConnected && isFolded(heading)) : []);
|
|
264
|
+
if (started && pointed && foldable(pointed) && !hiddenByFold(pointed)) want.add(pointed);
|
|
265
|
+
for (const heading of [...buttons.keys()]) if (!want.has(heading)) drop(heading);
|
|
266
|
+
for (const heading of want) {
|
|
267
|
+
const shape = shapeOf(heading);
|
|
268
|
+
const rect = shape && foldRectOf(heading);
|
|
269
|
+
if (!rect) {
|
|
270
|
+
drop(heading);
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
let node = buttons.get(heading);
|
|
274
|
+
if (!node) {
|
|
275
|
+
node = make(heading);
|
|
276
|
+
buttons.set(heading, node);
|
|
277
|
+
}
|
|
278
|
+
const open = !isFolded(heading);
|
|
279
|
+
if (node.getAttribute("aria-expanded") !== String(open)) {
|
|
280
|
+
node.setAttribute("aria-expanded", String(open));
|
|
281
|
+
node.setAttribute("aria-label", open ? t("折叠") : t("展开"));
|
|
282
|
+
}
|
|
283
|
+
drawAt(node, shape.layer, rect.left - shape.origin.left, rect.top - shape.origin.top);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function hide() {
|
|
288
|
+
for (const heading of [...buttons.keys()]) drop(heading);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
const folds = {
|
|
292
|
+
/** Editing begins: what was folded folded again, in the task editing begins in (no frame shows it open). */
|
|
293
|
+
start() {
|
|
294
|
+
if (started) return;
|
|
295
|
+
started = true;
|
|
296
|
+
setFoldOpener(showAround);
|
|
297
|
+
load();
|
|
298
|
+
apply();
|
|
299
|
+
observer = new MutationObserver(changed);
|
|
300
|
+
const root = main();
|
|
301
|
+
if (root) observer.observe(root, { childList: true, subtree: true, characterData: true });
|
|
302
|
+
addEventListener("pagehide", save);
|
|
303
|
+
},
|
|
304
|
+
/** Editing ends: every fold shown open (what is folded is kept). */
|
|
305
|
+
stop() {
|
|
306
|
+
if (!started) return;
|
|
307
|
+
save();
|
|
308
|
+
started = false;
|
|
309
|
+
observer?.disconnect();
|
|
310
|
+
for (const node of document.querySelectorAll(`[${FOLDED}]`)) node.removeAttribute(FOLDED);
|
|
311
|
+
heads = [];
|
|
312
|
+
hidden = new Set();
|
|
313
|
+
hide();
|
|
314
|
+
},
|
|
315
|
+
place,
|
|
316
|
+
hide,
|
|
317
|
+
/** A button shows (the frames go on following the headings). */
|
|
318
|
+
get showing() { return buttons.size > 0; },
|
|
319
|
+
holds,
|
|
320
|
+
toggle,
|
|
321
|
+
isFolded,
|
|
322
|
+
hidden: hiddenByFold,
|
|
323
|
+
showAround,
|
|
324
|
+
/** `units` with what each folded heading among them hides (a section it covers whole instead): rule.mjs takenWith. */
|
|
325
|
+
takenWith: (units) => takenWith(units, { isFolded, hiddenBy }),
|
|
326
|
+
/** A block with what it hides (a folded heading's section, folds inside it too), in document order: what goes into a column with it (columns/ split, drag/ besideTo). */
|
|
327
|
+
withHidden: (unit) => (isFolded(unit) ? [unit, ...hiddenBy(unit)] : [unit]),
|
|
328
|
+
/** The last block of a block and what it hides (a folded heading's last hidden block), for a place after it. */
|
|
329
|
+
lastOf: (unit) => (isFolded(unit) ? hiddenBy(unit).at(-1) ?? unit : unit),
|
|
330
|
+
/** The blocks of `list` as the reader sees them: each shown block, a folded heading with what it hides. */
|
|
331
|
+
groupsOf(list) {
|
|
332
|
+
const groups = [];
|
|
333
|
+
for (const unit of list) {
|
|
334
|
+
if (unit.hasAttribute(FOLDED) && groups.length > 0) groups.at(-1).push(unit);
|
|
335
|
+
else groups.push([unit]);
|
|
336
|
+
}
|
|
337
|
+
return groups;
|
|
338
|
+
},
|
|
339
|
+
/** Where Ctrl+Shift+↑/↓ takes a folded heading (rule.mjs stepOver). */
|
|
340
|
+
stepOver,
|
|
341
|
+
/** What the status line calls `targets` taken for `picked` (named: block-info.mjs's): 标题和折叠的 N 块. */
|
|
342
|
+
namedWith(picked, targets, named) {
|
|
343
|
+
const extra = targets.length - picked.length;
|
|
344
|
+
return extra > 0 && picked.every((node) => targets.includes(node)) ? t("{0}和折叠的 {1} 块", named(picked), extra) : named(targets);
|
|
345
|
+
},
|
|
346
|
+
};
|
|
347
|
+
return folds;
|
|
348
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { HEADING, LEFT_OUT, headingText } from "../outline/read.mjs";
|
|
2
|
+
import { UNIT, unitsOf } from "../core.mjs";
|
|
3
|
+
import { CHAPTER, LEADS_CHAPTER } from "../../components/registry.mjs";
|
|
4
|
+
import { FOLDED } from "../folded.mjs";
|
|
5
|
+
|
|
6
|
+
// What folding a heading's section takes (docs/editor.md, "Folding a heading's section"), pure so the
|
|
7
|
+
// unit tests hold it (tests/unit/heading-folds.mjs); the tool that folds is index.mjs. A heading the
|
|
8
|
+
// outline lists, standing straight in a box, folds what follows it in that box up to the first block
|
|
9
|
+
// that ends it: a heading of its level or higher, or a block holding one the outline lists (a section,
|
|
10
|
+
// a tabs area, a row of columns, a disclosure, a highlight block…), the outline's rule of what nests
|
|
11
|
+
// under a heading (outline/tree.mjs treeOf), so the fold and the outline say the same of a section.
|
|
12
|
+
|
|
13
|
+
export { FOLDED };
|
|
14
|
+
|
|
15
|
+
/** A heading's level, 1-4. */
|
|
16
|
+
export const levelOf = (heading) => Number(heading.localName[1]);
|
|
17
|
+
|
|
18
|
+
const kindOf = (node) => node.getAttribute("data-ge-unit-kind");
|
|
19
|
+
|
|
20
|
+
/** Whether a node is a heading that folds: one the outline lists, standing straight in a box, with words. */
|
|
21
|
+
export function foldable(node) {
|
|
22
|
+
return node?.nodeType === 1 && node.matches(HEADING) && node.matches(UNIT) && !node.closest(LEFT_OUT)
|
|
23
|
+
&& Boolean(node.parentElement?.hasAttribute("data-ge-box")) && headingText(node) !== "";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** Whether `unit` ends a section of level `level`: a heading of that level or higher, or a block holding one the outline lists. */
|
|
27
|
+
export function ends(unit, level) {
|
|
28
|
+
if (unit.matches(HEADING)) return levelOf(unit) <= level;
|
|
29
|
+
for (const heading of unit.querySelectorAll(HEADING)) {
|
|
30
|
+
if (levelOf(heading) <= level && !heading.closest(LEFT_OUT) && headingText(heading) !== "") return true;
|
|
31
|
+
}
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** The units after `heading` in its box that are its section (at `level`, its own by default), the one ending it not among them. */
|
|
36
|
+
export function sectionAfter(heading, level = levelOf(heading)) {
|
|
37
|
+
const box = heading.parentElement;
|
|
38
|
+
if (!box) return [];
|
|
39
|
+
const out = [];
|
|
40
|
+
let past = false;
|
|
41
|
+
for (const unit of unitsOf(box)) {
|
|
42
|
+
if (!past) {
|
|
43
|
+
past = unit === heading;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (ends(unit, level)) break;
|
|
47
|
+
out.push(unit);
|
|
48
|
+
}
|
|
49
|
+
return out;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Nodes in document order, each once, none inside another. */
|
|
53
|
+
export function inOrder(nodes) {
|
|
54
|
+
const set = [...new Set(nodes)];
|
|
55
|
+
return set.filter((node) => !set.some((other) => other !== node && other.contains(node)))
|
|
56
|
+
.sort((a, b) => (a.compareDocumentPosition(b) & 4 ? -1 : 1)); // 4: DOCUMENT_POSITION_FOLLOWING
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* What an operation that takes blocks away whole takes for `units`: each folded heading with what it
|
|
61
|
+
* hides (isFolded(heading), hiddenBy(heading): the units its fold hides, those of folds inside it too),
|
|
62
|
+
* in document order. A folded heading whose box is a chapter (a section) of which it and what it hides
|
|
63
|
+
* are every unit, but for dividers before it, stands for that section: the section is taken.
|
|
64
|
+
*/
|
|
65
|
+
export function takenWith(units, { isFolded, hiddenBy }) {
|
|
66
|
+
const out = [];
|
|
67
|
+
for (const unit of units) {
|
|
68
|
+
out.push(unit);
|
|
69
|
+
if (isFolded(unit)) out.push(...hiddenBy(unit));
|
|
70
|
+
}
|
|
71
|
+
for (const unit of [...out]) {
|
|
72
|
+
const box = unit.parentElement;
|
|
73
|
+
if (!isFolded(unit) || !box?.matches(UNIT) || !CHAPTER.has(kindOf(box))) continue;
|
|
74
|
+
const covered = new Set([unit, ...hiddenBy(unit)]);
|
|
75
|
+
const all = unitsOf(box);
|
|
76
|
+
const at = all.indexOf(unit);
|
|
77
|
+
if (all.every((each, index) => covered.has(each) || (index < at && LEADS_CHAPTER.has(kindOf(each))))) out.push(box);
|
|
78
|
+
}
|
|
79
|
+
return inOrder(out);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Where Ctrl+Shift+↑/↓ takes a folded heading (its section with it): past the next section of its
|
|
84
|
+
* level going down (the block after what it hides, which ends it, and what follows that up to the
|
|
85
|
+
* next block ending a section of its level), past the one before going up (back to the block ending a
|
|
86
|
+
* section of its level, or the box's first block, up to the block before it). `list`: the blocks it
|
|
87
|
+
* moves among, in order. { first, last } of what it goes past, or null where there is none.
|
|
88
|
+
*/
|
|
89
|
+
export function stepOver(heading, delta, list = unitsOf(heading.parentElement)) {
|
|
90
|
+
const level = levelOf(heading);
|
|
91
|
+
const at = list.indexOf(heading);
|
|
92
|
+
if (at < 0) return null;
|
|
93
|
+
if (delta > 0) {
|
|
94
|
+
const from = at + 1 + sectionAfter(heading).length;
|
|
95
|
+
if (from >= list.length) return null;
|
|
96
|
+
let to = from;
|
|
97
|
+
while (to + 1 < list.length && !ends(list[to + 1], level)) to++;
|
|
98
|
+
return { first: list[from], last: list[to] };
|
|
99
|
+
}
|
|
100
|
+
if (at === 0) return null;
|
|
101
|
+
let from = at - 1;
|
|
102
|
+
while (from > 0 && !ends(list[from], level)) from--;
|
|
103
|
+
return { first: list[from], last: list[at - 1] };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The key a folded heading is kept by: `b:<block id>`, or with none `t:<tag>:<words>#<n>`, n its place
|
|
108
|
+
* among the foldable headings of its tag and words (`all`, in document order; with an id or not).
|
|
109
|
+
*/
|
|
110
|
+
export function keyOf(heading, all) {
|
|
111
|
+
const id = heading.getAttribute("data-block-id");
|
|
112
|
+
if (id) return `b:${id}`;
|
|
113
|
+
const text = headingText(heading);
|
|
114
|
+
const same = all.filter((each) => each.localName === heading.localName && headingText(each) === text);
|
|
115
|
+
return `t:${heading.localName}:${text}#${Math.max(0, same.indexOf(heading))}`;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** The heading of `all` a key names (keyOf), or null: by its block id, or the n-th of its tag and words, with an id or not. */
|
|
119
|
+
export function headingOf(key, all) {
|
|
120
|
+
if (key.startsWith("b:")) return all.find((each) => each.getAttribute("data-block-id") === key.slice(2)) ?? null;
|
|
121
|
+
const match = /^t:(h[1-4]):([\s\S]*)#(\d+)$/.exec(key);
|
|
122
|
+
if (!match) return null;
|
|
123
|
+
const [, tag, text, n] = match;
|
|
124
|
+
return all.filter((each) => each.localName === tag && headingText(each) === text)[Number(n)] ?? null;
|
|
125
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// What the other tools ask of the headings' folds (fold/ folds a heading's section, docs/editor.md
|
|
2
|
+
// "Folding a heading's section"): the mark on what a fold hides, whether a node is hidden by one, and
|
|
3
|
+
// reveal(), what every path that brings a block into sight goes through (a link to a block, the
|
|
4
|
+
// outline, a 批注, a conflict's card): the folds over it opened, then what the kit opens.
|
|
5
|
+
|
|
6
|
+
/** What marks a unit (and its leads) a fold hides: the identity (data-ge-id) of the outermost heading folded over it. */
|
|
7
|
+
export const FOLDED = "data-ge-folded";
|
|
8
|
+
|
|
9
|
+
/** Whether a node (or the block it is in) is hidden by a fold. */
|
|
10
|
+
export const hiddenByFold = (node) => Boolean((node?.nodeType === 1 ? node : node?.parentElement)?.closest?.(`[${FOLDED}]`));
|
|
11
|
+
|
|
12
|
+
let opener = null; // the page's fold tool's showAround, once editing begins
|
|
13
|
+
|
|
14
|
+
/** The page's fold tool: what opens the folds over a node (fold/ showAround). */
|
|
15
|
+
export function setFoldOpener(open) {
|
|
16
|
+
opener = open;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** What hides `target` opened: the folds over it first, then what the kit opens (DocKit.reveal: a disclosure, a tab, a detail card). */
|
|
20
|
+
export function reveal(target) {
|
|
21
|
+
opener?.(target);
|
|
22
|
+
globalThis.DocKit?.reveal(target);
|
|
23
|
+
}
|
|
@@ -25,7 +25,8 @@ import { t } from "../../../shared/i18n/index.mjs";
|
|
|
25
25
|
// Esc and a press elsewhere. "更多" opens its list below it, resting on it or with a click. Resting
|
|
26
26
|
// on the type row opens what the block can be turned into beside the bar. The bar shows the
|
|
27
27
|
// selection's state and reports commands; the editor applies them (index.mjs). Swatches use the
|
|
28
|
-
// kit's own classes, so they match the text in either theme
|
|
28
|
+
// kit's own classes, so they match the text in either theme (a background's, a span, shows the
|
|
29
|
+
// words' fill; the cell bar draws its own as a block's: table/cell-bar.mjs). The icons are drawn here after Notion's
|
|
29
30
|
// look (20px, thin lines), not taken from Notion's files. The bar
|
|
30
31
|
// fades in (no fade out); its panels fade in and out quickly and keep inside the window.
|
|
31
32
|
|
|
@@ -319,7 +319,7 @@ export function createFormatting({ active, say, recordStep, struct, convert, cro
|
|
|
319
319
|
|
|
320
320
|
// The blocks of the selection across blocks turned into `type` together (one undo step), the
|
|
321
321
|
// selection drawn again over their text where it is now (notion-lite's placeCaret(keep)); blocks
|
|
322
|
-
// that hold no text of the body then (a
|
|
322
|
+
// that hold no text of the body then (a disclosure, code) are selected instead.
|
|
323
323
|
function turnAcross(type) {
|
|
324
324
|
const turn = crossTurn();
|
|
325
325
|
if (!turn) return;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UNIT, isEmpty, isHost, nestedBlocks, withLeads } from "./core.mjs";
|
|
2
|
-
import { boxRole, isBlock, isLead } from "../components/registry.mjs";
|
|
2
|
+
import { boxRole, endIsPadding, isBlock, isLead } from "../components/registry.mjs";
|
|
3
3
|
|
|
4
4
|
// Where the blocks are on the screen (docs/editor.md, "Selecting blocks"). measure() reads the
|
|
5
5
|
// page once into a tree of boxes and units with their rectangles. hoverAt, atHeight, measuredNode, pick,
|
|
@@ -11,7 +11,7 @@ import { boxRole, isBlock, isLead } from "../components/registry.mjs";
|
|
|
11
11
|
// of text blocks, the one a click there puts the caret into)
|
|
12
12
|
// pick the blocks a box selection takes: the ones it touches, lifted to one level
|
|
13
13
|
// endOf what a click below the last block of a box does: a new paragraph there, or the
|
|
14
|
-
// caret into the empty paragraph already at the end
|
|
14
|
+
// caret into the empty paragraph already at the end (none in a box whose end is its padding)
|
|
15
15
|
// innerBox the innermost box at a click's height, whose blocks are those beside it
|
|
16
16
|
//
|
|
17
17
|
// Where dragged blocks would go (resolveDrop) is drag/drop.mjs, from the same tree.
|
|
@@ -217,8 +217,8 @@ function boxesOf(el) {
|
|
|
217
217
|
return [...el.querySelectorAll("[data-ge-box]")].filter((box) => box.parentElement.closest(`${UNIT}, [data-ge-box]`) === el);
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
-
|
|
221
|
-
function contentOf(rect, style) {
|
|
220
|
+
/** A box's rect inside its padding and border (its text area: insert/ boxedBeside too). */
|
|
221
|
+
export function contentOf(rect, style) {
|
|
222
222
|
const inset = (side) => (parseFloat(style[`padding${side}`]) || 0) + (parseFloat(style[`border${side}Width`]) || 0);
|
|
223
223
|
return { left: rect.left + inset("Left"), top: rect.top + inset("Top"), right: rect.right - inset("Right"), bottom: rect.bottom - inset("Bottom") };
|
|
224
224
|
}
|
|
@@ -360,10 +360,12 @@ export function pick(tree, rect) {
|
|
|
360
360
|
* block, a flow or the page takes a new paragraph at its end ({ box, after }: after its last
|
|
361
361
|
* block, or at its start); when the last block, followed down through the flows it holds (a
|
|
362
362
|
* section's, a panel's, a disclosure's), is an empty paragraph, the caret goes there instead
|
|
363
|
-
* ({ focus }), so clicking again does not pile them up.
|
|
363
|
+
* ({ focus }), so clicking again does not pile them up. A box whose end is its own padding
|
|
364
|
+
* (endIsPadding: a highlight block, a disclosure's content) takes none: under its last block is a gap
|
|
365
|
+
* like any other (insert/ clickBlank). Anywhere else, null.
|
|
364
366
|
*/
|
|
365
367
|
export function endOf(box, y) {
|
|
366
|
-
if (!FLOWS.has(box.role)) return null;
|
|
368
|
+
if (!FLOWS.has(box.role) || endIsPadding(box.kind)) return null;
|
|
367
369
|
const last = box.children.at(-1) ?? null;
|
|
368
370
|
if (last && y <= last.rect.bottom) return null;
|
|
369
371
|
let deepest = last;
|
|
@@ -44,13 +44,12 @@ import { t } from "../../../shared/i18n/index.mjs";
|
|
|
44
44
|
// (lineAt, blocks.mjs). The handle and the bar are drawn in the editor's own layer (overlay-layer.mjs:
|
|
45
45
|
// the one of the block they stand beside), never inside a block, each belonging to the block it stands
|
|
46
46
|
// beside (overlays.mjs). A press ends when the pointer comes up, is cancelled, or the handle loses the
|
|
47
|
-
// pointer capture (then a drag under way is cancelled, never dropped).
|
|
47
|
+
// pointer capture (then a drag under way is cancelled, never dropped). On a page the editor edits, its
|
|
48
48
|
// side gutters (the kit's --doc-page-gutter, --doc-wide-gutter) are at least the room the
|
|
49
|
-
// handle takes left of a block, and a little (
|
|
50
|
-
//
|
|
51
|
-
// the right. A wide window, whose column
|
|
52
|
-
|
|
53
|
-
const EDGE = ADD.width + HANDLE.width + HANDLE.gap + 12; // the page's gutter while editing: the bar's square, the grip, its gap, and room to breathe (64)
|
|
49
|
+
// handle takes left of a block, and a little (margin.mjs MARGIN.edge, from the page's first paint: the
|
|
50
|
+
// head's MARGIN_STYLE): on a narrow window the handle stands in the margin, never over the text, as
|
|
51
|
+
// Feishu's and Notion's do; the section bar has the same room on the right. A wide window, whose column
|
|
52
|
+
// leaves more than that, does not change.
|
|
54
53
|
|
|
55
54
|
const STYLE = `
|
|
56
55
|
.ge-handle { position: absolute; left: 0; top: 0; z-index: ${IN_LAYER.handle}; display: flex; align-items: center; height: ${HANDLE.height}px; touch-action: none; }
|
|
@@ -84,8 +83,6 @@ const STYLE = `
|
|
|
84
83
|
.ge-section-bar::before { content: ""; position: absolute; top: 0; bottom: 0; left: 6px; width: 4px; border-radius: 2px; background: light-dark(rgb(55 53 47 / 14%), rgb(255 255 255 / 14%)); transition: background .08s ease-in; }
|
|
85
84
|
.ge-section-bar:hover::before { background: light-dark(rgb(55 53 47 / 28%), rgb(255 255 255 / 26%)); }
|
|
86
85
|
.ge-section-bar[data-active]::before { background: color-mix(in srgb, var(--doc-accent, #2678d8) 60%, transparent); }
|
|
87
|
-
/* Room for the handle beside the page's blocks: the page's gutters while editing (resize/ reads --ge-edge-room). */
|
|
88
|
-
:root[data-ge-editing] { --ge-edge-room: ${EDGE}px; --doc-page-gutter: var(--ge-edge-room); --doc-wide-gutter: var(--ge-edge-room); }
|
|
89
86
|
`;
|
|
90
87
|
|
|
91
88
|
// Notion's grip in size (its dragHandle icon at its icons' 20px): 2.5px dots 5px apart across and 6px down (notion-lite's were 5px down, the grip 2px shorter than Notion's: the user, 2026-10-26).
|
|
@@ -111,9 +108,11 @@ function emptyLine(host) {
|
|
|
111
108
|
* handle as it is, as those tools keep themselves. add(target, where): the "+" clicked, an empty
|
|
112
109
|
* block "below" the block (or "above" it: Alt) with the "/" menu open in it. notes: 批注 on blocks,
|
|
113
110
|
* notes.can(units) whether they can take one, notes.at(unit) where the button beside the block stands
|
|
114
|
-
* (window coordinates, null where it has none), notes.write(units) the annotation begun.
|
|
111
|
+
* (window coordinates, null where it has none), notes.write(units) the annotation begun. aside(node):
|
|
112
|
+
* a node over a block the 批注 button steps aside for while the pointer is on it (a heading's fold
|
|
113
|
+
* triangle, fold/, which may stand where the button would).
|
|
115
114
|
*/
|
|
116
|
-
export function createHandle({ info, active, selection, drag, menu, openMenu, drawing, schedule, keeps = () => false, add = () => {}, notes = { can: () => false, at: () => null, write: () => {} } }) {
|
|
115
|
+
export function createHandle({ info, active, selection, drag, menu, openMenu, drawing, schedule, keeps = () => false, aside = () => false, add = () => {}, notes = { can: () => false, at: () => null, write: () => {} } }) {
|
|
117
116
|
addStyle(STYLE);
|
|
118
117
|
const { kindOf, boxKindOf } = info;
|
|
119
118
|
const grip = element("div", { class: "ge-grip", role: "button", "aria-label": t("打开块菜单") });
|
|
@@ -133,7 +132,7 @@ export function createHandle({ info, active, selection, drag, menu, openMenu, dr
|
|
|
133
132
|
let barShown = null; // the section the bar stands beside
|
|
134
133
|
let shown = null; // the block the handle stands beside
|
|
135
134
|
let noted = null; // the block the 批注 button stands beside
|
|
136
|
-
let pointer = null; // { x, y }: where the pointer last moved over the page
|
|
135
|
+
let pointer = null; // { x, y, target }: where the pointer last moved over the page, and what it was on
|
|
137
136
|
let typing = false; // the handle hides while the reader types, until the pointer moves
|
|
138
137
|
let still = null; // the page scrolled with the pointer here: the handle hides until it moves away
|
|
139
138
|
let press = null; // the handle is pressed: { target, x, y }
|
|
@@ -273,7 +272,7 @@ export function createHandle({ info, active, selection, drag, menu, openMenu, dr
|
|
|
273
272
|
// block's middle line, or null where it has none: a block that takes an annotation, as do those
|
|
274
273
|
// selected with it, standing beside nothing, nor in anything that does, with its place free.
|
|
275
274
|
function noteSpot(target) {
|
|
276
|
-
const rect = pointer && box(target);
|
|
275
|
+
const rect = pointer && !aside(pointer.target) && box(target);
|
|
277
276
|
if (!rect || pointer.x <= (rect.left + rect.right) / 2 + (noted === target ? -MIDDLE_SLACK : MIDDLE_SLACK)) return null;
|
|
278
277
|
if (!pointedAt(target).every((unit) => notes.can([unit])) || !notes.can(notedBlocks(target))) return null;
|
|
279
278
|
for (let unit = target; unit; unit = unitElement(unit.parentElement)) if (standsBeside(kindOf(unit), unit)) return null;
|
|
@@ -416,7 +415,7 @@ export function createHandle({ info, active, selection, drag, menu, openMenu, dr
|
|
|
416
415
|
}
|
|
417
416
|
|
|
418
417
|
// The first block of a container whose first line acts for it (its description's `firstLineActs`: a
|
|
419
|
-
// highlight block's, after its icon, Notion's callout disableFirstItemHoverMenu; a quote's) shows no
|
|
418
|
+
// highlight block's, after its icon, Notion's callout disableFirstItemHoverMenu; a callout's; a quote's) shows no
|
|
420
419
|
// handle of its own: the container's stands on its line (a disclosure's is its title row).
|
|
421
420
|
function firstOfPanel(el) {
|
|
422
421
|
const panel = el?.parentElement;
|
|
@@ -452,7 +451,7 @@ export function createHandle({ info, active, selection, drag, menu, openMenu, dr
|
|
|
452
451
|
still = null;
|
|
453
452
|
if (!active() || event.buttons) return;
|
|
454
453
|
typing = false;
|
|
455
|
-
pointer = { x, y };
|
|
454
|
+
pointer = { x, y, target };
|
|
456
455
|
// The pointer on the way to a 批注's marker or button finds a section's strip, which stands left of
|
|
457
456
|
// them. A card at a section's edge is the card's.
|
|
458
457
|
if (!bar.contains(target)) barOver = target?.closest?.(".ge-note-card") ? null : barAt(x, y);
|
|
@@ -586,6 +585,15 @@ export function createHandle({ info, active, selection, drag, menu, openMenu, dr
|
|
|
586
585
|
placeBar();
|
|
587
586
|
placeHandle();
|
|
588
587
|
},
|
|
588
|
+
/**
|
|
589
|
+
* The block the pointer is at as the reader sees it, for what shows beside it but the handle (a
|
|
590
|
+
* heading's fold triangle, fold/): none while dragging, typing, drawing a box or dragging a gap;
|
|
591
|
+
* of a container whose first line acts for it (a highlight block), that first block.
|
|
592
|
+
*/
|
|
593
|
+
get pointed() {
|
|
594
|
+
if (drag.active || drawing() || typing || document.documentElement.hasAttribute("data-ge-gap-drag") || !hovered?.isConnected) return null;
|
|
595
|
+
return pointedAt(hovered).at(-1);
|
|
596
|
+
},
|
|
589
597
|
/** The handle, the 批注 button or the bar shows (the frames go on). */
|
|
590
598
|
get showing() { return Boolean(shown || noted || barShown); },
|
|
591
599
|
/** Whether a node is part of the handle, the 批注 button or the bar. */
|