@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
|
@@ -12,9 +12,9 @@ import { asTitle, flowchartFromList, flowchartFromPanel, itemFromStep, listFromF
|
|
|
12
12
|
|
|
13
13
|
// Turning blocks into other types on the page (DOM only; tested with jsdom): text, small text
|
|
14
14
|
// (小字, the kit's .doc-note), four heading levels, bulleted, numbered and to-do lists and flow charts (流程图), disclosures
|
|
15
|
-
// (折叠列表),
|
|
16
|
-
//
|
|
17
|
-
// into a disclosure, goes into it as it is), code blocks, quotes and
|
|
15
|
+
// (折叠列表), highlight panels (高亮块: a container with the opening summary's look, whose blocks keep
|
|
16
|
+
// their own types, lists and headings among them) and callouts (提示块: the same kind of container, its
|
|
17
|
+
// look its own; a block turned into either, or into a disclosure, goes into it as it is), code blocks, quotes and
|
|
18
18
|
// dividers; the types are the components' (src/editor/components/, registry.mjs), and so is how a
|
|
19
19
|
// type that is no text block is made (its `create`). The "/" menu,
|
|
20
20
|
// Markdown shortcuts, the block menu and its "在下方新建一块" all come here (editor.mjs:
|
|
@@ -48,7 +48,8 @@ const ownAttribute = (host, name) => Boolean(ATTRIBUTES[host.getAttribute("data-
|
|
|
48
48
|
|
|
49
49
|
// The types a block, or a group of blocks, goes into as it is (each keeping its type: `takesAsIs`): a
|
|
50
50
|
// highlight block (notion-lite's callout, whose body is its children: transformBlocks moves the blocks
|
|
51
|
-
// into a new one) and, as the reader asked, a disclosure (into its
|
|
51
|
+
// into a new one), a callout (the same kind of block) and, as the reader asked, a disclosure (into its
|
|
52
|
+
// content; its title left empty to type).
|
|
52
53
|
const TAKES_AS_IS = new Set(Object.keys(typesWith("takesAsIs")));
|
|
53
54
|
|
|
54
55
|
// Whether a box takes the block of a type: what its role accepts, and none of a type that does not
|
|
@@ -181,7 +182,7 @@ export function containerType(unit) {
|
|
|
181
182
|
const contentOf = (unit) => BLOCK_TYPES[containerType(unit)]?.content?.(unit) ?? unit;
|
|
182
183
|
|
|
183
184
|
// The containers that turn into one another, what they hold carried along (Notion's: HOLDERS): a
|
|
184
|
-
// disclosure, a quote, a highlight block. Each is the kind of box it is, as well as of block.
|
|
185
|
+
// disclosure, a quote, a highlight block, a callout. Each is the kind of box it is, as well as of block.
|
|
185
186
|
|
|
186
187
|
// The blocks a disclosure, quote or highlight block holds (a highlight block's icon not among them).
|
|
187
188
|
const heldBy = (unit) => heldIn(contentOf(unit));
|
|
@@ -272,8 +273,8 @@ function standIn(host, type) {
|
|
|
272
273
|
return standsFor(next, host);
|
|
273
274
|
}
|
|
274
275
|
|
|
275
|
-
// Whether a block already is the text block of a type: its tag, and
|
|
276
|
-
//
|
|
276
|
+
// Whether a block already is the text block of a type: its tag, and its class where its type has
|
|
277
|
+
// one; of the paragraph types, the one its class makes it.
|
|
277
278
|
function isOfType(host, type) {
|
|
278
279
|
const spec = BLOCK_TYPES[type];
|
|
279
280
|
if (host.localName !== spec.tag) return false;
|
|
@@ -40,7 +40,7 @@ const WRAPPERS = new Set(["UL", "OL", "BLOCKQUOTE"]);
|
|
|
40
40
|
|
|
41
41
|
// An inline element of the report's own, as the scanner judges it (source/blocks.mjs): its
|
|
42
42
|
// attributes as the file writes them (not the page's data-ge-* markers).
|
|
43
|
-
const isOwnAtom =
|
|
43
|
+
const isOwnAtom =(node) => ownInline(node.localName, [...node.attributes].filter(({ name }) => !MARKER.test(name)), node.textContent.trim() !== "");
|
|
44
44
|
|
|
45
45
|
// A block's atoms in `root` (its source parsed), in the order of the file, as the scanner lists
|
|
46
46
|
// them (source/blocks.mjs inlineMode): the outermost formulas, links shown with their icon and inline
|
|
@@ -88,6 +88,7 @@ export function prepareBlock(element, { inner, atoms, kind = "flow", caps = [] }
|
|
|
88
88
|
const template = element.ownerDocument.createElement("template");
|
|
89
89
|
template.innerHTML = inner;
|
|
90
90
|
template.content.querySelectorAll("*").forEach((node) => node.setAttribute("data-ge-src", ""));
|
|
91
|
+
HOSTS[kind]?.pictures?.show(template.content); // a cell's pictures shown where the server serves them
|
|
91
92
|
const sourceAtoms = atomsIn(template.content, kind === "text" && caps.includes("plain"));
|
|
92
93
|
const drawnAtoms = sourceAtoms.filter((atom) => atom.matches(ATOM_SELECTOR)); // a formula as the kit drew it
|
|
93
94
|
// The blocks a list item holds are blocks of their own: only its text before them is rebuilt.
|
|
@@ -342,15 +343,16 @@ export function matchesSource(element, inner) {
|
|
|
342
343
|
export function serializeInner(element) {
|
|
343
344
|
const inner = HOSTS[element.getAttribute?.("data-ge-kind")]?.inner;
|
|
344
345
|
if (inner) return inner(element);
|
|
345
|
-
// A table cell's lists are its text (单元格里的列表); any other block's are blocks of their own.
|
|
346
|
-
|
|
347
|
-
|
|
346
|
+
// A table cell's lists are its text (单元格里的列表); any other block's are blocks of their own. A
|
|
347
|
+
// kind of text block that holds pictures (a cell's: HOSTS `pictures`) writes them; any other none.
|
|
348
|
+
const kind = element.getAttribute?.("data-ge-kind");
|
|
349
|
+
return serializeNodes(ownNodes(element), kind === "cell", HOSTS[kind]?.pictures ?? null).replace(/<br>\s*$/, "");
|
|
348
350
|
}
|
|
349
351
|
|
|
350
352
|
// A list in a table cell, its items' inline content (a line break holding an empty item's caret left out).
|
|
351
|
-
function serializeList(list) {
|
|
353
|
+
function serializeList(list, pictures = null) {
|
|
352
354
|
const tag = list.tagName.toLowerCase();
|
|
353
|
-
const items = [...list.children].filter((item) => item.tagName === "LI").map((item) => `<li>${[...item.childNodes]
|
|
355
|
+
const items = [...list.children].filter((item) => item.tagName === "LI").map((item) => `<li>${serializeNodes([...item.childNodes], false, pictures).replace(/<br>\s*$/, "")}</li>`);
|
|
354
356
|
return items.length > 0 ? `<${tag}>${items.join("")}</${tag}>` : "";
|
|
355
357
|
}
|
|
356
358
|
|
|
@@ -383,11 +385,16 @@ export function textEnd(element) {
|
|
|
383
385
|
|
|
384
386
|
const ownNodes = (element) => [...element.childNodes].slice(0, textEnd(element));
|
|
385
387
|
|
|
386
|
-
/**
|
|
388
|
+
/**
|
|
389
|
+
* A block's own content as HTML (innerHTML, without the blocks a list item holds, nor the words an
|
|
390
|
+
* Agent took out that the page shows in it: GONE_WORDS), what undo and redo record of it.
|
|
391
|
+
*/
|
|
387
392
|
export function ownHTML(element) {
|
|
388
|
-
|
|
393
|
+
const shown = element.querySelector(GONE_WORDS);
|
|
394
|
+
if (nestedBlocks(element).length === 0 && !shown) return element.innerHTML;
|
|
389
395
|
const copy = element.ownerDocument.createElement("div");
|
|
390
396
|
copy.append(...ownNodes(element).map((node) => node.cloneNode(true)));
|
|
397
|
+
if (shown) copy.querySelectorAll(GONE_WORDS).forEach((node) => node.remove());
|
|
391
398
|
return copy.innerHTML;
|
|
392
399
|
}
|
|
393
400
|
|
|
@@ -429,12 +436,42 @@ export const parentItem = (item) => item?.tagName === "LI" && item.parentElement
|
|
|
429
436
|
// edits becomes a space too.
|
|
430
437
|
const spaced = (text) => escapeTyped(text).replace(/ *\u00a0[ \u00a0]*/g, " ");
|
|
431
438
|
|
|
432
|
-
|
|
439
|
+
// The editor's own nodes in a text block (data-doc-dev: the words an Agent took out, which the page
|
|
440
|
+
// shows where they were, changes/) are no content: left out, the text on either side of one is
|
|
441
|
+
// written as one text, as it was before the node split it (a space either side of it the one space
|
|
442
|
+
// it was, never two).
|
|
443
|
+
function serializeNodes(nodes, lists = false, pictures = null) {
|
|
444
|
+
let html = "";
|
|
445
|
+
let text = null; // a text node's, not written yet: the text after an editor's node joins it
|
|
446
|
+
let across = false; // an editor's node stands between it and what comes next
|
|
447
|
+
for (const node of nodes) {
|
|
448
|
+
if (node.nodeType === 1 && node.hasAttribute("data-doc-dev")) {
|
|
449
|
+
across = text !== null;
|
|
450
|
+
continue;
|
|
451
|
+
}
|
|
452
|
+
if (node.nodeType === 3 && node.data !== ZWSP) {
|
|
453
|
+
if (text !== null && !across) html += spaced(text);
|
|
454
|
+
text = text !== null && across ? text + node.data : node.data;
|
|
455
|
+
across = false;
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
if (text !== null) html += spaced(text);
|
|
459
|
+
text = null;
|
|
460
|
+
across = false;
|
|
461
|
+
html += serializeNode(node, lists, pictures);
|
|
462
|
+
}
|
|
463
|
+
return text === null ? html : html + spaced(text);
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// `pictures`: the host's (HOSTS `pictures`: write(element) its markup, "" for one of no file, null for no picture).
|
|
467
|
+
function serializeNode(node, lists = false, pictures = null) {
|
|
433
468
|
// A text node holding nothing but a zero-width space keeps the caret after a mark the editor
|
|
434
469
|
// made (markdown/, typing shortcuts); it is never content.
|
|
435
470
|
if (node.nodeType === 3) return node.data === ZWSP ? "" : spaced(node.data);
|
|
436
471
|
if (node.nodeType !== 1) return "";
|
|
437
|
-
if (isList(node)) return lists ? serializeList(node) : "";
|
|
472
|
+
if (isList(node)) return lists ? serializeList(node, pictures) : "";
|
|
473
|
+
const picture = pictures?.write(node) ?? null;
|
|
474
|
+
if (picture !== null) return picture;
|
|
438
475
|
const atom = node.getAttribute("data-ge-atom");
|
|
439
476
|
if (atom !== null && ATOM_SOURCE.has(atom)) return ATOM_SOURCE.get(atom);
|
|
440
477
|
// Elements from the source keep the author's tag and attributes; only elements the browser
|
|
@@ -443,7 +480,7 @@ function serializeNode(node, lists = false) {
|
|
|
443
480
|
// and their text kept.
|
|
444
481
|
const fromSource = node.hasAttribute("data-ge-src") && node.tagName in TAGS;
|
|
445
482
|
const tag = fromSource ? node.tagName.toLowerCase() : TAGS[node.tagName];
|
|
446
|
-
const inner = [...node.childNodes]
|
|
483
|
+
const inner = serializeNodes([...node.childNodes], false, pictures);
|
|
447
484
|
const ink = node.tagName === "SPAN" ? [...node.classList].filter(isInkClass) : [];
|
|
448
485
|
if (ink.length > 0) return inner ? `<span class="${ink.join(" ")}">${inner}</span>` : "";
|
|
449
486
|
// Small text's end part (its Tab: components/paragraph/page.mjs), at the line's right end.
|
|
@@ -498,8 +535,9 @@ export function isEmpty(element) {
|
|
|
498
535
|
const siblingTag = (element) => element.tagName === "LI" ? "li" : "p";
|
|
499
536
|
|
|
500
537
|
/**
|
|
501
|
-
* A text block made on the page: data-ge-new, with its type and unit kind
|
|
502
|
-
*
|
|
538
|
+
* A text block made on the page: data-ge-new, with its type and unit kind, a text block of the flow
|
|
539
|
+
* (every type's that is one: a callout's words, its own kind until 2026-11-07, are a paragraph of it
|
|
540
|
+
* now). Inside a component it leaves the frame to the component, as `from` (the block it was split off) does.
|
|
503
541
|
*/
|
|
504
542
|
export function newHost(doc, type, from = null) {
|
|
505
543
|
const spec = BLOCK_TYPES[type];
|
|
@@ -509,9 +547,8 @@ export function newHost(doc, type, from = null) {
|
|
|
509
547
|
block.setAttribute("data-ge-new", "");
|
|
510
548
|
block.setAttribute("data-ge-type", type);
|
|
511
549
|
block.setAttribute("data-ge-unit-kind", spec.kind);
|
|
512
|
-
|
|
513
|
-
block.setAttribute("data-ge-
|
|
514
|
-
block.setAttribute("data-ge-caps", capsFor(kind));
|
|
550
|
+
block.setAttribute("data-ge-kind", "flow");
|
|
551
|
+
block.setAttribute("data-ge-caps", capsFor("flow"));
|
|
515
552
|
if (from?.hasAttribute("data-ge-framed")) block.setAttribute("data-ge-framed", "");
|
|
516
553
|
return block;
|
|
517
554
|
}
|
|
@@ -542,6 +579,9 @@ export function newTail(container, type) {
|
|
|
542
579
|
// New blocks split off `from` are paragraphs, or list items in a list.
|
|
543
580
|
const newBlock = (doc, tag, from) => newHost(doc, tag === "li" ? "item" : "paragraph", from);
|
|
544
581
|
|
|
582
|
+
/** A new, empty paragraph, as a split makes one outside a list (the page's title's Enter: typing/ enterBody). */
|
|
583
|
+
export const newParagraphHost = (doc) => newBlock(doc, "p", null);
|
|
584
|
+
|
|
545
585
|
// The element a text block made on the page is part of when it is not a block of its own: the
|
|
546
586
|
// summary of a new disclosure, a new code block (its code's pre, its title's block), the header of a
|
|
547
587
|
// new detail card.
|
|
@@ -688,10 +728,12 @@ const isFormula = (node) => node.matches(".doc-math-inline");
|
|
|
688
728
|
* text with the format bar's marks (marks: false drops them, links: false drops links), a formula
|
|
689
729
|
* of this page as its chip (another one, KaTeX's or the kit's \(…\), as the chip formula(tex) makes,
|
|
690
730
|
* or else as its TeX source; `formulas` false, each as its source), a link shown with its icon as the
|
|
691
|
-
* chip mention(mentionOf(it)) makes (else a link of its title)
|
|
692
|
-
*
|
|
731
|
+
* chip mention(mentionOf(it)) makes (else a link of its title), an element what picture(element)
|
|
732
|
+
* makes of it (a cell's picture: page/table/pictures.mjs; null nothing, undefined no picture: none
|
|
733
|
+
* given, no picture is one); blocks and line breaks start new lines, and everything else gives only
|
|
734
|
+
* its text.
|
|
693
735
|
*/
|
|
694
|
-
export function pastedLines(doc, html, { marks = true, links = true, formula = null, formulas = true, mention = null } = {}) {
|
|
736
|
+
export function pastedLines(doc, html, { marks = true, links = true, formula = null, formulas = true, mention = null, picture = null } = {}) {
|
|
695
737
|
const template = doc.createElement("template");
|
|
696
738
|
template.innerHTML = html;
|
|
697
739
|
const lines = [[]];
|
|
@@ -745,6 +787,12 @@ export function pastedLines(doc, html, { marks = true, links = true, formula = n
|
|
|
745
787
|
}
|
|
746
788
|
}
|
|
747
789
|
if (/^(STYLE|SCRIPT|TEMPLATE|META|TITLE|LINK|NOSCRIPT|BUTTON|SVG)$/i.test(child.tagName) || child.matches('[aria-hidden="true"], .ge-code-gutter, [data-doc-dev]')) continue;
|
|
790
|
+
// A picture, where `picture` takes it (undefined: no picture): what it makes of it, else nothing.
|
|
791
|
+
const made = picture?.(child);
|
|
792
|
+
if (made !== undefined) {
|
|
793
|
+
if (made) push(target, made);
|
|
794
|
+
continue;
|
|
795
|
+
}
|
|
748
796
|
if (child.tagName === "BR") {
|
|
749
797
|
if (target) push(target, doc.createTextNode(" "));
|
|
750
798
|
else newLine();
|
|
@@ -762,7 +810,7 @@ export function pastedLines(doc, html, { marks = true, links = true, formula = n
|
|
|
762
810
|
continue;
|
|
763
811
|
}
|
|
764
812
|
walk(child, mark);
|
|
765
|
-
if (mark.textContent.trim() || mark.querySelector("[data-ge-atom]")) push(target, mark);
|
|
813
|
+
if (mark.textContent.trim() || mark.querySelector("[data-ge-atom]") || (picture && mark.firstElementChild)) push(target, mark);
|
|
766
814
|
else if (mark.textContent) push(target, doc.createTextNode(mark.textContent));
|
|
767
815
|
}
|
|
768
816
|
};
|
|
@@ -872,6 +920,9 @@ export function mergeInto(into, from, { anyKind = false } = {}) {
|
|
|
872
920
|
// with its own.
|
|
873
921
|
|
|
874
922
|
export const ELEMENT_ID = "data-ge-id";
|
|
923
|
+
|
|
924
|
+
/** The words an Agent took out of a text block, shown where they were (changes/): never its content. */
|
|
925
|
+
export const GONE_WORDS = "[data-ge-gone-words]";
|
|
875
926
|
const ELEMENT_ID_PREFIX = Math.random().toString(36).slice(2, 6); // a page's own, as formulas' keys
|
|
876
927
|
let elementIds = 0;
|
|
877
928
|
|
|
@@ -927,10 +978,10 @@ export const inTable = (node) => /^(TR|TD|TH)$/.test(node?.tagName ?? "") && nod
|
|
|
927
978
|
export function unitElement(node) {
|
|
928
979
|
let found = node?.closest?.(UNIT_OR_LEAD) ?? null;
|
|
929
980
|
while (inTable(found)) found = found.parentElement?.closest(UNIT_OR_LEAD) ?? null;
|
|
930
|
-
// Text that is part of a block
|
|
931
|
-
//
|
|
981
|
+
// Text made on the page that is part of a block (a new code block's code, a media block's new
|
|
982
|
+
// caption) stands for that block: the part's own block, not the one around it.
|
|
932
983
|
const part = found && !found.hasAttribute("data-ge-unit") ? partOf(found) : null;
|
|
933
|
-
if (part) found =
|
|
984
|
+
if (part) found = part.closest(UNIT);
|
|
934
985
|
if (!found?.hasAttribute("data-ge-lead")) return found;
|
|
935
986
|
const id = found.getAttribute("data-ge-lead");
|
|
936
987
|
let next = found.nextElementSibling;
|
|
@@ -1180,12 +1231,12 @@ export function snapshotLayout(root) {
|
|
|
1180
1231
|
}
|
|
1181
1232
|
|
|
1182
1233
|
// Whether a text block may be written with no text: it is of a type whose component says so (its
|
|
1183
|
-
// `empty`: a paragraph, a heading, a list item
|
|
1234
|
+
// `empty`: a paragraph, a heading, a list item; the server's emptyLeaf reads the same)
|
|
1184
1235
|
// and can be emptied (can "empty"), an item holding blocks too, its line kept over them (keepLine). A
|
|
1185
1236
|
// field that may be emptied (a cell, a caption) is no block written empty; a new code block is
|
|
1186
1237
|
// written empty by its type (describeNode).
|
|
1187
1238
|
const clearable = (element) => can(element, "empty");
|
|
1188
|
-
/** Whether an empty text block stays, written with no text (a paragraph, a heading, a list item, a
|
|
1239
|
+
/** Whether an empty text block stays, written with no text (a paragraph, a heading, a list item, a code block). */
|
|
1189
1240
|
const keepsWhenEmpty = (element) => BLOCK_TYPES[textTypeOf(element)]?.empty === true && clearable(element);
|
|
1190
1241
|
|
|
1191
1242
|
/** Whether a text block may go: it can be removed, is not kept (data-ge-keep) and holds no blocks (it would show no line of its own). */
|
|
@@ -1208,8 +1259,11 @@ const leaves = (node, emptied) => gone(node) || emptied.has(node);
|
|
|
1208
1259
|
// The text block of a block: the block itself, or where its component says (a code block's code).
|
|
1209
1260
|
const textOf = (node) => BLOCK_TYPES[blockTypeOf(node)]?.textHost?.(node) ?? node;
|
|
1210
1261
|
|
|
1211
|
-
// What a component's description is given to say what goes with a block (`extras`).
|
|
1262
|
+
// What a component's description is given to say what goes with a block (`extras`). `nodes(box)`: the
|
|
1263
|
+
// blocks of a box of its own as the commit writes them (nodeOf), a block written whole holding those of
|
|
1264
|
+
// boxes of its own apart from its markup (an instance's slots: installed/index.mjs).
|
|
1212
1265
|
const HELPERS = { sizeValue, serializeInner, unitsOf };
|
|
1266
|
+
const helpersFor = (emptied) => ({ ...HELPERS, nodes: (box) => unitsOf(box).map((child) => nodeOf(child, emptied)).filter(Boolean) });
|
|
1213
1267
|
|
|
1214
1268
|
/**
|
|
1215
1269
|
* The first element in `root` (in document order, `root` itself left out) carrying each value of
|
|
@@ -1351,7 +1405,7 @@ function describeNode(element, emptied) {
|
|
|
1351
1405
|
// (`content`: a disclosure's content region), its title (`title`), its id (`keyed`: a detail
|
|
1352
1406
|
// card's), when it is written at all (`written`: a row once each of its columns has something, a
|
|
1353
1407
|
// detail card while a link opens it; else once it holds something).
|
|
1354
|
-
const extras = spec.extras?.(element,
|
|
1408
|
+
const extras = spec.extras?.(element, helpersFor(emptied)) ?? {};
|
|
1355
1409
|
if (spec.bare) return spec.written?.(element, []) === false ? null : { type, ...extras };
|
|
1356
1410
|
if (!spec.box) {
|
|
1357
1411
|
const text = textOf(element);
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { startBoard } from "./board/index.mjs";
|
|
2
|
+
import { relayTo } from "./notices.mjs";
|
|
3
|
+
import { connectWorkbench } from "./session.mjs";
|
|
4
|
+
|
|
5
|
+
// A custom page inside a workbench (src/server/routes.mjs serves it at /pages/<slug> with this module;
|
|
6
|
+
// docs/workbench.md "Custom pages"): no document editor, the session, by which the workbench shows it
|
|
7
|
+
// as it shows a document's page, and its boards' editing (./board/: the cards moved, resized, added,
|
|
8
|
+
// taken out, their settings and their blocks' writes, through the page service, by the page map the
|
|
9
|
+
// server writes in its head), which shows the page again only once nothing of it waits. Its session's
|
|
10
|
+
// slug is "@<slug>", the page's address in the workbench (#@<slug>), which no document's slug can be.
|
|
11
|
+
// It answers the session's own commands (theme, keys, scroll-top: src/editor/page/session.mjs),
|
|
12
|
+
// prepare-close (once the board's ops sent are answered: each is written at once, nothing else waits),
|
|
13
|
+
// add-card (the top bar's 添加自定义块: the library of the page's first board, under the button's place that
|
|
14
|
+
// the workbench sends) and, on the home page, restore-defaults (恢复默认卡片, the sidebar's: the board's, one step of its
|
|
15
|
+
// undo; its answer { ok, added, skipped } the workbench says) and undo-restore ({ cards }: that step
|
|
16
|
+
// undone while it is the board's last, the workbench's 撤销),
|
|
17
|
+
// and sends ready, reload (its live script heard that page.html or page.json changed, or a block it
|
|
18
|
+
// holds: the workbench loads it again in a hidden frame and swaps it in once drawn), open (a link to a
|
|
19
|
+
// document or another page, or a block's context.workspace.open: doc-open-request) and key. Opened on its own (not in a frame of the workbench), it has no
|
|
20
|
+
// session: its board edits all the same, and the live script reloads it.
|
|
21
|
+
|
|
22
|
+
const slug = decodeURIComponent(location.pathname.split("/")[2] ?? "");
|
|
23
|
+
const IDLE = { editing: false, pending: false, saving: false, offline: false, conflicts: 0, unfit: 0, changed: false };
|
|
24
|
+
// Nothing stands over a custom page as a modal.
|
|
25
|
+
const NO_MODALS = { open: () => [], listen() {}, closeTop: () => false };
|
|
26
|
+
|
|
27
|
+
let board = null;
|
|
28
|
+
const session = connectWorkbench({
|
|
29
|
+
slug: `@${slug}`,
|
|
30
|
+
snapshot: () => ({ title: document.title, icon: null, state: IDLE }),
|
|
31
|
+
commands: {
|
|
32
|
+
"prepare-close": async () => {
|
|
33
|
+
await board?.idle();
|
|
34
|
+
return { ok: true };
|
|
35
|
+
},
|
|
36
|
+
// 添加自定义块 of the workbench's top bar: the library opens in the page, at `anchor` (the button's place in
|
|
37
|
+
// this frame's coordinates; none: in the middle of the window), the first board's.
|
|
38
|
+
"add-card": async ({ anchor } = {}) => (board ? board.addCard({ anchor }) : { ok: false, reason: "board" }),
|
|
39
|
+
...(slug === "home" ? {
|
|
40
|
+
"restore-defaults": async () => (board ? board.restoreDefaults() : { ok: false, reason: "board" }),
|
|
41
|
+
"undo-restore": async ({ cards }) => (board ? board.undoRestore(cards) : { ok: false, reason: "board" }),
|
|
42
|
+
} : {}),
|
|
43
|
+
},
|
|
44
|
+
modals: NO_MODALS,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// The page map (routes.mjs: its slug, its token, the version it was served at, its blocks): the boards edit.
|
|
48
|
+
let map = null;
|
|
49
|
+
try {
|
|
50
|
+
map = JSON.parse(document.querySelector("script[data-ge-page]")?.textContent ?? "null");
|
|
51
|
+
} catch {}
|
|
52
|
+
board = map?.token ? startBoard({ map, reload: () => (session ? session.reload() : location.reload()), hosted: Boolean(session) }) : null;
|
|
53
|
+
// The live script (routes.mjs) shows the page again through the workbench, which swaps a new page in
|
|
54
|
+
// once drawn: no reload seen; once the board's own writes, a drag, a form or a field typed in are done.
|
|
55
|
+
if (board) window.__galleryEditReload = () => board.swap();
|
|
56
|
+
|
|
57
|
+
if (session) {
|
|
58
|
+
// Its notices (a card someone else changed) are the workbench's toasts, as a document's page's are.
|
|
59
|
+
relayTo(session.notice, session.noticeRoom);
|
|
60
|
+
if (!board) window.__galleryEditReload = () => session.reload();
|
|
61
|
+
|
|
62
|
+
// A block's context.workspace.open (the kit's runtime/workspace.js: 我的待办's item, 最近编辑's
|
|
63
|
+
// document): a document, at its block where it names one, or a custom page, opened in the workbench.
|
|
64
|
+
addEventListener("doc-open-request", (event) => {
|
|
65
|
+
const { slug = null, block = null, page = null } = event.detail ?? {};
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
session.open(page ? { hash: `@${page}` } : { target: slug, block });
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// A link to a document or a page of the workbench goes there in the workbench, never in this frame:
|
|
71
|
+
// a workbench's address (#<link>, #@<slug>, /#…), a document's page (/generated/<slug>.html) or its
|
|
72
|
+
// file (../<slug>/doc.html), a custom page's served path (/pages/<slug>, the page alone that gallery
|
|
73
|
+
// page open gives, or written relative to this one: "reading" from /pages/home). Another site's
|
|
74
|
+
// opens in a tab of its own.
|
|
75
|
+
addEventListener("click", (event) => {
|
|
76
|
+
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
|
|
77
|
+
const link = event.target instanceof Element ? event.target.closest("a[href]") : null;
|
|
78
|
+
if (!link || link.hasAttribute("download")) return;
|
|
79
|
+
const raw = link.getAttribute("href") ?? "";
|
|
80
|
+
// A place in this page (an element of that id) is the browser's to go to.
|
|
81
|
+
if (raw.startsWith("#") && raw.length > 1 && document.getElementById(decodeURIComponent(raw.slice(1)))) return;
|
|
82
|
+
let url;
|
|
83
|
+
try {
|
|
84
|
+
url = new URL(raw, location.href);
|
|
85
|
+
} catch {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
if (url.origin !== location.origin) {
|
|
89
|
+
event.preventDefault();
|
|
90
|
+
window.open(url.href, "_blank", "noopener");
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const custom = /^\/pages\/([a-z0-9-]+)\/?$/.exec(url.pathname)?.[1];
|
|
94
|
+
const page = /^\/generated\/([a-z0-9-]+)\.html$/.exec(url.pathname)?.[1] ?? /^\/([a-z0-9-]+)\/(?:doc|report)\.html$/.exec(url.pathname)?.[1];
|
|
95
|
+
if (custom) {
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
session.open({ hash: `@${custom}` });
|
|
98
|
+
} else if (page) {
|
|
99
|
+
event.preventDefault();
|
|
100
|
+
session.open({ target: page, block: url.hash.slice(1) || null });
|
|
101
|
+
} else if ((url.pathname === "/" || raw.startsWith("#")) && url.hash.length > 1) {
|
|
102
|
+
event.preventDefault();
|
|
103
|
+
session.open({ hash: decodeURIComponent(url.hash.slice(1)) });
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
@@ -28,6 +28,8 @@ import { t } from "../../../shared/i18n/index.mjs";
|
|
|
28
28
|
// cancels, and so does anything that ends the press another way (the handle losing the pointer
|
|
29
29
|
// capture, the window losing the focus, the page hidden): never a drop. Ending is idempotent, and
|
|
30
30
|
// the line, tint and copy belong to their drag (overlays.mjs). Ctrl+Shift+arrows move selected blocks standing next to each other by one place (moveBy).
|
|
31
|
+
// A folded heading goes with what it hides, or as the section it covers whole (fold/ takenWith); its
|
|
32
|
+
// copy shows what is in sight, and Ctrl+Shift+↑/↓ take it a section of its level at a time.
|
|
31
33
|
|
|
32
34
|
const STYLE = `
|
|
33
35
|
${gestureLock("data-ge-drag", { cursor: "grabbing", select: true })}
|
|
@@ -43,9 +45,9 @@ const STYLE = `
|
|
|
43
45
|
* info: block-info.mjs. selection: selection/index.mjs. struct(parents, touched, mutate): the
|
|
44
46
|
* editor's undoable structural change (history.mjs). say: the status line. closeMenu(): the block
|
|
45
47
|
* menu closes. schedule(): the block tools' next frame (blocks.mjs), which calls step() while a
|
|
46
|
-
* drag lasts.
|
|
48
|
+
* drag lasts. folds: the headings' folds (fold/).
|
|
47
49
|
*/
|
|
48
|
-
export function createDrag({ info, selection, struct, say, closeMenu, schedule }) {
|
|
50
|
+
export function createDrag({ info, selection, struct, say, closeMenu, schedule, folds }) {
|
|
49
51
|
addStyle(STYLE);
|
|
50
52
|
const { addColumn, columnsOf, rowAround } = columnOps() ?? {};
|
|
51
53
|
const { kindOf, nameOf, named, fixedText, boxKindOf } = info;
|
|
@@ -105,7 +107,8 @@ export function createDrag({ info, selection, struct, say, closeMenu, schedule }
|
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
// Put blocks beside a block (drop.mjs `aside`): { target, side }, the two side by side in a new
|
|
108
|
-
// row of columns
|
|
110
|
+
// row of columns (a folded heading's column taking what it hides: fold/ withHidden); { row, index,
|
|
111
|
+
// whole }, a new column of that row at `index` holding them, or,
|
|
109
112
|
// when they are all of one column of it (`whole`), that column moved there. One undo step that
|
|
110
113
|
// keeps them selected; a container they leave empty goes, as when they move (and a row left
|
|
111
114
|
// with one column gives its blocks back: history.mjs).
|
|
@@ -122,7 +125,7 @@ export function createDrag({ info, selection, struct, say, closeMenu, schedule }
|
|
|
122
125
|
const leftovers = leftoversOf(targets, aside.row ?? aside.target);
|
|
123
126
|
const parents = [...new Set([...targets.map((target) => target.parentNode), aside.row ?? aside.target.parentElement, ...leftovers.map((node) => node.parentNode)].filter(Boolean))];
|
|
124
127
|
struct(parents, [], () => {
|
|
125
|
-
const { created } = aside.row ? addColumn(aside.row, aside.index, parts) : rowAround(aside.target, [parts], aside.side);
|
|
128
|
+
const { created } = aside.row ? addColumn(aside.row, aside.index, parts) : rowAround(folds.withHidden(aside.target), [parts], aside.side);
|
|
126
129
|
leftovers.forEach((node) => node.remove());
|
|
127
130
|
return { touched: [], focus: null, select: targets, reselect: true, created };
|
|
128
131
|
});
|
|
@@ -134,30 +137,40 @@ export function createDrag({ info, selection, struct, say, closeMenu, schedule }
|
|
|
134
137
|
*/
|
|
135
138
|
function moveBy(targets, delta, { keepFocus = false } = {}) {
|
|
136
139
|
closeMenu();
|
|
137
|
-
|
|
140
|
+
const picked = ordered([targets].flat().filter(alive));
|
|
141
|
+
targets = folds.takenWith(picked);
|
|
138
142
|
if (targets.length === 0) return false;
|
|
139
143
|
const reason = targets.map(fixedText).find(Boolean);
|
|
140
144
|
if (reason) {
|
|
141
145
|
say(reason);
|
|
142
146
|
return false;
|
|
143
147
|
}
|
|
144
|
-
|
|
148
|
+
const name = folds.namedWith(picked, targets, named);
|
|
149
|
+
// The blocks to move among: not a box's lead (a highlight block's icon stays first in it), as the
|
|
150
|
+
// reader sees them: a folded heading and what it hides one (fold/ groupsOf).
|
|
145
151
|
const boxKind = boxKindOf(targets[0].parentElement);
|
|
146
152
|
const list = unitsOf(targets[0].parentElement).filter((unit) => !isLead(boxKind, kindOf(unit)));
|
|
147
|
-
const
|
|
148
|
-
|
|
153
|
+
const groups = folds.groupsOf(list);
|
|
154
|
+
const first = groups.findIndex((group) => group[0] === targets[0]);
|
|
155
|
+
let last = first;
|
|
156
|
+
let count = first < 0 ? 0 : groups[first].length;
|
|
157
|
+
while (first >= 0 && count < targets.length && last + 1 < groups.length) count += groups[++last].length;
|
|
158
|
+
if (first < 0 || !groups.slice(first, last + 1).flat().every((unit, index) => targets[index] === unit) || count !== targets.length) {
|
|
149
159
|
say(t("选中的块不相邻,不能一起上下移动;可以拖动其中一块的手柄,把它们一起移到别处。"));
|
|
150
160
|
return false;
|
|
151
161
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
162
|
+
// A folded heading alone goes a section of its level at a time (fold/ stepOver); others a block in sight at a time.
|
|
163
|
+
const alone = first === last && folds.isFolded(targets[0]);
|
|
164
|
+
const step = alone ? folds.stepOver(targets[0], delta, list) : null;
|
|
165
|
+
const over = alone ? step && [step.first, step.last] : groups[delta < 0 ? first - 1 : last + 1];
|
|
166
|
+
if (!over) {
|
|
167
|
+
say(groups.length === last - first + 1 ? t("这里只有{0};可以拖动手柄移到别处。", targets.length === 1 ? t("这一个{0}", nameOf(targets[0])) : t("这几块")) : t("{0}已经在{1}。", name, delta < 0 ? t("最前面") : t("最后面")));
|
|
155
168
|
return false;
|
|
156
169
|
}
|
|
157
|
-
moveTo(targets, targets[0].parentElement, delta < 0 ? withLeads(
|
|
170
|
+
moveTo(targets, targets[0].parentElement, delta < 0 ? withLeads(over[0])[0] : over.at(-1).nextSibling);
|
|
158
171
|
if (!keepFocus) selection.select(targets, { quiet: true });
|
|
159
172
|
targets[delta < 0 ? 0 : targets.length - 1].scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
160
|
-
say(t("已移动{0} · Ctrl+Z 撤销",
|
|
173
|
+
say(t("已移动{0} · Ctrl+Z 撤销", name));
|
|
161
174
|
return true;
|
|
162
175
|
}
|
|
163
176
|
|
|
@@ -165,7 +178,8 @@ export function createDrag({ info, selection, struct, say, closeMenu, schedule }
|
|
|
165
178
|
// the drag started (a block that cannot move says why).
|
|
166
179
|
function start(target, x, y) {
|
|
167
180
|
const picked = selection.picked;
|
|
168
|
-
const
|
|
181
|
+
const chosen = picked.length > 1 && picked.includes(target) ? [...picked] : [target];
|
|
182
|
+
const targets = folds.takenWith(chosen); // a folded heading with what it hides (fold/)
|
|
169
183
|
const reason = targets.map(fixedText).find(Boolean);
|
|
170
184
|
if (reason) {
|
|
171
185
|
say(reason);
|
|
@@ -174,7 +188,7 @@ export function createDrag({ info, selection, struct, say, closeMenu, schedule }
|
|
|
174
188
|
closeMenu();
|
|
175
189
|
selection.select(targets, { quiet: true });
|
|
176
190
|
const session = {
|
|
177
|
-
targets, target, from: target.parentElement, x, y, drop: null, rest: null, opened: new Set(),
|
|
191
|
+
targets, target, from: target.parentElement, x, y, drop: null, rest: null, opened: new Set(), name: folds.namedWith(chosen, targets, named),
|
|
178
192
|
line: element("div", { class: "ge-drop-line", hidden: "" }),
|
|
179
193
|
tint: element("div", { class: "ge-drop-tint", hidden: "" }),
|
|
180
194
|
preview: null,
|
|
@@ -184,12 +198,12 @@ export function createDrag({ info, selection, struct, say, closeMenu, schedule }
|
|
|
184
198
|
// The line and the tint go in the layer of where the blocks would go
|
|
185
199
|
// (overlay-layer.mjs), when there is one; the copy follows the pointer in the window.
|
|
186
200
|
for (const kind of ["line", "tint"]) own(session[kind], `drag ${kind}`, { owner: target, alive });
|
|
187
|
-
session.preview = createPreview(targets, x, y, { owner: target, alive });
|
|
201
|
+
session.preview = createPreview(targets.filter((node) => !folds.hidden(node)), x, y, { owner: target, alive }); // what is in sight
|
|
188
202
|
drag = session;
|
|
189
203
|
note("drag", `start ${targets.map(describe).join(", ")}`);
|
|
190
204
|
targets.flatMap(withLeads).forEach((part) => part.setAttribute("data-ge-dragging", ""));
|
|
191
205
|
document.documentElement.setAttribute("data-ge-drag", "");
|
|
192
|
-
say(t("正在移动{0} · 拖到要放的位置后松开 · 停在选项卡上切换,停在折叠块标题上展开 · Esc 取消",
|
|
206
|
+
say(t("正在移动{0} · 拖到要放的位置后松开 · 停在选项卡上切换,停在折叠块标题上展开 · Esc 取消", session.name), "prompt");
|
|
193
207
|
update();
|
|
194
208
|
schedule();
|
|
195
209
|
return true;
|
|
@@ -219,8 +233,9 @@ export function createDrag({ info, selection, struct, say, closeMenu, schedule }
|
|
|
219
233
|
: items ? accepts(box.kind, "item") || accepts(box.kind, "list")
|
|
220
234
|
: steps ? accepts(box.kind, "step") || (accepts(box.kind, "flowchart") && box.kind !== "nest" && !box.el.closest("ol.doc-flow"))
|
|
221
235
|
: [...kinds].every((kind) => accepts(box.kind, kind)));
|
|
222
|
-
// Blocks a column takes may go beside a block, into a column (分栏)
|
|
223
|
-
|
|
236
|
+
// Blocks a column takes may go beside a block, into a column (分栏); beside a folded heading when a
|
|
237
|
+
// column takes what it hides too, which goes into its column with it (besideTo).
|
|
238
|
+
const aside = !tabs && [...kinds].every((kind) => accepts("column", kind)) && ((unit) => folds.withHidden(unit.el).every((node) => accepts("column", kindOf(node))));
|
|
224
239
|
return resolveDrop(drag.tree, x + scrollX, y + scrollY, { takes, dragged: (unit) => targets.includes(unit.el), count: targets.length, items, aside, edge: scrollX });
|
|
225
240
|
}
|
|
226
241
|
|
|
@@ -272,7 +287,7 @@ export function createDrag({ info, selection, struct, say, closeMenu, schedule }
|
|
|
272
287
|
// Releasing (commit) or cancelling: the blocks go where the line showed, or stay.
|
|
273
288
|
function end(commit) {
|
|
274
289
|
if (!drag) return;
|
|
275
|
-
const { targets, target, drop, line, tint, preview, opened } = drag;
|
|
290
|
+
const { targets, target, drop, line, tint, preview, opened, name } = drag;
|
|
276
291
|
clearTimeout(drag.rest?.timer);
|
|
277
292
|
drag = null;
|
|
278
293
|
line.remove();
|
|
@@ -293,16 +308,17 @@ export function createDrag({ info, selection, struct, say, closeMenu, schedule }
|
|
|
293
308
|
besideTo(targets, drop.aside);
|
|
294
309
|
selection.select(targets, { quiet: true });
|
|
295
310
|
target.scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
296
|
-
say(t("{0} · 拖动栏间的竖线调宽度 · Ctrl+Z 撤销", drop.aside.whole ? t("已移动这一栏") : drop.aside.row ? t("已把{0}放进新的一栏",
|
|
311
|
+
say(t("{0} · 拖动栏间的竖线调宽度 · Ctrl+Z 撤销", drop.aside.whole ? t("已移动这一栏") : drop.aside.row ? t("已把{0}放进新的一栏", name) : t("已把{0}并排分栏", name)));
|
|
297
312
|
return;
|
|
298
313
|
}
|
|
299
314
|
const others = unitsOf(drop.container).filter((unit) => !targets.includes(unit) && extentOf(unit));
|
|
300
|
-
// The place is never before a box's lead (a highlight block's icon): drop.mjs.
|
|
301
|
-
|
|
315
|
+
// The place is never before a box's lead (a highlight block's icon): drop.mjs. At the end, after
|
|
316
|
+
// what the last block in sight hides too (a folded heading's section: fold/), never between them.
|
|
317
|
+
const reference = drop.slot < others.length ? withLeads(others[drop.slot])[0] : others.length > 0 ? folds.lastOf(others.at(-1)).nextSibling : null;
|
|
302
318
|
const emptied = moveTo(targets, drop.nest ?? drop.container, drop.nest ? null : reference);
|
|
303
319
|
selection.select(targets, { quiet: true });
|
|
304
320
|
target.scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
305
|
-
say(t("已移动{0}{1}{2} · Ctrl+Z 撤销",
|
|
321
|
+
say(t("已移动{0}{1}{2} · Ctrl+Z 撤销", name, drop.nest ? t("到上一项下面") : "", emptied ? t("(原来的外层已空,一并去掉)") : ""));
|
|
306
322
|
}
|
|
307
323
|
|
|
308
324
|
// The window losing the focus, or the page going out of sight, ends a drag: cancelled.
|
|
@@ -11,8 +11,12 @@ import { element, mount } from "../ui.mjs";
|
|
|
11
11
|
// (theirs stay theirs, a chart's gradients among them). The page's own rules are brought in as one
|
|
12
12
|
// stylesheet (made once, applied at once: no unstyled first frame), and each copy stands in a frame
|
|
13
13
|
// of its ancestors as the page has them (shallow copies, display: contents), so a list item keeps its
|
|
14
|
-
// marker and its number, and a section's paragraph its section's look.
|
|
15
|
-
//
|
|
14
|
+
// marker and its number, and a section's paragraph its section's look. A frame draws nothing of its
|
|
15
|
+
// own (visibility: hidden, the copy visible): display: contents leaves an element's ::before and
|
|
16
|
+
// ::after and a <details>'s own summary drawn (Chrome's "▶ 详细信息" for one without a summary, an
|
|
17
|
+
// ancestor item's marker, a flowchart step's number, each at the window's left or top), which would
|
|
18
|
+
// follow the pointer (the user's report of 2026-11-06). At most MAX blocks, each at most TALL of the
|
|
19
|
+
// window (cut, fading out at the bottom).
|
|
16
20
|
|
|
17
21
|
const MAX = 12;
|
|
18
22
|
const TALL = 0.6;
|
|
@@ -72,9 +76,9 @@ function copyOf(part, rect, top) {
|
|
|
72
76
|
}
|
|
73
77
|
const cut = rect.height > innerHeight * TALL;
|
|
74
78
|
if (cut) copy.classList.add("ge-cut");
|
|
75
|
-
// Its own size, as it was on the page: no share of a row or of its box (the window is the box here); inline, so the page's rules for the block cannot undo it.
|
|
79
|
+
// Its own size, as it was on the page: no share of a row or of its box (the window is the box here); inline, so the page's rules for the block cannot undo it. Visible, in frames that are not.
|
|
76
80
|
Object.assign(copy.style, {
|
|
77
|
-
position: "absolute", margin: "0", maxWidth: "none", minWidth: "0", maxHeight: "none", flex: "none",
|
|
81
|
+
position: "absolute", margin: "0", maxWidth: "none", minWidth: "0", maxHeight: "none", flex: "none", visibility: "visible",
|
|
78
82
|
left: `${rect.left}px`, top: `${rect.top}px`, width: `${rect.width}px`,
|
|
79
83
|
height: `${cut ? Math.round(innerHeight * TALL) : rect.height}px`,
|
|
80
84
|
});
|
|
@@ -82,6 +86,7 @@ function copyOf(part, rect, top) {
|
|
|
82
86
|
for (let node = part.parentElement; node && node !== top.parentElement; node = node.parentElement) {
|
|
83
87
|
const shell = clean(node.cloneNode(false));
|
|
84
88
|
shell.style.display = "contents";
|
|
89
|
+
shell.style.visibility = "hidden"; // a frame lends the copy its rules and draws nothing of its own
|
|
85
90
|
shell.append(outer);
|
|
86
91
|
outer = shell;
|
|
87
92
|
}
|