@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
package/kit/runtime.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
(() => {
|
|
3
3
|
// <define:__COMPONENT_FLOWS__>
|
|
4
|
-
var define_COMPONENT_FLOWS_default = [".doc-page", ".doc-section", ".doc-summary", ".doc-panel", ".doc-details-content", ".doc-dialog-content", "[data-doc-sheet]", ".doc-column"];
|
|
4
|
+
var define_COMPONENT_FLOWS_default = [".doc-page", ".doc-section", ".doc-summary", ".doc-panel", ".doc-callout", ".doc-details-content", ".doc-dialog-content", "[data-doc-sheet]", ".doc-column", "[data-doc-slot]"];
|
|
5
5
|
|
|
6
6
|
// <define:__COMPONENT_RUNTIME__>
|
|
7
|
-
var define_COMPONENT_RUNTIME_default = [{ id: "page", match: "main.doc-page", runtime: { generated: [".doc-display", "script[data-doc-state]"], root: { attrs: ["data-doc-ready", "data-doc-drawn", "data-doc-controls"] }, state: { html: ["data-doc-theme", "data-doc-width"] }, internal: ["doc-display*", "data-doc-export-copy", "data-theme", "doc-export-id", "doc-reveal", "doc-kit-error"] } }, { id: "text", runtime: { classes: { ".doc-range": ["doc-range"] } } }, { id: "mention", runtime: { attrs: { "a.doc-link-mention": ["data-doc-gone"] } } }, { id: "paragraph", match: "p" }, { id: "heading", match: "h1, h2, h3, h4" }, { id: "list", match: "ul, ol", runtime: { attrs: { "ol.doc-flow": ["data-doc-flow-key", "data-doc-flow-recount"] }, generated: ["br.doc-item-line"] } }, { id: "quote", match: "blockquote" }, { id: "
|
|
7
|
+
var define_COMPONENT_RUNTIME_default = [{ id: "page", match: "main.doc-page", runtime: { generated: [".doc-display", "script[data-doc-state]"], root: { attrs: ["data-doc-ready", "data-doc-drawn", "data-doc-controls", "data-doc-effective-theme", "data-doc-platform"] }, state: { html: ["data-doc-theme", "data-doc-font", "data-doc-size", "data-doc-spacing", "data-doc-measure", "data-doc-width"] }, internal: ["doc-display*", "data-doc-export-copy", "data-theme", "doc-export-id", "doc-reveal", "doc-kit-error", "doc-net-consent*", "data-doc-snapshot", "data-at", "data-x", "data-y", "data-w", "data-h", "data-columns"] } }, { id: "text", runtime: { classes: { ".doc-range": ["doc-range"], ".doc-long-run": ["doc-long-run"] } } }, { id: "mention", runtime: { attrs: { "a.doc-link-mention": ["data-doc-gone"] } } }, { id: "paragraph", match: "p" }, { id: "heading", match: "h1, h2, h3, h4" }, { id: "list", match: "ul, ol", runtime: { attrs: { "ol.doc-flow": ["data-doc-flow-key", "data-doc-flow-recount"] }, generated: ["br.doc-item-line"] } }, { id: "quote", match: "blockquote" }, { id: "code", match: ".doc-code", runtime: { generated: [".doc-code-fold", ".doc-code-range", ".doc-code-tools"], internal: ["doc-code-lines", "doc-code-line*", "doc-code-content", "doc-code-toolbar", "doc-code-language", "doc-code-separator", "doc-code-copy*", "doc-code-wrap*", "data-line-number"] } }, { id: "divider", match: "hr" }, { id: "math", match: ".doc-math-inline, .doc-math-block", runtime: { generated: [".doc-math-break", ".doc-math-joiner"], classes: { ".doc-math-tie": ["doc-math-tie"], ".doc-math-skip": ["doc-math-skip"] } } }, { id: "section", match: "section.doc-section" }, { id: "highlight", match: ".doc-panel, .doc-summary" }, { id: "callout", match: ".doc-callout" }, { id: "details", match: "details.doc-details" }, { id: "dialog", match: "dialog.doc-dialog", runtime: { attrs: { "dialog.doc-dialog": ["data-doc-dialog-ready", "open", "aria-label"], ".doc-dialog-content": ["tabindex"] }, root: { classes: ["doc-dialog-open", "doc-dialog-gutter"] }, internal: ["doc-dialog-in", "doc-dialog-fade"] } }, { id: "sheets", match: "[data-doc-sheets]", runtime: { state: { "[data-doc-sheets]": ["data-active-sheet"], "[data-sheet-tab]": ["aria-selected", "tabindex", "is-active"], "[data-doc-sheet]": ["hidden", "aria-hidden"] }, internal: ["doc-sheets"] } }, { id: "table", match: "table.doc-table", runtime: { generated: ["colgroup[data-doc-columns]", ".doc-scrollbars"], attrs: { "table.doc-table": ["data-doc-sortable-ready", "data-doc-filled"], ".doc-table-wrap": ["data-doc-min-width", "data-doc-layout", "data-doc-whole"], "th, td": ["data-column-kind", "data-column-wrap", "data-run-wrap", "data-doc-edge"] }, classes: { "table.doc-table": ["doc-table--auto"] }, internal: ["doc-code-run", "doc-table-sort-button", "doc-scrollbar*", "data-doc-sort-arrow", "data-active", "data-drag", "data-x", "data-y", "data-more"] } }, { id: "columns", match: ".doc-columns" }, { id: "figure", match: "figure" }, { id: "chart", match: "[data-doc-chart]", runtime: { attrs: { "[data-doc-chart]": ["data-doc-layout"] }, classes: { "[data-doc-chart]": ["doc-chart"] }, internal: ["doc-chart-message", "data-missing"] } }, { id: "image", match: "figure.doc-image", runtime: { generated: ["dialog.doc-zoom"], attrs: { "img[data-doc-zoom]": ["data-doc-zoom", "tabindex", "role", "aria-haspopup", "aria-label"] }, root: { classes: ["doc-zoom-open", "doc-zoom-gutter", "doc-zoom-hover"] }, internal: ["doc-zoom-*"] } }, { id: "file", match: "figure.doc-file" }, { id: "bookmark", match: "figure.doc-bookmark" }, { id: "embed", match: "figure.doc-embed", runtime: { attrs: { "iframe.doc-embed-frame": ["data-doc-blob"] } } }, { id: "diff", match: ".doc-diff", runtime: { generated: [".doc-diff-body", ".doc-diff-stats"], internal: ["doc-diff-added", "doc-diff-removed"] } }, { id: "icon", match: ".doc-icon", runtime: { internal: ["data-doc-tab-icon"] } }, { id: "installed", match: "div[data-doc-component], section[data-doc-component]", runtime: { generated: [".doc-component-note", ".doc-component-data"], attrs: { "[data-doc-fallback]": ["data-doc-fallback"], "[data-doc-fallback-control]": ["data-doc-fallback-control", "inert"] }, internal: ["data-doc-package", "doc-component-more", "doc-component-one", "doc-component-line", "doc-component-short", "doc-dragging"] } }, { id: "state", match: "[data-doc-bind], [data-doc-show]", runtime: { generated: [".doc-choice"], attrs: { "[data-doc-show]": ["hidden"] }, state: { "button[data-doc-bind]": ["aria-pressed"] }, internal: ["doc-choice-*"] } }];
|
|
8
8
|
|
|
9
9
|
// src/render/kit/runtime/bindings.js
|
|
10
10
|
var global = globalThis;
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
let state = null;
|
|
27
27
|
const later = /* @__PURE__ */ new Map();
|
|
28
28
|
const listeners = /* @__PURE__ */ new Set();
|
|
29
|
-
function
|
|
29
|
+
function open2() {
|
|
30
30
|
if (state) return state;
|
|
31
31
|
if (!global.DocState) throw new Error("State bindings require /kit/state.js to be loaded.");
|
|
32
32
|
const defaults = {};
|
|
@@ -49,11 +49,11 @@
|
|
|
49
49
|
});
|
|
50
50
|
return state;
|
|
51
51
|
}
|
|
52
|
-
const known = (key) => later.has(key) || Object.prototype.hasOwnProperty.call(
|
|
52
|
+
const known = (key) => later.has(key) || Object.prototype.hasOwnProperty.call(open2().snapshot(), key);
|
|
53
53
|
const store = {
|
|
54
54
|
get(key) {
|
|
55
55
|
if (later.has(key)) return later.get(key);
|
|
56
|
-
return
|
|
56
|
+
return open2().get(key, "");
|
|
57
57
|
},
|
|
58
58
|
set(key, value) {
|
|
59
59
|
if (!known(key)) later.set(key, value);
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
for (const listener of listeners) listener(key);
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
|
-
if (JSON.stringify(
|
|
65
|
+
if (JSON.stringify(open2().get(key)) !== JSON.stringify(value)) open2().set(key, value);
|
|
66
66
|
},
|
|
67
67
|
/** Calls listener(key) when a key changes; returns what stops it. */
|
|
68
68
|
subscribe(listener) {
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
const key = element.getAttribute("data-doc-bind").trim();
|
|
76
76
|
if (!key) return null;
|
|
77
77
|
if (!known(key)) later.set(key, initial(element) ?? "");
|
|
78
|
-
const
|
|
78
|
+
const show2 = () => {
|
|
79
79
|
const value = store.get(key);
|
|
80
80
|
if (element.localName === "details") {
|
|
81
81
|
if (element.open !== Boolean(value)) element.open = Boolean(value);
|
|
@@ -99,25 +99,286 @@
|
|
|
99
99
|
};
|
|
100
100
|
const event = element.localName === "details" ? "toggle" : element.localName === "button" ? "click" : element.localName === "select" || element.type === "checkbox" || element.type === "radio" ? "change" : "input";
|
|
101
101
|
element.addEventListener(event, write, { signal });
|
|
102
|
-
const stop = store.subscribe((changed) => changed === key &&
|
|
103
|
-
|
|
102
|
+
const stop = store.subscribe((changed) => changed === key && show2());
|
|
103
|
+
show2();
|
|
104
104
|
return { destroy: stop };
|
|
105
105
|
}
|
|
106
106
|
function bindShow(element) {
|
|
107
107
|
const { key, value } = showOf(element);
|
|
108
108
|
if (!key) return null;
|
|
109
|
-
const
|
|
109
|
+
const show2 = () => {
|
|
110
110
|
const chosen = store.get(key);
|
|
111
111
|
const hidden = chosen !== "" && chosen !== null && chosen !== void 0 && String(chosen) !== value;
|
|
112
112
|
if (element.hidden !== hidden) element.hidden = hidden;
|
|
113
113
|
};
|
|
114
|
-
const stop = store.subscribe((changed) => changed === key &&
|
|
115
|
-
|
|
114
|
+
const stop = store.subscribe((changed) => changed === key && show2());
|
|
115
|
+
show2();
|
|
116
116
|
return { destroy: stop };
|
|
117
117
|
}
|
|
118
118
|
return { store, bindControl, bindShow, CONTROLS };
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
+
// src/render/kit/runtime/choice.js
|
|
122
|
+
var MENU = "doc-choice";
|
|
123
|
+
var CHECK = '<svg class="doc-choice-check" viewBox="0 0 16 16" aria-hidden="true"><path d="m3.5 8.5 3 3 6-7"/></svg>';
|
|
124
|
+
var GAP = 4;
|
|
125
|
+
var EDGE = 8;
|
|
126
|
+
var LEAST_HEIGHT = 96;
|
|
127
|
+
var TYPING = 700;
|
|
128
|
+
var open = null;
|
|
129
|
+
function rowsOf(options) {
|
|
130
|
+
const rows = [];
|
|
131
|
+
for (const entry of Array.isArray(options) ? options : []) {
|
|
132
|
+
if (Array.isArray(entry)) rows.push({ value: String(entry[0]), label: String(entry[1] ?? entry[0]) });
|
|
133
|
+
else if (entry !== null && typeof entry === "object" && "group" in entry) rows.push({ group: String(entry.group) });
|
|
134
|
+
else if (entry !== null && typeof entry === "object") rows.push({ value: String(entry.value), label: String(entry.label ?? entry.value), disabled: Boolean(entry.disabled) });
|
|
135
|
+
else rows.push({ value: String(entry), label: String(entry) });
|
|
136
|
+
}
|
|
137
|
+
return rows;
|
|
138
|
+
}
|
|
139
|
+
var choosable = (row) => row.value !== void 0 && !row.disabled;
|
|
140
|
+
function show(anchor, rows, { current = -1, signal = null, label = "" } = {}) {
|
|
141
|
+
open?.finish(null);
|
|
142
|
+
const doc = anchor.ownerDocument;
|
|
143
|
+
const view = doc.defaultView;
|
|
144
|
+
const menu = doc.createElement("div");
|
|
145
|
+
menu.className = MENU;
|
|
146
|
+
menu.setAttribute("role", "listbox");
|
|
147
|
+
if (label) menu.setAttribute("aria-label", label);
|
|
148
|
+
const nodes = rows.map((row, index) => {
|
|
149
|
+
const node = doc.createElement("div");
|
|
150
|
+
if (row.group !== void 0) {
|
|
151
|
+
node.className = "doc-choice-group";
|
|
152
|
+
node.setAttribute("role", "presentation");
|
|
153
|
+
node.textContent = row.group;
|
|
154
|
+
} else {
|
|
155
|
+
node.className = "doc-choice-row";
|
|
156
|
+
node.setAttribute("role", "option");
|
|
157
|
+
node.setAttribute("aria-selected", String(index === current));
|
|
158
|
+
if (row.disabled) node.setAttribute("aria-disabled", "true");
|
|
159
|
+
const words = doc.createElement("span");
|
|
160
|
+
words.className = "doc-choice-label";
|
|
161
|
+
words.textContent = row.label;
|
|
162
|
+
node.append(words);
|
|
163
|
+
if (index === current) node.insertAdjacentHTML("beforeend", CHECK);
|
|
164
|
+
}
|
|
165
|
+
menu.append(node);
|
|
166
|
+
return node;
|
|
167
|
+
});
|
|
168
|
+
const first = () => rows.findIndex(choosable);
|
|
169
|
+
let active = current >= 0 && choosable(rows[current]) ? current : first();
|
|
170
|
+
const light = () => nodes.forEach((node, index) => node.classList.toggle("is-active", index === active));
|
|
171
|
+
const reveal2 = () => {
|
|
172
|
+
const node = nodes[active];
|
|
173
|
+
if (!node) return;
|
|
174
|
+
if (node.offsetTop < menu.scrollTop) menu.scrollTop = node.offsetTop - 4;
|
|
175
|
+
else if (node.offsetTop + node.offsetHeight > menu.scrollTop + menu.clientHeight) menu.scrollTop = node.offsetTop + node.offsetHeight - menu.clientHeight + 4;
|
|
176
|
+
};
|
|
177
|
+
const move = (to) => {
|
|
178
|
+
if (to < 0 || to >= rows.length || !choosable(rows[to])) return;
|
|
179
|
+
active = to;
|
|
180
|
+
light();
|
|
181
|
+
reveal2();
|
|
182
|
+
};
|
|
183
|
+
const step = (from, by) => {
|
|
184
|
+
for (let at = from + by; at >= 0 && at < rows.length; at += by) if (choosable(rows[at])) return at;
|
|
185
|
+
return from;
|
|
186
|
+
};
|
|
187
|
+
const place = () => {
|
|
188
|
+
const box = anchor.getBoundingClientRect();
|
|
189
|
+
const root = doc.documentElement;
|
|
190
|
+
const width = root.clientWidth || view.innerWidth;
|
|
191
|
+
const height = view.innerHeight;
|
|
192
|
+
menu.style.minWidth = `${Math.round(box.width)}px`;
|
|
193
|
+
menu.style.maxHeight = "";
|
|
194
|
+
menu.style.left = "0px";
|
|
195
|
+
menu.style.top = "0px";
|
|
196
|
+
const size = menu.getBoundingClientRect();
|
|
197
|
+
const below = height - box.bottom - GAP - EDGE;
|
|
198
|
+
const above = box.top - GAP - EDGE;
|
|
199
|
+
const up = size.height > below && above > below;
|
|
200
|
+
const room = Math.max(LEAST_HEIGHT, up ? above : below);
|
|
201
|
+
menu.style.maxHeight = `${Math.floor(room)}px`;
|
|
202
|
+
const tall = Math.min(size.height, room);
|
|
203
|
+
const rtl = view.getComputedStyle(anchor).direction === "rtl";
|
|
204
|
+
const left = rtl ? box.right - size.width : box.left;
|
|
205
|
+
menu.style.left = `${Math.round(Math.max(EDGE, Math.min(left, width - size.width - EDGE)))}px`;
|
|
206
|
+
menu.style.top = `${Math.round(up ? box.top - GAP - tall : box.bottom + GAP)}px`;
|
|
207
|
+
};
|
|
208
|
+
return new Promise((resolve) => {
|
|
209
|
+
const controller = new AbortController();
|
|
210
|
+
const { signal: own } = controller;
|
|
211
|
+
let typed = "";
|
|
212
|
+
let typedAt = 0;
|
|
213
|
+
let done = false;
|
|
214
|
+
const watcher = new view.MutationObserver((records) => {
|
|
215
|
+
if (!anchor.isConnected || anchor.localName === "select" && records.some((record) => anchor.contains(record.target))) finish2(null);
|
|
216
|
+
});
|
|
217
|
+
function finish2(row, refocus = true) {
|
|
218
|
+
if (done) return;
|
|
219
|
+
done = true;
|
|
220
|
+
if (open?.finish === finish2) open = null;
|
|
221
|
+
controller.abort();
|
|
222
|
+
watcher.disconnect();
|
|
223
|
+
try {
|
|
224
|
+
menu.hidePopover?.();
|
|
225
|
+
} catch {
|
|
226
|
+
}
|
|
227
|
+
menu.remove();
|
|
228
|
+
if (refocus && anchor.isConnected) anchor.focus({ preventScroll: true });
|
|
229
|
+
resolve(row);
|
|
230
|
+
}
|
|
231
|
+
open = { finish: finish2, anchor };
|
|
232
|
+
signal?.addEventListener("abort", () => finish2(null, false), { once: true, signal: own });
|
|
233
|
+
if (signal?.aborted) return finish2(null, false);
|
|
234
|
+
(anchor.closest?.("dialog[open]") ?? doc.body).append(menu);
|
|
235
|
+
menu.setAttribute("popover", "manual");
|
|
236
|
+
try {
|
|
237
|
+
menu.showPopover();
|
|
238
|
+
} catch {
|
|
239
|
+
menu.removeAttribute("popover");
|
|
240
|
+
}
|
|
241
|
+
light();
|
|
242
|
+
place();
|
|
243
|
+
reveal2();
|
|
244
|
+
const inside = (target) => target instanceof view.Node && menu.contains(target);
|
|
245
|
+
view.addEventListener("pointerdown", (event) => {
|
|
246
|
+
if (!inside(event.target) && !(event.target instanceof view.Node && anchor.contains(event.target))) finish2(null, false);
|
|
247
|
+
}, { capture: true, signal: own });
|
|
248
|
+
view.addEventListener("scroll", (event) => {
|
|
249
|
+
if (!inside(event.target)) finish2(null, false);
|
|
250
|
+
}, { capture: true, signal: own });
|
|
251
|
+
view.addEventListener("resize", () => finish2(null, false), { signal: own });
|
|
252
|
+
view.addEventListener("blur", () => finish2(null, false), { signal: own });
|
|
253
|
+
watcher.observe(doc.documentElement, { childList: true, subtree: true });
|
|
254
|
+
view.addEventListener("keydown", (event) => {
|
|
255
|
+
if (event.isComposing || event.keyCode === 229) return;
|
|
256
|
+
const take = () => {
|
|
257
|
+
event.preventDefault();
|
|
258
|
+
event.stopImmediatePropagation();
|
|
259
|
+
};
|
|
260
|
+
const key = event.key;
|
|
261
|
+
if (event.repeat && (key === "Enter" || key === " ")) take();
|
|
262
|
+
else if (key === "Escape") {
|
|
263
|
+
take();
|
|
264
|
+
finish2(null);
|
|
265
|
+
} else if (key === "Tab") {
|
|
266
|
+
finish2(null, false);
|
|
267
|
+
} else if (key === "ArrowDown" || key === "ArrowUp") {
|
|
268
|
+
take();
|
|
269
|
+
if (event.altKey) finish2(choosable(rows[active] ?? {}) ? rows[active] : null);
|
|
270
|
+
else move(step(active, key === "ArrowDown" ? 1 : -1));
|
|
271
|
+
} else if (key === "Home" || key === "End") {
|
|
272
|
+
take();
|
|
273
|
+
move(key === "Home" ? first() : rows.length - 1 - [...rows].reverse().findIndex(choosable));
|
|
274
|
+
} else if (key === "PageDown" || key === "PageUp") {
|
|
275
|
+
take();
|
|
276
|
+
const page = Math.max(1, Math.floor(menu.clientHeight / 28) - 1);
|
|
277
|
+
let to = active;
|
|
278
|
+
for (let count = 0; count < page; count++) to = step(to, key === "PageDown" ? 1 : -1);
|
|
279
|
+
move(to);
|
|
280
|
+
} else if (key === "Enter" || key === " " && typed === "") {
|
|
281
|
+
take();
|
|
282
|
+
if (choosable(rows[active] ?? {})) finish2(rows[active]);
|
|
283
|
+
} else if (key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {
|
|
284
|
+
take();
|
|
285
|
+
typed = Date.now() - typedAt > TYPING ? key.toLowerCase() : typed + key.toLowerCase();
|
|
286
|
+
typedAt = Date.now();
|
|
287
|
+
const same = [...typed].every((letter) => letter === typed[0]);
|
|
288
|
+
const at = (from) => rows.findIndex((row, index) => index >= from && choosable(row) && row.label.trim().toLowerCase().startsWith(same ? typed[0] : typed));
|
|
289
|
+
const found = same && typed.length > 1 ? at(active + 1) >= 0 ? at(active + 1) : at(0) : at(0);
|
|
290
|
+
if (found >= 0) move(found);
|
|
291
|
+
setTimeout(() => {
|
|
292
|
+
if (Date.now() - typedAt >= TYPING) typed = "";
|
|
293
|
+
}, TYPING + 20);
|
|
294
|
+
}
|
|
295
|
+
}, { capture: true, signal: own });
|
|
296
|
+
menu.addEventListener("pointermove", (event) => {
|
|
297
|
+
const node = event.target instanceof view.Element ? event.target.closest(".doc-choice-row") : null;
|
|
298
|
+
const at = node ? nodes.indexOf(node) : -1;
|
|
299
|
+
if (at >= 0 && at !== active && choosable(rows[at])) {
|
|
300
|
+
active = at;
|
|
301
|
+
light();
|
|
302
|
+
}
|
|
303
|
+
}, { signal: own });
|
|
304
|
+
menu.addEventListener("pointerdown", (event) => {
|
|
305
|
+
event.preventDefault();
|
|
306
|
+
event.stopPropagation();
|
|
307
|
+
}, { signal: own });
|
|
308
|
+
menu.addEventListener("click", (event) => {
|
|
309
|
+
event.preventDefault();
|
|
310
|
+
event.stopPropagation();
|
|
311
|
+
const node = event.target instanceof view.Element ? event.target.closest(".doc-choice-row") : null;
|
|
312
|
+
const at = node ? nodes.indexOf(node) : -1;
|
|
313
|
+
if (at >= 0 && choosable(rows[at])) finish2(rows[at]);
|
|
314
|
+
}, { signal: own });
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
async function chooseIn(select) {
|
|
318
|
+
const rows = [];
|
|
319
|
+
const current = { at: -1 };
|
|
320
|
+
const walk = (parent, disabled) => {
|
|
321
|
+
for (const child of parent.children) {
|
|
322
|
+
if (child.localName === "optgroup") {
|
|
323
|
+
if (child.label) rows.push({ group: child.label });
|
|
324
|
+
walk(child, disabled || child.disabled);
|
|
325
|
+
} else if (child.localName === "option" && !child.hidden) {
|
|
326
|
+
if (child.selected) current.at = rows.length;
|
|
327
|
+
rows.push({ value: child.value, label: child.label || child.textContent.trim(), disabled: disabled || child.disabled, option: child });
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
walk(select, false);
|
|
332
|
+
const row = await show(select, rows, { current: current.at, label: select.getAttribute("aria-label") ?? "" });
|
|
333
|
+
if (!row?.option || !select.isConnected || row.option.index === select.selectedIndex) return;
|
|
334
|
+
select.selectedIndex = row.option.index;
|
|
335
|
+
const view = select.ownerDocument.defaultView;
|
|
336
|
+
select.dispatchEvent(new view.Event("input", { bubbles: true, composed: true }));
|
|
337
|
+
select.dispatchEvent(new view.Event("change", { bubbles: true }));
|
|
338
|
+
}
|
|
339
|
+
async function choose(anchor, { options, value = null, label = "", signal } = {}) {
|
|
340
|
+
if (anchor?.nodeType !== 1) throw new Error("DocKit.choose: the first argument is the element the menu opens under");
|
|
341
|
+
if (open?.anchor === anchor) {
|
|
342
|
+
open.finish(null);
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
const rows = rowsOf(options);
|
|
346
|
+
const current = value === null || value === void 0 ? -1 : rows.findIndex((row2) => row2.value === String(value));
|
|
347
|
+
const row = await show(anchor, rows, { current, signal, label });
|
|
348
|
+
return row?.value ?? null;
|
|
349
|
+
}
|
|
350
|
+
var popup = (select) => {
|
|
351
|
+
if (!(select instanceof select.ownerDocument.defaultView.HTMLSelectElement)) return false;
|
|
352
|
+
if (select.multiple || Number(select.getAttribute("size")) > 1 || select.disabled) return false;
|
|
353
|
+
return !select.closest("fieldset:disabled");
|
|
354
|
+
};
|
|
355
|
+
var selectAt = (event, view) => {
|
|
356
|
+
const node = event.target instanceof view.Element ? event.target.closest("select") : null;
|
|
357
|
+
return node && popup(node) ? node : null;
|
|
358
|
+
};
|
|
359
|
+
function startChoices(doc) {
|
|
360
|
+
const view = doc.defaultView;
|
|
361
|
+
view.addEventListener("mousedown", (event) => {
|
|
362
|
+
if (event.button !== 0 || event.ctrlKey) return;
|
|
363
|
+
const select = selectAt(event, view);
|
|
364
|
+
if (!select) return;
|
|
365
|
+
event.preventDefault();
|
|
366
|
+
select.focus({ preventScroll: true, focusVisible: false });
|
|
367
|
+
if (open?.anchor === select) open.finish(null);
|
|
368
|
+
else void chooseIn(select);
|
|
369
|
+
}, true);
|
|
370
|
+
view.addEventListener("keydown", (event) => {
|
|
371
|
+
if (event.isComposing || event.keyCode === 229 || event.defaultPrevented) return;
|
|
372
|
+
const select = selectAt(event, view);
|
|
373
|
+
if (!select || open) return;
|
|
374
|
+
const opens = event.key === " " || event.key === "Enter" || event.key === "F4" || event.key === "ArrowDown" || event.key === "ArrowUp";
|
|
375
|
+
if (!opens || event.ctrlKey || event.metaKey || event.shiftKey) return;
|
|
376
|
+
event.preventDefault();
|
|
377
|
+
event.stopImmediatePropagation();
|
|
378
|
+
if (!event.repeat) void chooseIn(select);
|
|
379
|
+
}, true);
|
|
380
|
+
}
|
|
381
|
+
|
|
121
382
|
// src/render/kit/runtime/embeds.js
|
|
122
383
|
var sources = /* @__PURE__ */ new Map();
|
|
123
384
|
function showEmbed(figure) {
|
|
@@ -196,11 +457,28 @@
|
|
|
196
457
|
return each.map((weight) => weight / all);
|
|
197
458
|
}
|
|
198
459
|
|
|
460
|
+
// src/shared/long-runs.mjs
|
|
461
|
+
var LONG_RUN = 20;
|
|
462
|
+
var RUNS = /[^\s\u2000-\u206f\u2e80-\u9fff\uac00-\ud7af\uf900-\ufaff\ufe30-\ufe4f\uff00-\uffef]+/gu;
|
|
463
|
+
var PIECES = /(?<=[-?])/u;
|
|
464
|
+
var long = (run) => run.length > LONG_RUN && run.split(PIECES).some((piece) => [...piece].length > LONG_RUN);
|
|
465
|
+
function longRuns(text) {
|
|
466
|
+
const found = [];
|
|
467
|
+
if (text.length <= LONG_RUN) return found;
|
|
468
|
+
for (const match of text.matchAll(RUNS)) if (long(match[0])) found.push({ index: match.index, length: match[0].length });
|
|
469
|
+
return found;
|
|
470
|
+
}
|
|
471
|
+
function holdsLongRun(text) {
|
|
472
|
+
if (text.length <= LONG_RUN) return false;
|
|
473
|
+
for (const match of text.matchAll(RUNS)) if (long(match[0])) return true;
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
476
|
+
|
|
199
477
|
// src/render/kit/words.js
|
|
200
478
|
var RUNTIME = {
|
|
201
|
-
"component-missing": { zh: "\
|
|
202
|
-
"component-broken": { zh: "\
|
|
203
|
-
"component-silent": { zh: "\
|
|
479
|
+
"component-missing": { zh: "\u81EA\u5B9A\u4E49\u5757 {0} \u4E0D\u5728\u8FD9\u4E2A\u5DE5\u4F5C\u533A\u91CC\uFF0C\u8FD9\u91CC\u53EA\u663E\u793A\u5B83\u7684\u5185\u5BB9\u3002", en: "The custom block {0} is not in this workspace: only what it holds is shown." },
|
|
480
|
+
"component-broken": { zh: "\u81EA\u5B9A\u4E49\u5757 {0} \u6CA1\u6709\u52A0\u8F7D\uFF0C\u8FD9\u91CC\u53EA\u663E\u793A\u5B83\u7684\u5185\u5BB9\u3002\u539F\u56E0\uFF1A{1}", en: "The custom block {0} did not load: only what it holds is shown. Why: {1}" },
|
|
481
|
+
"component-silent": { zh: "\u81EA\u5B9A\u4E49\u5757 {0} \u7684\u811A\u672C\u6CA1\u6709\u542F\u52A8\u5B83\uFF0C\u8FD9\u91CC\u53EA\u663E\u793A\u5B83\u7684\u5185\u5BB9\uFF1A\u770B\u63A7\u5236\u53F0\u91CC\u7684\u9519\u8BEF\u3002", en: "The script of the custom block {0} did not start it: only what it holds is shown. See the console for the error." },
|
|
204
482
|
"value-true": { zh: "\u662F", en: "Yes" },
|
|
205
483
|
"value-false": { zh: "\u5426", en: "No" },
|
|
206
484
|
"value-empty": { zh: "\uFF08\u7A7A\uFF09", en: "(empty)" },
|
|
@@ -213,7 +491,11 @@
|
|
|
213
491
|
"open-image": { zh: "\u653E\u5927\u67E5\u770B\u56FE\u7247", en: "View the image larger" },
|
|
214
492
|
"open-image-named": { zh: "\u653E\u5927\u67E5\u770B\uFF1A{0}", en: "View larger: {0}" },
|
|
215
493
|
"close": { zh: "\u5173\u95ED", en: "Close" },
|
|
216
|
-
"flowchart": FLOW_LABEL
|
|
494
|
+
"flowchart": FLOW_LABEL,
|
|
495
|
+
// net.js: a block whose fetch waits for the reader's consent, its bar's line and its button.
|
|
496
|
+
"net-why": { zh: "\u8FD9\u4E2A\u5757\u8981\u8054\u7F51\u624D\u80FD\u663E\u793A\u5185\u5BB9", en: "This block needs the internet to show its content" },
|
|
497
|
+
"net-allow": { zh: "\u5141\u8BB8\u8BBF\u95EE {0}", en: "Allow {0}" },
|
|
498
|
+
"net-allow-many": { zh: "\u5141\u8BB8\u8BBF\u95EE {0} \u7B49 {1} \u4E2A\u7F51\u7AD9", en: "Allow {0} and others ({1} sites)" }
|
|
217
499
|
};
|
|
218
500
|
var UI_LANGUAGE = "data-ge-language";
|
|
219
501
|
function kitLanguage(root = globalThis.document?.documentElement) {
|
|
@@ -225,7 +507,7 @@
|
|
|
225
507
|
const entry = table2[key];
|
|
226
508
|
if (!entry) throw new Error(`The kit has no word "${key}" here (src/render/kit/words.js).`);
|
|
227
509
|
const text = entry[language] ?? entry.zh;
|
|
228
|
-
return values.length === 0 ? text : text.replace(/\{(\d+)\}/g, (
|
|
510
|
+
return values.length === 0 ? text : text.replace(/\{(\d+)\}/g, (whole2, index) => index < values.length ? String(values[index]) : whole2);
|
|
229
511
|
}
|
|
230
512
|
var sayer = (table2) => (key, ...values) => wordIn(table2, kitLanguage(), key, ...values);
|
|
231
513
|
var sayRuntime = /* @__PURE__ */ sayer(RUNTIME);
|
|
@@ -234,7 +516,7 @@
|
|
|
234
516
|
// src/render/kit/runtime/flowchart.js
|
|
235
517
|
var CJK = "\\u2e80-\\u9fff\\uac00-\\ud7af\\uf900-\\ufaff\\uff00-\\uffef";
|
|
236
518
|
var WORDS = new RegExp(`[${CJK}]|[^\\s${CJK}]+`, "g");
|
|
237
|
-
var
|
|
519
|
+
var PIECES2 = new RegExp(`[${CJK}]|[^\\s${CJK}]+|\\s+`, "g");
|
|
238
520
|
var WIDE = new RegExp(`[${CJK}]`);
|
|
239
521
|
function linesOf(pieces, width) {
|
|
240
522
|
let lines = 0;
|
|
@@ -372,11 +654,23 @@
|
|
|
372
654
|
return context.measureText(text).width;
|
|
373
655
|
};
|
|
374
656
|
}
|
|
375
|
-
function piecesOf(text, style) {
|
|
657
|
+
function piecesOf(text, style, split = true) {
|
|
376
658
|
const measure = measurer(style);
|
|
377
659
|
const space = measure(" ");
|
|
378
|
-
const
|
|
379
|
-
|
|
660
|
+
const anywhere = split && style.wordBreak === "break-all";
|
|
661
|
+
const pieces = [];
|
|
662
|
+
let widest = 0;
|
|
663
|
+
for (const piece of String(text).match(PIECES2) ?? []) {
|
|
664
|
+
if (/^\s/.test(piece)) {
|
|
665
|
+
pieces.push({ width: space, space: true });
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
const width = measure(piece);
|
|
669
|
+
widest = Math.max(widest, width);
|
|
670
|
+
if (split && !WIDE.test(piece) && (anywhere || holdsLongRun(piece))) for (const character of piece) pieces.push({ width: measure(character) });
|
|
671
|
+
else pieces.push({ width });
|
|
672
|
+
}
|
|
673
|
+
return { pieces, widest };
|
|
380
674
|
}
|
|
381
675
|
function inlinePieces(nodes, style) {
|
|
382
676
|
const holds = (node) => node.nodeType === 1 && (node.tagName === "CODE" || node.querySelector("code"));
|
|
@@ -390,23 +684,27 @@
|
|
|
390
684
|
} else if (node.nodeType === 1) node.childNodes.forEach((child) => walk(child, code ?? (node.tagName === "CODE" ? node : null)));
|
|
391
685
|
};
|
|
392
686
|
nodes.forEach((node) => walk(node, null));
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
687
|
+
const collect = (split) => {
|
|
688
|
+
const pieces = [];
|
|
689
|
+
let joins = false;
|
|
690
|
+
for (const { text, code } of segments) {
|
|
691
|
+
if (!text) continue;
|
|
692
|
+
const look = code ? getComputedStyle(code) : style;
|
|
693
|
+
const own = piecesOf(text, look, split).pieces;
|
|
694
|
+
if (code && own.length) {
|
|
695
|
+
own[0].width += pixels(look.paddingLeft) + pixels(look.borderLeftWidth);
|
|
696
|
+
own.at(-1).width += pixels(look.paddingRight) + pixels(look.borderRightWidth);
|
|
697
|
+
}
|
|
698
|
+
own.forEach((piece, at) => {
|
|
699
|
+
if (at === 0 && joins && !piece.space && !WIDE.test(text[0])) pieces.at(-1).width += piece.width;
|
|
700
|
+
else pieces.push(piece);
|
|
701
|
+
});
|
|
702
|
+
joins = !/\s$/.test(text) && !WIDE.test(text.at(-1));
|
|
703
|
+
}
|
|
704
|
+
return { pieces, widest: Math.max(0, ...pieces.filter((piece) => !piece.space).map((piece) => piece.width)) };
|
|
705
|
+
};
|
|
706
|
+
const whole2 = collect(false);
|
|
707
|
+
return { pieces: collect(true).pieces, widest: whole2.widest };
|
|
410
708
|
}
|
|
411
709
|
function contentOf(elements) {
|
|
412
710
|
const blocks = [];
|
|
@@ -456,8 +754,8 @@
|
|
|
456
754
|
const [first] = blocks;
|
|
457
755
|
if (short || first?.tagName !== "P") return { nodes: ownNodes(item2), style, line: lineOf(style), content: blocks, short };
|
|
458
756
|
const look = getComputedStyle(first);
|
|
459
|
-
const
|
|
460
|
-
return { nodes: [...first.childNodes], style:
|
|
757
|
+
const whole2 = first.children.length === 1 && first.textContent === first.firstElementChild.textContent ? getComputedStyle(first.firstElementChild) : look;
|
|
758
|
+
return { nodes: [...first.childNodes], style: whole2, line: lineOf(look), content: blocks.slice(1), short };
|
|
461
759
|
}
|
|
462
760
|
function stepShape(item2) {
|
|
463
761
|
const style = getComputedStyle(item2);
|
|
@@ -559,10 +857,149 @@
|
|
|
559
857
|
}
|
|
560
858
|
var FLOWCHART = `ol.${FLOW}`;
|
|
561
859
|
|
|
860
|
+
// src/render/kit/runtime/gestures.js
|
|
861
|
+
var listen = (target, type, run, signal, options = {}) => target.addEventListener(type, run, { ...options, signal });
|
|
862
|
+
var DRAGGING = "doc-dragging";
|
|
863
|
+
function fieldIn(field, { commit, signal } = {}) {
|
|
864
|
+
if (typeof commit !== "function") throw new Error("DocKit.input: commit(value) is a function");
|
|
865
|
+
let committed = field.value;
|
|
866
|
+
let composing = false;
|
|
867
|
+
let leftComposing = false;
|
|
868
|
+
const done = () => {
|
|
869
|
+
if (composing || field.value === committed) return;
|
|
870
|
+
committed = field.value;
|
|
871
|
+
commit(committed);
|
|
872
|
+
};
|
|
873
|
+
listen(field, "compositionstart", () => {
|
|
874
|
+
composing = true;
|
|
875
|
+
}, signal);
|
|
876
|
+
listen(field, "compositionend", () => {
|
|
877
|
+
composing = false;
|
|
878
|
+
if (leftComposing) {
|
|
879
|
+
leftComposing = false;
|
|
880
|
+
done();
|
|
881
|
+
}
|
|
882
|
+
}, signal);
|
|
883
|
+
listen(field, "keydown", (event) => {
|
|
884
|
+
if (composing || event.isComposing || event.keyCode === 229) return;
|
|
885
|
+
if (event.key === "Enter" && field.localName !== "select" && (field.localName !== "textarea" || event.ctrlKey || event.metaKey)) {
|
|
886
|
+
event.preventDefault();
|
|
887
|
+
done();
|
|
888
|
+
} else if (event.key === "Escape") {
|
|
889
|
+
event.preventDefault();
|
|
890
|
+
event.stopPropagation();
|
|
891
|
+
field.value = committed;
|
|
892
|
+
field.blur();
|
|
893
|
+
}
|
|
894
|
+
}, signal);
|
|
895
|
+
listen(field, "blur", () => {
|
|
896
|
+
if (composing) leftComposing = true;
|
|
897
|
+
else done();
|
|
898
|
+
}, signal);
|
|
899
|
+
if (field.localName === "select") listen(field, "change", done, signal);
|
|
900
|
+
return Object.freeze({
|
|
901
|
+
/**
|
|
902
|
+
* The value the file holds now (drawn from a part): shown, unless the reader is typing another in
|
|
903
|
+
* the field, whose words stay; either way it is what is committed against.
|
|
904
|
+
*/
|
|
905
|
+
set(value) {
|
|
906
|
+
const typing = field.ownerDocument.activeElement === field && field.value !== committed;
|
|
907
|
+
committed = String(value);
|
|
908
|
+
if (!typing) field.value = committed;
|
|
909
|
+
},
|
|
910
|
+
/** The value committed last, or set. */
|
|
911
|
+
get value() {
|
|
912
|
+
return committed;
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
function dragIn(area, { items, handle = null, threshold = 4, enabled = () => true, marker = null, over, drop, signal } = {}) {
|
|
917
|
+
if (typeof items !== "string" || typeof over !== "function" || typeof drop !== "function") throw new Error("DocKit.drag: items (a selector), over(x, y, item) and drop(item, spot) are given");
|
|
918
|
+
const view = area.ownerDocument.defaultView;
|
|
919
|
+
let drag = null;
|
|
920
|
+
const end = () => {
|
|
921
|
+
drag?.item.classList.remove(DRAGGING);
|
|
922
|
+
marker?.remove();
|
|
923
|
+
drag = null;
|
|
924
|
+
};
|
|
925
|
+
const noClick = () => {
|
|
926
|
+
const swallow = (event) => {
|
|
927
|
+
event.preventDefault();
|
|
928
|
+
event.stopPropagation();
|
|
929
|
+
};
|
|
930
|
+
view.addEventListener("click", swallow, { capture: true, once: true });
|
|
931
|
+
view.setTimeout(() => view.removeEventListener("click", swallow, { capture: true }), 0);
|
|
932
|
+
};
|
|
933
|
+
listen(area, "pointerdown", (event) => {
|
|
934
|
+
const at = event.target instanceof view.Element ? event.target : null;
|
|
935
|
+
const item2 = at?.closest(items);
|
|
936
|
+
if (!item2 || !area.contains(item2) || event.button !== 0 || handle && !at.closest(handle) || !enabled()) return;
|
|
937
|
+
drag = { item: item2, x: event.clientX, y: event.clientY, pointer: event.pointerId, moving: false };
|
|
938
|
+
item2.setPointerCapture?.(event.pointerId);
|
|
939
|
+
}, signal);
|
|
940
|
+
listen(area, "pointermove", (event) => {
|
|
941
|
+
if (!drag || event.pointerId !== drag.pointer) return;
|
|
942
|
+
if (!drag.moving && Math.hypot(event.clientX - drag.x, event.clientY - drag.y) < threshold) return;
|
|
943
|
+
drag.moving = true;
|
|
944
|
+
drag.item.classList.add(DRAGGING);
|
|
945
|
+
const spot = over(event.clientX, event.clientY, drag.item);
|
|
946
|
+
if (spot && marker) spot.into.insertBefore(marker, spot.before ?? null);
|
|
947
|
+
else marker?.remove();
|
|
948
|
+
}, signal);
|
|
949
|
+
listen(area, "pointerup", (event) => {
|
|
950
|
+
if (!drag || event.pointerId !== drag.pointer) return;
|
|
951
|
+
const { item: item2, moving } = drag;
|
|
952
|
+
const spot = moving ? over(event.clientX, event.clientY, item2) : null;
|
|
953
|
+
end();
|
|
954
|
+
if (!moving) return;
|
|
955
|
+
noClick();
|
|
956
|
+
if (spot) drop(item2, spot);
|
|
957
|
+
}, signal);
|
|
958
|
+
listen(area, "pointercancel", end, signal);
|
|
959
|
+
listen(area, "lostpointercapture", (event) => {
|
|
960
|
+
if (drag && event.pointerId === drag.pointer) end();
|
|
961
|
+
}, signal);
|
|
962
|
+
listen(view, "keydown", (event) => {
|
|
963
|
+
if (!drag || event.key !== "Escape") return;
|
|
964
|
+
event.preventDefault();
|
|
965
|
+
event.stopPropagation();
|
|
966
|
+
end();
|
|
967
|
+
}, signal, { capture: true });
|
|
968
|
+
signal?.addEventListener("abort", end, { once: true });
|
|
969
|
+
return Object.freeze({
|
|
970
|
+
/** Give up a drag going on, as Escape does: nothing dropped. */
|
|
971
|
+
cancel: end,
|
|
972
|
+
/** Whether an item is being dragged: past the threshold, not yet released. */
|
|
973
|
+
get dragging() {
|
|
974
|
+
return Boolean(drag?.moving);
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
|
|
562
979
|
// src/shared/components/installed.mjs
|
|
563
980
|
var ATTRIBUTE = "data-doc-component";
|
|
564
981
|
var PACKAGE_ID = /^[a-z0-9][a-z0-9-]*\/[a-z0-9][a-z0-9-]*$/;
|
|
565
982
|
var INSTANCE = `div[${ATTRIBUTE}], section[${ATTRIBUTE}]`;
|
|
983
|
+
var SLOT = "data-doc-slot";
|
|
984
|
+
var SLOT_PART = `div[${SLOT}], section[${SLOT}]`;
|
|
985
|
+
var REGION = `${INSTANCE}, ${SLOT_PART}`;
|
|
986
|
+
var edgeAround = (node) => node?.parentElement?.closest(REGION) ?? null;
|
|
987
|
+
function heldBy(node) {
|
|
988
|
+
const edge = edgeAround(node);
|
|
989
|
+
if (!edge) return null;
|
|
990
|
+
const owner = heldBy(edge);
|
|
991
|
+
if (edge.matches(INSTANCE)) return owner ?? edge;
|
|
992
|
+
return owner !== null && edgeAround(edge) === owner ? null : owner;
|
|
993
|
+
}
|
|
994
|
+
function heldWithin(element) {
|
|
995
|
+
if (!element.matches(REGION)) return heldBy(element);
|
|
996
|
+
const owner = heldBy(element);
|
|
997
|
+
if (element.matches(INSTANCE)) return owner ?? element;
|
|
998
|
+
return owner !== null && edgeAround(element) === owner ? null : owner;
|
|
999
|
+
}
|
|
1000
|
+
var opensDocument = (node) => node.matches(SLOT_PART) && heldBy(node) !== null && edgeAround(node) === heldBy(node);
|
|
1001
|
+
var componentAt = (node) => node?.nodeType === 1 && heldBy(node) !== null && !opensDocument(node);
|
|
1002
|
+
var slotsIn = (instance) => [...instance.querySelectorAll(SLOT_PART)].filter((slot) => edgeAround(slot) === instance);
|
|
566
1003
|
var FALLBACK = "data-doc-fallback";
|
|
567
1004
|
var CONTROLS2 = "input, select, textarea, button";
|
|
568
1005
|
var CONTROL_MARK = "data-doc-fallback-control";
|
|
@@ -578,16 +1015,686 @@
|
|
|
578
1015
|
var SCHEMA = "data-doc-schema";
|
|
579
1016
|
var schemaAhead = (value, schema = 1) => value !== null && value !== void 0 && !(String(value).trim() !== "" && Number(value) <= schema);
|
|
580
1017
|
|
|
1018
|
+
// src/shared/card-size.mjs
|
|
1019
|
+
var PAGE2 = "main.gallery-page";
|
|
1020
|
+
var BOARD = ".gallery-board";
|
|
1021
|
+
var CARD = ".gallery-card";
|
|
1022
|
+
var CARD_ID = "data-card-id";
|
|
1023
|
+
var MOST = Object.freeze({ w: 12, h: 24 });
|
|
1024
|
+
var DEFAULT = Object.freeze({ x: 0, y: 0, w: 4, h: 2 });
|
|
1025
|
+
var whole = (value, fallback) => {
|
|
1026
|
+
const number2 = Number.parseInt(value ?? "", 10);
|
|
1027
|
+
return Number.isFinite(number2) ? number2 : fallback;
|
|
1028
|
+
};
|
|
1029
|
+
function cellsOf(card) {
|
|
1030
|
+
const w = Math.min(MOST.w, Math.max(1, whole(card.dataset.w, DEFAULT.w)));
|
|
1031
|
+
const h = Math.min(MOST.h, Math.max(1, whole(card.dataset.h, DEFAULT.h)));
|
|
1032
|
+
const x = Math.min(MOST.w - w, Math.max(0, whole(card.dataset.x, DEFAULT.x)));
|
|
1033
|
+
const y = Math.max(0, whole(card.dataset.y, DEFAULT.y));
|
|
1034
|
+
return { x, y, w, h };
|
|
1035
|
+
}
|
|
1036
|
+
function drawnCells(card) {
|
|
1037
|
+
const { w, h } = cellsOf(card);
|
|
1038
|
+
const columns = Number(
|
|
1039
|
+
/** @type {HTMLElement | null} */
|
|
1040
|
+
card.closest(BOARD)?.dataset.columns
|
|
1041
|
+
) || MOST.w;
|
|
1042
|
+
const drawn2 = Number.parseInt(card.style?.getPropertyValue?.("--gallery-h") ?? "", 10);
|
|
1043
|
+
return { w: Math.min(w, columns), h: Number.isFinite(drawn2) ? Math.min(MOST.h, Math.max(1, drawn2)) : h };
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
// src/shared/colors.mjs
|
|
1047
|
+
var COLORS = [
|
|
1048
|
+
{ name: "gray", label: "\u7070\u8272", text: ["#6e6e73", "#a1a1a6"], fill: ["#f0efed", "#383836"], mark: ["#e0dfdd", "#454542"] },
|
|
1049
|
+
{ name: "brown", label: "\u68D5\u8272", text: ["#9f765a", "#ba856f"], fill: ["#f5ede9", "#45362d"], mark: ["#efdbce", "#534034"] },
|
|
1050
|
+
{ name: "orange", label: "\u6A59\u8272", text: ["#d27b2d", "#c77d48"], fill: ["#fbebde", "#53361f"], mark: ["#fbddc5", "#654025"] },
|
|
1051
|
+
{ name: "yellow", label: "\u9EC4\u8272", text: ["#cb9434", "#ca9849"], fill: ["#f9f3dc", "#504425"], mark: ["#f8eab6", "#614f26"] },
|
|
1052
|
+
{ name: "green", label: "\u7EFF\u8272", text: ["#50946e", "#529e72"], fill: ["#e8f1ec", "#263d30"], mark: ["#cfead9", "#2c4b3a"] },
|
|
1053
|
+
{ name: "blue", label: "\u84DD\u8272", text: ["#387dc9", "#5e87c9"], fill: ["#e5f2fc", "#233850"], mark: ["#cde5fb", "#294564"] },
|
|
1054
|
+
{ name: "purple", label: "\u7D2B\u8272", text: ["#9a6bb4", "#9d68d3"], fill: ["#f3ebf9", "#3c2d47"], mark: ["#ebdaf6", "#4b3859"] },
|
|
1055
|
+
{ name: "pink", label: "\u7C89\u8272", text: ["#c14c8a", "#d15796"], fill: ["#fae9f1", "#4e2b3c"], mark: ["#f8d7e6", "#5d3548"] },
|
|
1056
|
+
{ name: "red", label: "\u7EA2\u8272", text: ["#cf5148", "#df5452"], fill: ["#fce9e7", "#502c29"], mark: ["#fed7d1", "#663632"] }
|
|
1057
|
+
];
|
|
1058
|
+
var COLOR_NAMES = COLORS.map(({ name }) => name);
|
|
1059
|
+
|
|
1060
|
+
// src/shared/component-source.mjs
|
|
1061
|
+
var SOURCE_ATTRIBUTES = ["data-checked", "rowspan", "colspan", "data-sort-status", "data-sort-type", "data-sort-key", "data-sort-default", "data-sort-ignore", "data-sort-value", "data-sort-rank"];
|
|
1062
|
+
var LOOK_CLASSES = /* @__PURE__ */ new Set([
|
|
1063
|
+
...COLOR_NAMES.flatMap((name) => [`doc-text-${name}`, `doc-highlight-${name}`]),
|
|
1064
|
+
// table.mjs's CELL_ALIGN_CLASSES, CELL_VALIGN_CLASSES and CELL_BOLD_CLASS, written out: an import of that
|
|
1065
|
+
// file would bring its description, prose and all, into the kit's runtime (tests/unit/installed.mjs
|
|
1066
|
+
// holds the two lists together).
|
|
1067
|
+
"doc-align-left",
|
|
1068
|
+
"doc-align-center",
|
|
1069
|
+
"doc-align-right",
|
|
1070
|
+
"doc-valign-top",
|
|
1071
|
+
"doc-valign-middle",
|
|
1072
|
+
"doc-valign-bottom",
|
|
1073
|
+
"doc-bold"
|
|
1074
|
+
]);
|
|
1075
|
+
function lookChanged(before, after) {
|
|
1076
|
+
const looks = (value) => [...new Set(String(value ?? "").split(/\s+/).filter((name) => LOOK_CLASSES.has(name)))].sort().join(" ");
|
|
1077
|
+
return looks(before) !== looks(after);
|
|
1078
|
+
}
|
|
1079
|
+
|
|
1080
|
+
// src/shared/json-layout.mjs
|
|
1081
|
+
var isValue = (value) => value === null || typeof value !== "object";
|
|
1082
|
+
var isFlat = (value) => Object.values(value).every((each) => isValue(each) || Array.isArray(each) && each.every(isValue));
|
|
1083
|
+
function laidOut(value, indent) {
|
|
1084
|
+
if (typeof value?.toJSON === "function") return laidOut(value.toJSON(), indent);
|
|
1085
|
+
if (isValue(value)) return JSON.stringify(value) ?? "null";
|
|
1086
|
+
const list2 = Array.isArray(value);
|
|
1087
|
+
const entries = Object.entries(value).map(([key, each]) => [key, typeof each?.toJSON === "function" ? each.toJSON() : each]).filter(([, each]) => list2 || each !== void 0 && typeof each !== "function");
|
|
1088
|
+
const items = entries.map(([key, each]) => `${list2 ? "" : `${JSON.stringify(key)}: `}${laidOut(each, `${indent} `)}`);
|
|
1089
|
+
if (items.length === 0) return list2 ? "[]" : "{}";
|
|
1090
|
+
if (isFlat(Object.fromEntries(entries))) return list2 ? `[${items.join(", ")}]` : `{ ${items.join(", ")} }`;
|
|
1091
|
+
return `${list2 ? "[" : "{"}
|
|
1092
|
+
${items.map((item2) => `${indent} ${item2}`).join(",\n")}
|
|
1093
|
+
${indent}${list2 ? "]" : "}"}`;
|
|
1094
|
+
}
|
|
1095
|
+
function jsonIn(text, value) {
|
|
1096
|
+
const start = text.length - text.trimStart().length;
|
|
1097
|
+
const end = text.trimEnd().length;
|
|
1098
|
+
const indent = text.slice(text.lastIndexOf("\n", start) + 1, start);
|
|
1099
|
+
const json = text.slice(start, end).includes("\n") ? laidOut(value, indent) : JSON.stringify(value) ?? "null";
|
|
1100
|
+
return text.slice(0, start) + json.replaceAll("</", "<\\/").replaceAll("<!--", "\\u003c!--") + text.slice(end);
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
// src/shared/inline-spacing.mjs
|
|
1104
|
+
var UNITS = /* @__PURE__ */ new Set([..."\u4E2A\u4E07\u4EBF\u5343\u767E\u5341\u5143\u89D2\u5206\u5398\u6BDB\u500D\u5E74\u6708\u65E5\u53F7\u65F6\u70B9\u79D2\u5929\u5468\u5C81\u4EBA\u4F4D\u540D\u6B21\u5BB6\u6761\u9879\u79CD\u53F0\u53EA\u4EF6\u7BC7\u9875\u5F20\u5957\u4EFD\u7EC4\u6279\u671F\u5C4A\u4EE3\u7EA7\u5C42\u8F6E\u6B65\u7C73\u514B\u65A4\u5428\u5EA6\u91CC\u516C\u6BEB\u5FAE\u5BF8\u5C3A\u4E24\u5347\u6237\u6240\u5EA7\u680B\u8F86\u67B6\u8258\u672C\u90E8\u7AE0\u8282\u573A\u5C40\u9996\u53E5\u5B57\u884C\u5217\u904D\u56DE\u756A\u6210"]);
|
|
1105
|
+
var ZWSP = String.fromCharCode(8203);
|
|
1106
|
+
var WORD = /[\p{L}\p{N}]/u;
|
|
1107
|
+
var ITEM = "code, .doc-math-inline, .katex";
|
|
1108
|
+
var LINE = /^(P|LI|H[1-6]|TD|TH|DT|DD|DIV|SECTION|ARTICLE|ASIDE|HEADER|FOOTER|MAIN|NAV|FIGURE|FIGCAPTION|CAPTION|SUMMARY|DETAILS|BLOCKQUOTE|UL|OL|TABLE|THEAD|TBODY|TR|PRE|BR|HR|DIALOG|BODY|BUTTON|svg)$/;
|
|
1109
|
+
var emptyFormula = (element) => element.matches(".doc-math-inline") && (element.getAttribute("data-ge-empty") === "formula" || !element.textContent.replace(/\\[()]/g, "").trim());
|
|
1110
|
+
var isInlineItem = (node) => node?.nodeType === 1 && node.matches(ITEM) && !emptyFormula(node);
|
|
1111
|
+
function inlineItems(root) {
|
|
1112
|
+
const items = root.nodeType === 1 && root.matches(ITEM) ? [root, ...root.querySelectorAll(ITEM)] : [...root.querySelectorAll(ITEM)];
|
|
1113
|
+
return items.filter((item2) => isInlineItem(item2) && !item2.parentElement?.closest(".doc-math-inline, .katex, .katex-display, code"));
|
|
1114
|
+
}
|
|
1115
|
+
function endOf(node, after) {
|
|
1116
|
+
if (node.nodeType === 3) {
|
|
1117
|
+
const characters = [...node.data.replaceAll(ZWSP, "")];
|
|
1118
|
+
return characters.length === 0 ? void 0 : after ? characters[0] : characters.at(-1);
|
|
1119
|
+
}
|
|
1120
|
+
if (node.nodeType !== 1) return void 0;
|
|
1121
|
+
if (LINE.test(node.tagName)) return null;
|
|
1122
|
+
if (node.matches(ITEM)) return emptyFormula(node) ? void 0 : true;
|
|
1123
|
+
if (node.hasAttribute("data-ge-empty")) return void 0;
|
|
1124
|
+
const children = [...node.childNodes];
|
|
1125
|
+
for (const child of after ? children : children.reverse()) {
|
|
1126
|
+
const found = endOf(child, after);
|
|
1127
|
+
if (found !== void 0) return found;
|
|
1128
|
+
}
|
|
1129
|
+
return void 0;
|
|
1130
|
+
}
|
|
1131
|
+
function sideOf(node, after) {
|
|
1132
|
+
for (let at = node; at; ) {
|
|
1133
|
+
const next = after ? at.nextSibling : at.previousSibling;
|
|
1134
|
+
if (!next) {
|
|
1135
|
+
at = at.parentElement;
|
|
1136
|
+
if (!at || LINE.test(at.tagName) || at.hasAttribute("contenteditable")) return null;
|
|
1137
|
+
continue;
|
|
1138
|
+
}
|
|
1139
|
+
const found = endOf(next, after);
|
|
1140
|
+
if (found !== void 0) return found;
|
|
1141
|
+
at = next;
|
|
1142
|
+
}
|
|
1143
|
+
return null;
|
|
1144
|
+
}
|
|
1145
|
+
function spaceAround(element) {
|
|
1146
|
+
const put = { before: null, after: null };
|
|
1147
|
+
for (const after of [false, true]) {
|
|
1148
|
+
const side = sideOf(element, after);
|
|
1149
|
+
if (side !== true && !(typeof side === "string" && WORD.test(side))) continue;
|
|
1150
|
+
const space = element.ownerDocument.createTextNode(" ");
|
|
1151
|
+
if (after) element.after(space);
|
|
1152
|
+
else element.before(space);
|
|
1153
|
+
put[after ? "after" : "before"] = space;
|
|
1154
|
+
}
|
|
1155
|
+
return put;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
// src/shared/number-reading.mjs
|
|
1159
|
+
var missingValues = /* @__PURE__ */ new Set(["", "-", "\u2014", "\u2013", "\u2212", "n/a", "na", "null"]);
|
|
1160
|
+
function isMissingValue(raw) {
|
|
1161
|
+
return missingValues.has(raw.toLowerCase());
|
|
1162
|
+
}
|
|
1163
|
+
var QUALIFIER = String.raw`(?:约|大约|近|超过|不足|≈|~|<=?|>=?|≤|≥|±)?`;
|
|
1164
|
+
var AMOUNT = String.raw`[$¥€£₩₹]?\s*((?:\d{1,3}(?:[,\s\u00a0\u2009]\d{3})+|\d{1,4}(?:,\d{4})+|\d+)(?:\.\d*)?(?:e[+-]?\d+)?|\.\d+)`;
|
|
1165
|
+
var UNIT = String.raw`((?:[%‰x×]|[A-Za-zµμ\u4e00-\u9fff°℃]+(?:\/[A-Za-zµμ\u4e00-\u9fff°℃·]+)?)?)`;
|
|
1166
|
+
var UNIT_SCALES = { \u5343: 1e3, \u4E07: 1e4, \u4EBF: 1e8 };
|
|
1167
|
+
var SCALE = UNIT_SCALES;
|
|
1168
|
+
var SINGLE = new RegExp(`^${QUALIFIER}\\s*([+-]?)\\s*${AMOUNT}\\s*${UNIT}$`, "i");
|
|
1169
|
+
var RANGE = new RegExp(`^([+-]?)\\s*${AMOUNT}\\s*${UNIT}\\s*(?:-|~|\u81F3|\u5230)\\s*[+-]?\\s*${AMOUNT}\\s*${UNIT}$`, "i");
|
|
1170
|
+
function numberReading(raw) {
|
|
1171
|
+
let text = raw.normalize("NFKC").trim().replace(/[−–—]/g, "-");
|
|
1172
|
+
const accounting = /^\((.+)\)$/.exec(text);
|
|
1173
|
+
if (accounting) text = accounting[1].trim();
|
|
1174
|
+
const single = SINGLE.exec(text);
|
|
1175
|
+
const match = single ?? RANGE.exec(text);
|
|
1176
|
+
if (!match) return null;
|
|
1177
|
+
const value = Number(`${match[1]}${match[2].replace(/[,\s\u00a0\u2009]/g, "")}`);
|
|
1178
|
+
const written = accounting ? -value : value;
|
|
1179
|
+
const unit = match[3] ?? "";
|
|
1180
|
+
const scaled = written * (SCALE[unit[0]] ?? 1);
|
|
1181
|
+
if (!Number.isFinite(scaled)) return null;
|
|
1182
|
+
return single ? { value: scaled, written, unit } : { value: scaled, written, unit, range: true };
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
// src/shared/table-chart.mjs
|
|
1186
|
+
var CHART_DATA = "data-doc-chart-data";
|
|
1187
|
+
var CHART_SOURCE = "data-doc-chart-source";
|
|
1188
|
+
var VIEW_FROM = "data-doc-from";
|
|
1189
|
+
var TABLE_READERS = [CHART_DATA, VIEW_FROM];
|
|
1190
|
+
var CHART_KEY = /^[A-Za-z][\w-]{0,31}$/;
|
|
1191
|
+
var FORMULA = /\\\(([\s\S]*?)\\\)|\\\[([\s\S]*?)\\\]|\$\$([\s\S]*?)\$\$/g;
|
|
1192
|
+
var cellWords = (text) => text.replace(FORMULA, (_, inline, display, dollars) => inline ?? display ?? dollars).replaceAll(ZWSP, "").replace(/\s+/g, " ").trim();
|
|
1193
|
+
var TEX = 'annotation[encoding="application/x-tex"]';
|
|
1194
|
+
function cellText(node) {
|
|
1195
|
+
if (node.nodeType === 3) return (
|
|
1196
|
+
/** @type {Text} */
|
|
1197
|
+
node.data
|
|
1198
|
+
);
|
|
1199
|
+
if (node.nodeType !== 1) return "";
|
|
1200
|
+
const element = (
|
|
1201
|
+
/** @type {Element} */
|
|
1202
|
+
node
|
|
1203
|
+
);
|
|
1204
|
+
if (element.hasAttribute("data-ge-empty")) return "";
|
|
1205
|
+
const tex = element.classList.contains("katex") ? element.querySelector(TEX) : null;
|
|
1206
|
+
if (tex) return tex.textContent ?? "";
|
|
1207
|
+
let text = "";
|
|
1208
|
+
for (const child of element.childNodes) text += cellText(child);
|
|
1209
|
+
return text;
|
|
1210
|
+
}
|
|
1211
|
+
var WORD_TYPES = /* @__PURE__ */ new Set(["text", "date"]);
|
|
1212
|
+
function cellValue(cell, type = null) {
|
|
1213
|
+
if (!cell) return null;
|
|
1214
|
+
const raw = cell.sort ?? cell.words;
|
|
1215
|
+
if (isMissingValue(raw)) return null;
|
|
1216
|
+
if (WORD_TYPES.has(type)) return cell.words;
|
|
1217
|
+
const reading = numberReading(raw);
|
|
1218
|
+
return reading && !reading.range ? reading.value : cell.words;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
// src/shared/net-policy.mjs
|
|
1222
|
+
var NET = "net:";
|
|
1223
|
+
var netHostsOf = (needs) => Array.isArray(needs) ? needs.filter((need) => typeof need === "string" && need.startsWith(NET)).map((need) => need.slice(NET.length)) : [];
|
|
1224
|
+
|
|
1225
|
+
// src/render/kit/runtime/net.js
|
|
1226
|
+
var CONSENT_BAR = "doc-net-consent";
|
|
1227
|
+
function createNet({ restart, instances, describe }) {
|
|
1228
|
+
const global2 = globalThis;
|
|
1229
|
+
const refused = /* @__PURE__ */ new Map();
|
|
1230
|
+
const bars = /* @__PURE__ */ new Map();
|
|
1231
|
+
let consents = null;
|
|
1232
|
+
let snapshot;
|
|
1233
|
+
const embedded2 = () => {
|
|
1234
|
+
if (snapshot !== void 0) return snapshot;
|
|
1235
|
+
try {
|
|
1236
|
+
snapshot = JSON.parse(document.querySelector("script[data-doc-snapshot]")?.textContent ?? "null");
|
|
1237
|
+
} catch {
|
|
1238
|
+
snapshot = null;
|
|
1239
|
+
}
|
|
1240
|
+
return snapshot;
|
|
1241
|
+
};
|
|
1242
|
+
const failure = (code, message, fields = {}) => Object.assign(new Error(message), { code, ...fields });
|
|
1243
|
+
const read = (data, as) => {
|
|
1244
|
+
if (as === "text") return typeof data === "string" ? data : JSON.stringify(data);
|
|
1245
|
+
if (typeof data !== "string") return data;
|
|
1246
|
+
try {
|
|
1247
|
+
return JSON.parse(data);
|
|
1248
|
+
} catch {
|
|
1249
|
+
return data;
|
|
1250
|
+
}
|
|
1251
|
+
};
|
|
1252
|
+
const ownSlug = () => document.querySelector(".doc-page")?.dataset.docId || null;
|
|
1253
|
+
const pageSlug = () => /^\/pages\/([a-z0-9-]+)\/?$/.exec(location.pathname)?.[1] ?? null;
|
|
1254
|
+
function clear(host) {
|
|
1255
|
+
refused.delete(host);
|
|
1256
|
+
bars.get(host)?.remove();
|
|
1257
|
+
bars.delete(host);
|
|
1258
|
+
}
|
|
1259
|
+
function ask(id, hosts) {
|
|
1260
|
+
const asked = new CustomEvent("doc-net-consent", { cancelable: true, detail: { block: id, hosts } });
|
|
1261
|
+
if (global2.dispatchEvent(asked)) {
|
|
1262
|
+
const page = pageSlug();
|
|
1263
|
+
const slug = ownSlug();
|
|
1264
|
+
global2.open(`${location.origin}/${page ? `#@${page}` : slug ? `#${slug}` : ""}`, "_blank", "noopener");
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
function showConsent(host, id, hosts) {
|
|
1268
|
+
refused.set(host, { id, hosts });
|
|
1269
|
+
let bar = bars.get(host);
|
|
1270
|
+
if (!bar?.isConnected) {
|
|
1271
|
+
bar = document.createElement("div");
|
|
1272
|
+
bar.className = CONSENT_BAR;
|
|
1273
|
+
bar.setAttribute("data-doc-dev", "");
|
|
1274
|
+
bar.setAttribute("contenteditable", "false");
|
|
1275
|
+
bar.setAttribute("role", "group");
|
|
1276
|
+
const why = document.createElement("span");
|
|
1277
|
+
why.className = `${CONSENT_BAR}-why`;
|
|
1278
|
+
const button2 = document.createElement("button");
|
|
1279
|
+
button2.type = "button";
|
|
1280
|
+
button2.className = `${CONSENT_BAR}-allow`;
|
|
1281
|
+
button2.addEventListener("click", (event) => {
|
|
1282
|
+
event.preventDefault();
|
|
1283
|
+
event.stopPropagation();
|
|
1284
|
+
const waiting = refused.get(host);
|
|
1285
|
+
if (waiting) ask(waiting.id, waiting.hosts);
|
|
1286
|
+
});
|
|
1287
|
+
bar.append(why, button2);
|
|
1288
|
+
host.after(bar);
|
|
1289
|
+
bars.set(host, bar);
|
|
1290
|
+
}
|
|
1291
|
+
const [first, ...others] = hosts;
|
|
1292
|
+
bar.querySelector(`.${CONSENT_BAR}-why`).textContent = sayRuntime("net-why");
|
|
1293
|
+
const button = bar.querySelector(`.${CONSENT_BAR}-allow`);
|
|
1294
|
+
button.textContent = others.length > 0 ? sayRuntime("net-allow-many", first, hosts.length) : sayRuntime("net-allow", first);
|
|
1295
|
+
button.title = hosts.join("\n");
|
|
1296
|
+
bar.setAttribute("aria-label", sayRuntime("net-why"));
|
|
1297
|
+
}
|
|
1298
|
+
global2.addEventListener("doc-settings-changed", (event) => {
|
|
1299
|
+
const told = event.detail?.net;
|
|
1300
|
+
if (!Array.isArray(told)) return;
|
|
1301
|
+
const before = consents;
|
|
1302
|
+
consents = new Set(told);
|
|
1303
|
+
for (const [host, def] of instances()) {
|
|
1304
|
+
const hosts = netHostsOf(describe(def.id)?.needs);
|
|
1305
|
+
if (hosts.length === 0) continue;
|
|
1306
|
+
const pair = (name) => `${def.id}@${name}`;
|
|
1307
|
+
const changed = before !== null && hosts.some((name) => before.has(pair(name)) !== consents.has(pair(name)));
|
|
1308
|
+
const waiting = refused.get(host);
|
|
1309
|
+
if (changed || waiting && waiting.hosts.every((name) => consents.has(pair(name)))) {
|
|
1310
|
+
clear(host);
|
|
1311
|
+
restart(host);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
});
|
|
1315
|
+
return {
|
|
1316
|
+
/** The context.fetch of the instance of `def` on `host`, at `place` (context.place). */
|
|
1317
|
+
fetchFor: (def, host, place) => async (url, options = {}) => {
|
|
1318
|
+
const as = options?.as ?? "json";
|
|
1319
|
+
if (as !== "json" && as !== "text") throw failure("url", `context.fetch: as is "json" or "text", not ${JSON.stringify(as)}`);
|
|
1320
|
+
if (place === "export") {
|
|
1321
|
+
let name2;
|
|
1322
|
+
try {
|
|
1323
|
+
const address = new URL(url);
|
|
1324
|
+
address.hash = "";
|
|
1325
|
+
name2 = address.href;
|
|
1326
|
+
} catch {
|
|
1327
|
+
throw failure("url", `context.fetch: ${url} is not an absolute address`);
|
|
1328
|
+
}
|
|
1329
|
+
const kept = embedded2()?.net?.[name2];
|
|
1330
|
+
if (!kept) throw failure("offline", `an exported file reaches no network, and holds no answer for ${name2}`);
|
|
1331
|
+
return { data: read(kept.data, as), at: kept.at, cached: true };
|
|
1332
|
+
}
|
|
1333
|
+
let asked = null;
|
|
1334
|
+
const ask2 = { block: def.id, url, as, ...place === "document" && ownSlug() ? { doc: ownSlug() } : {} };
|
|
1335
|
+
global2.dispatchEvent(new CustomEvent("doc-net-fetch", { cancelable: true, detail: { ask: ask2, answer: (promise) => {
|
|
1336
|
+
asked = promise;
|
|
1337
|
+
} } }));
|
|
1338
|
+
if (!asked) throw failure("offline", "no server shows this page: nothing reaches the network for it");
|
|
1339
|
+
let answer;
|
|
1340
|
+
try {
|
|
1341
|
+
answer = await asked;
|
|
1342
|
+
} catch (error) {
|
|
1343
|
+
throw failure("offline", `the server did not answer: ${error?.message ?? error}`);
|
|
1344
|
+
}
|
|
1345
|
+
if (answer?.ok) {
|
|
1346
|
+
if (refused.has(host)) clear(host);
|
|
1347
|
+
return { data: answer.data, at: answer.at, cached: Boolean(answer.cached) };
|
|
1348
|
+
}
|
|
1349
|
+
const { code = "offline", why, hosts, host: name, status } = answer ?? {};
|
|
1350
|
+
if (code === "consent" && Array.isArray(hosts) && host.isConnected) showConsent(host, def.id, hosts);
|
|
1351
|
+
throw failure(code, `${def.id}: ${url}: ${code}${why ? ` (${why})` : ""}`, { ...hosts ? { hosts } : {}, ...name ? { host: name } : {}, ...status ? { status } : {} });
|
|
1352
|
+
},
|
|
1353
|
+
forget: clear
|
|
1354
|
+
};
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
// src/shared/page-links.mjs
|
|
1358
|
+
var DOC_SLUG = /^doc-([a-z][a-z0-9]{7})$/;
|
|
1359
|
+
function hashId(slug) {
|
|
1360
|
+
let one = 3735928559;
|
|
1361
|
+
let two = 1103547991;
|
|
1362
|
+
for (let at = 0; at < slug.length; at++) {
|
|
1363
|
+
one = Math.imul(one ^ slug.charCodeAt(at), 2654435761);
|
|
1364
|
+
two = Math.imul(two ^ slug.charCodeAt(at), 1597334677);
|
|
1365
|
+
}
|
|
1366
|
+
one = Math.imul(one ^ one >>> 16, 2246822507) ^ Math.imul(two ^ two >>> 13, 3266489909);
|
|
1367
|
+
two = Math.imul(two ^ two >>> 16, 2246822507) ^ Math.imul(one ^ one >>> 13, 3266489909);
|
|
1368
|
+
const hash = (two >>> 0) % 2 ** 21 * 2 ** 32 + (one >>> 0);
|
|
1369
|
+
return String.fromCharCode(97 + hash % 26) + Math.floor(hash / 26).toString(36).padStart(7, "0").slice(-7);
|
|
1370
|
+
}
|
|
1371
|
+
var pageId = (slug) => DOC_SLUG.exec(slug)?.[1] ?? hashId(slug);
|
|
1372
|
+
var earlierId = (slug) => DOC_SLUG.test(slug) ? hashId(slug) : null;
|
|
1373
|
+
var ID_FIRST = "abcdefghijklmnopqrstuvwxyz";
|
|
1374
|
+
var ID_REST = `${ID_FIRST}0123456789`;
|
|
1375
|
+
function pageOfLink(links, value) {
|
|
1376
|
+
if (links.has(value)) return value;
|
|
1377
|
+
const id = value.slice(value.lastIndexOf("-") + 1);
|
|
1378
|
+
for (const slug of links.keys()) if (pageId(slug) === id) return slug;
|
|
1379
|
+
for (const slug of links.keys()) if (earlierId(slug) === id) return slug;
|
|
1380
|
+
return null;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
// src/shared/page-address.mjs
|
|
1384
|
+
var SLUG = "[a-z0-9]+(?:-[a-z0-9]+)*";
|
|
1385
|
+
var FILE = "(?:doc|report)\\.html";
|
|
1386
|
+
var IN_FILE = new RegExp(`^\\.\\./(${SLUG})/${FILE}(?:#(.*))?$`);
|
|
1387
|
+
var PAGE3 = new RegExp(`^/generated/(${SLUG})\\.html$`);
|
|
1388
|
+
var OWN_FILE = new RegExp(`^/(${SLUG})/${FILE}$`);
|
|
1389
|
+
var LOOPBACK = /* @__PURE__ */ new Set(["127.0.0.1", "localhost"]);
|
|
1390
|
+
var decoded = (text) => {
|
|
1391
|
+
try {
|
|
1392
|
+
return decodeURIComponent(text);
|
|
1393
|
+
} catch {
|
|
1394
|
+
return text;
|
|
1395
|
+
}
|
|
1396
|
+
};
|
|
1397
|
+
function ownAddress(text) {
|
|
1398
|
+
try {
|
|
1399
|
+
const url = new URL(text, "http://127.0.0.1");
|
|
1400
|
+
return /^https?:$/.test(url.protocol) && LOOPBACK.has(url.hostname) && /^(?:https?:|\/)/i.test(text) ? url : null;
|
|
1401
|
+
} catch {
|
|
1402
|
+
return null;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
function hashAddress(hash, links = null) {
|
|
1406
|
+
const at = hash.indexOf("/");
|
|
1407
|
+
const name = at < 0 ? hash : hash.slice(0, at);
|
|
1408
|
+
const block = at < 0 ? null : hash.slice(at + 1) || null;
|
|
1409
|
+
const slug = links && pageOfLink(links, name);
|
|
1410
|
+
return slug ? { slug, block } : null;
|
|
1411
|
+
}
|
|
1412
|
+
function pageAddress(text, links = null) {
|
|
1413
|
+
const address = String(text ?? "").trim();
|
|
1414
|
+
const known = (slug, block) => !links || links.has(slug) ? { slug, block: block || null } : null;
|
|
1415
|
+
const inFile = IN_FILE.exec(address);
|
|
1416
|
+
if (inFile) return known(inFile[1], decoded(inFile[2] ?? ""));
|
|
1417
|
+
const url = ownAddress(address);
|
|
1418
|
+
if (!url) return null;
|
|
1419
|
+
const path = PAGE3.exec(url.pathname) ?? OWN_FILE.exec(url.pathname);
|
|
1420
|
+
if (path) return known(path[1], decoded(url.hash.slice(1)));
|
|
1421
|
+
return url.pathname === "/" && url.hash.length > 1 ? hashAddress(decoded(url.hash.slice(1)), links) : null;
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
// src/render/kit/runtime/table-reading.js
|
|
1425
|
+
var cellReading = (cell) => ({ words: cellWords(cellText(cell)), sort: cell.getAttribute("data-sort-value")?.trim() ?? null });
|
|
1426
|
+
var spans = (row) => Boolean(row) && [...row.cells].some((cell) => cell.rowSpan !== 1 || cell.colSpan !== 1);
|
|
1427
|
+
function readTable(table2, { order = (rows) => rows, cell = cellReading } = {}) {
|
|
1428
|
+
const head = table2.tHead?.rows[0] ?? null;
|
|
1429
|
+
const body = [...table2.tBodies].flatMap((section) => [...section.rows]);
|
|
1430
|
+
const header = head ?? (body[0] && body[0].cells.length > 0 && [...body[0].cells].every((each) => each.localName === "th") ? body[0] : null);
|
|
1431
|
+
const ordered = order(body.filter((row) => row !== header));
|
|
1432
|
+
const first = header ?? ordered[0] ?? null;
|
|
1433
|
+
const rows = header ? ordered : ordered.slice(1);
|
|
1434
|
+
const read = (row) => [...row.cells].map(cell);
|
|
1435
|
+
const named = first ? read(first) : [];
|
|
1436
|
+
return {
|
|
1437
|
+
table: table2,
|
|
1438
|
+
header,
|
|
1439
|
+
first,
|
|
1440
|
+
rows,
|
|
1441
|
+
names: named.map(({ words }) => words),
|
|
1442
|
+
types: first ? [...first.cells].map((each) => each.getAttribute("data-sort-type")) : [],
|
|
1443
|
+
cells: rows.map(read),
|
|
1444
|
+
merged: [first, ...rows].some(spans)
|
|
1445
|
+
};
|
|
1446
|
+
}
|
|
1447
|
+
function linksOf(row, own) {
|
|
1448
|
+
return [...row.querySelectorAll("a[href]")].flatMap((link) => {
|
|
1449
|
+
const href = link.getAttribute("href").trim();
|
|
1450
|
+
const place = href.startsWith("#") && href.length > 1 ? own ? { slug: own, block: decoded(href.slice(1)) } : null : pageAddress(href);
|
|
1451
|
+
return place ? [{ slug: place.slug, title: cellWords(cellText(link)), block: place.block ?? null }] : [];
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
function rowOf(reading, at, own) {
|
|
1455
|
+
const values = {};
|
|
1456
|
+
reading.names.forEach((name, index) => {
|
|
1457
|
+
values[name] = cellValue(reading.cells[at][index], reading.types[index] ?? null);
|
|
1458
|
+
});
|
|
1459
|
+
return Object.freeze({ el: reading.rows[at], values: Object.freeze(values), links: Object.freeze(linksOf(reading.rows[at], own)) });
|
|
1460
|
+
}
|
|
1461
|
+
var rowsOf2 = (reading, own = null) => reading.rows.map((_, at) => rowOf(reading, at, own));
|
|
1462
|
+
var SOURCES = `.doc-table-wrap[${CHART_SOURCE}]`;
|
|
1463
|
+
var READERS = TABLE_READERS.map((name) => `[${name}]`).join(", ");
|
|
1464
|
+
var WATCHED = [CHART_SOURCE, ...TABLE_READERS, "data-sort-value", "data-sort-type", "rowspan", "colspan", "aria-sort", "href"];
|
|
1465
|
+
function createKeyedTables(doc = globalThis.document) {
|
|
1466
|
+
const followers = /* @__PURE__ */ new Set();
|
|
1467
|
+
const kept = /* @__PURE__ */ new Map();
|
|
1468
|
+
let cells = /* @__PURE__ */ new WeakMap();
|
|
1469
|
+
let rowsKept = /* @__PURE__ */ new WeakMap();
|
|
1470
|
+
let observer = null;
|
|
1471
|
+
const frameOf = (key) => key === null || key === void 0 ? null : [...doc.querySelectorAll(SOURCES)].find((wrap) => wrap.getAttribute(CHART_SOURCE) === key && !wrap.closest("[data-doc-dev]")) ?? null;
|
|
1472
|
+
const fileOrder = /* @__PURE__ */ new WeakMap();
|
|
1473
|
+
const inFileOrder = (table2) => (rows) => {
|
|
1474
|
+
const sorted = [...table2.tHead?.rows[0]?.cells ?? []].some((cell) => /^(?:ascending|descending)$/.test(cell.getAttribute("aria-sort") ?? ""));
|
|
1475
|
+
if (!sorted) {
|
|
1476
|
+
rows.forEach((row, index) => fileOrder.set(row, index));
|
|
1477
|
+
return rows;
|
|
1478
|
+
}
|
|
1479
|
+
const place = (row) => fileOrder.get(row) ?? rows.length + rows.indexOf(row);
|
|
1480
|
+
return [...rows].sort((a, b) => place(a) - place(b));
|
|
1481
|
+
};
|
|
1482
|
+
const cellOf = (cell) => {
|
|
1483
|
+
if (!observer) return cellReading(cell);
|
|
1484
|
+
if (!cells.has(cell)) cells.set(cell, cellReading(cell));
|
|
1485
|
+
return cells.get(cell);
|
|
1486
|
+
};
|
|
1487
|
+
function touched(records) {
|
|
1488
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1489
|
+
let readers = false;
|
|
1490
|
+
const keysIn = (node) => {
|
|
1491
|
+
if (node.nodeType !== 1) return;
|
|
1492
|
+
for (const frame of [...node.matches(SOURCES) ? [node] : [], ...node.querySelectorAll(SOURCES)]) keys.add(frame.getAttribute(CHART_SOURCE));
|
|
1493
|
+
if (node.matches(READERS) || node.querySelector(READERS)) readers = true;
|
|
1494
|
+
};
|
|
1495
|
+
for (const record of records) {
|
|
1496
|
+
if (record.type === "attributes" && record.attributeName === CHART_SOURCE) {
|
|
1497
|
+
keys.add(record.oldValue);
|
|
1498
|
+
keys.add(record.target.getAttribute(CHART_SOURCE));
|
|
1499
|
+
continue;
|
|
1500
|
+
}
|
|
1501
|
+
if (record.type === "attributes" && TABLE_READERS.includes(record.attributeName)) {
|
|
1502
|
+
readers = true;
|
|
1503
|
+
continue;
|
|
1504
|
+
}
|
|
1505
|
+
const target = record.target.nodeType === 1 ? record.target : record.target.parentElement;
|
|
1506
|
+
const frame = target?.closest(SOURCES);
|
|
1507
|
+
if (frame) keys.add(frame.getAttribute(CHART_SOURCE));
|
|
1508
|
+
const cell = target?.closest("td, th");
|
|
1509
|
+
if (cell) cells.delete(cell);
|
|
1510
|
+
const row = target?.closest("tr");
|
|
1511
|
+
if (row) rowsKept.delete(row);
|
|
1512
|
+
for (const node of [...record.addedNodes, ...record.removedNodes]) keysIn(node);
|
|
1513
|
+
}
|
|
1514
|
+
keys.delete(null);
|
|
1515
|
+
return { keys, readers };
|
|
1516
|
+
}
|
|
1517
|
+
function heard(records) {
|
|
1518
|
+
if (!doc.defaultView || records.length === 0) return;
|
|
1519
|
+
const { keys, readers } = touched(records);
|
|
1520
|
+
if (keys.size === 0 && !readers) return;
|
|
1521
|
+
for (const key of keys) kept.delete(key);
|
|
1522
|
+
for (const follower of [...followers]) {
|
|
1523
|
+
if (!followers.has(follower)) continue;
|
|
1524
|
+
const key = follower.keyOf() ?? null;
|
|
1525
|
+
if (key === follower.key && !keys.has(key)) continue;
|
|
1526
|
+
follower.key = key;
|
|
1527
|
+
follower.heard();
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
const flush = () => observer && heard(observer.takeRecords());
|
|
1531
|
+
function keptOf(key) {
|
|
1532
|
+
flush();
|
|
1533
|
+
if (kept.has(key)) return kept.get(key);
|
|
1534
|
+
const frame = frameOf(key);
|
|
1535
|
+
const table2 = frame?.querySelector("table") ?? null;
|
|
1536
|
+
const entry = { frame, reading: table2 ? readTable(table2, { order: inFileOrder(table2), cell: cellOf }) : null, rows: /* @__PURE__ */ new Map(), signature: null };
|
|
1537
|
+
if (observer) kept.set(key, entry);
|
|
1538
|
+
return entry;
|
|
1539
|
+
}
|
|
1540
|
+
const serials = /* @__PURE__ */ new WeakMap();
|
|
1541
|
+
let serial = 0;
|
|
1542
|
+
const serialOf = (el) => serials.get(el) ?? (serials.set(el, ++serial), serial);
|
|
1543
|
+
function rowKept(reading, at, own, header) {
|
|
1544
|
+
const el = reading.rows[at];
|
|
1545
|
+
const was = observer ? rowsKept.get(el) : null;
|
|
1546
|
+
if (was && was.header === header && was.own === own) return was;
|
|
1547
|
+
const row = rowOf(reading, at, own);
|
|
1548
|
+
const entry = { header, own, row, sign: null };
|
|
1549
|
+
if (observer) rowsKept.set(el, entry);
|
|
1550
|
+
return entry;
|
|
1551
|
+
}
|
|
1552
|
+
function rowsKeptOf(key, own) {
|
|
1553
|
+
const entry = keptOf(key);
|
|
1554
|
+
if (!entry.reading) return null;
|
|
1555
|
+
if (!entry.rows.has(own)) {
|
|
1556
|
+
const header = JSON.stringify([entry.reading.names, entry.reading.types]);
|
|
1557
|
+
entry.rows.set(own, entry.reading.rows.map((_, at) => rowKept(entry.reading, at, own, header)));
|
|
1558
|
+
}
|
|
1559
|
+
return entry.rows.get(own);
|
|
1560
|
+
}
|
|
1561
|
+
return Object.freeze({
|
|
1562
|
+
frameOf,
|
|
1563
|
+
reading: (key) => keptOf(key).reading,
|
|
1564
|
+
rows: (key, own = null) => rowsKeptOf(key, own)?.map(({ row }) => row) ?? null,
|
|
1565
|
+
signature(key, own = null) {
|
|
1566
|
+
const entry = keptOf(key);
|
|
1567
|
+
if (!entry.reading) return "null";
|
|
1568
|
+
if (entry.signature === null) {
|
|
1569
|
+
const rows = rowsKeptOf(key, own).map((kept2) => {
|
|
1570
|
+
kept2.sign ??= JSON.stringify([serialOf(kept2.row.el), kept2.row.values, kept2.row.links]);
|
|
1571
|
+
return kept2.sign;
|
|
1572
|
+
});
|
|
1573
|
+
entry.signature = `${JSON.stringify([entry.reading.names, entry.reading.merged])}${rows.join(",")}`;
|
|
1574
|
+
}
|
|
1575
|
+
return entry.signature;
|
|
1576
|
+
},
|
|
1577
|
+
follow(keyOf, heardIt) {
|
|
1578
|
+
const follower = { keyOf, heard: heardIt, key: keyOf() ?? null };
|
|
1579
|
+
followers.add(follower);
|
|
1580
|
+
if (!observer) {
|
|
1581
|
+
observer = new MutationObserver(heard);
|
|
1582
|
+
observer.observe(doc.documentElement, { childList: true, subtree: true, characterData: true, attributes: true, attributeOldValue: true, attributeFilter: WATCHED });
|
|
1583
|
+
}
|
|
1584
|
+
return () => {
|
|
1585
|
+
followers.delete(follower);
|
|
1586
|
+
if (followers.size > 0 || !observer) return;
|
|
1587
|
+
observer.disconnect();
|
|
1588
|
+
observer = null;
|
|
1589
|
+
kept.clear();
|
|
1590
|
+
cells = /* @__PURE__ */ new WeakMap();
|
|
1591
|
+
rowsKept = /* @__PURE__ */ new WeakMap();
|
|
1592
|
+
};
|
|
1593
|
+
}
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
// src/render/kit/runtime/rows.js
|
|
1598
|
+
var TEXT = 3;
|
|
1599
|
+
var blankBefore = (node) => {
|
|
1600
|
+
const blank2 = node?.previousSibling;
|
|
1601
|
+
return blank2?.nodeType === TEXT && !blank2.data.trim() ? blank2 : null;
|
|
1602
|
+
};
|
|
1603
|
+
var blankAtEnd = (section) => {
|
|
1604
|
+
const last = section.lastChild;
|
|
1605
|
+
return last?.nodeType === TEXT && !last.data.trim() ? last : null;
|
|
1606
|
+
};
|
|
1607
|
+
var tableOf = (part) => part?.localName === "table" ? part : part?.querySelector?.("table") ?? null;
|
|
1608
|
+
function namedIn(columns, values) {
|
|
1609
|
+
const unknown = Object.keys(values ?? {}).filter((name) => !columns.includes(name));
|
|
1610
|
+
if (unknown.length > 0) throw new Error(`no column ${unknown.map((name) => `"${name}"`).join(", ")} in the table: its columns are ${columns.map((name) => `"${name}"`).join(", ") || "none"}`);
|
|
1611
|
+
return values ?? {};
|
|
1612
|
+
}
|
|
1613
|
+
function rowSet(table2, edit, own = null) {
|
|
1614
|
+
const found = readTable(table2);
|
|
1615
|
+
if (found.merged) return null;
|
|
1616
|
+
const columns = Object.freeze([...found.names]);
|
|
1617
|
+
const rows = Object.freeze(rowsOf2(found, own));
|
|
1618
|
+
const placeOf = (row) => rows.includes(row) && row.el.parentNode && table2.contains(row.el) ? [...table2.rows].indexOf(row.el) : -1;
|
|
1619
|
+
const named = (values) => namedIn(columns, values);
|
|
1620
|
+
const setCells = (row, values) => {
|
|
1621
|
+
columns.forEach((name, index) => {
|
|
1622
|
+
if (!Object.hasOwn(values, name)) return;
|
|
1623
|
+
while (row.cells.length <= index) row.append(row.ownerDocument.createElement("td"));
|
|
1624
|
+
row.cells[index].textContent = String(values[name] ?? "");
|
|
1625
|
+
});
|
|
1626
|
+
};
|
|
1627
|
+
const put = (nodes, next, section) => {
|
|
1628
|
+
const at = next ? blankBefore(next) ?? next : blankAtEnd(section);
|
|
1629
|
+
for (const node of nodes) if (node) (next?.parentNode ?? section).insertBefore(node, at);
|
|
1630
|
+
};
|
|
1631
|
+
const after = (row, skipped) => {
|
|
1632
|
+
let next = row.nextElementSibling;
|
|
1633
|
+
while (next && (next === skipped || next.localName !== "tr")) next = next.nextElementSibling;
|
|
1634
|
+
return next;
|
|
1635
|
+
};
|
|
1636
|
+
return Object.freeze({
|
|
1637
|
+
columns,
|
|
1638
|
+
rows,
|
|
1639
|
+
add(values, at = {}) {
|
|
1640
|
+
const given = named(values);
|
|
1641
|
+
const place = at?.after ? placeOf(at.after) : null;
|
|
1642
|
+
if (place === -1) return false;
|
|
1643
|
+
return edit((draft) => {
|
|
1644
|
+
const all = [...draft.rows];
|
|
1645
|
+
const previous = place === null ? null : all[place];
|
|
1646
|
+
const section = previous?.parentNode ?? draft.tBodies[draft.tBodies.length - 1] ?? draft.createTBody();
|
|
1647
|
+
const model = readTable(draft).rows[0] ?? null;
|
|
1648
|
+
const row = draft.ownerDocument.createElement("tr");
|
|
1649
|
+
columns.forEach((name, index) => {
|
|
1650
|
+
const like = model?.cells[index];
|
|
1651
|
+
const cell = draft.ownerDocument.createElement(like?.localName === "th" ? "th" : "td");
|
|
1652
|
+
if (like?.hasAttribute("scope")) cell.setAttribute("scope", like.getAttribute("scope"));
|
|
1653
|
+
cell.textContent = String(given[name] ?? "");
|
|
1654
|
+
row.append(cell);
|
|
1655
|
+
});
|
|
1656
|
+
const blank2 = blankBefore(previous ?? model ?? section.lastElementChild);
|
|
1657
|
+
put([blank2 ? draft.ownerDocument.createTextNode(blank2.data) : null, row], previous ? after(previous, null) : null, section);
|
|
1658
|
+
});
|
|
1659
|
+
},
|
|
1660
|
+
move(row, to = {}) {
|
|
1661
|
+
const from = placeOf(row);
|
|
1662
|
+
const target = to?.before ?? to?.after ?? null;
|
|
1663
|
+
const there = target ? placeOf(target) : null;
|
|
1664
|
+
const values = to?.values ? named(to.values) : null;
|
|
1665
|
+
if (from === -1 || there === -1) return false;
|
|
1666
|
+
return edit((draft) => {
|
|
1667
|
+
const all = [...draft.rows];
|
|
1668
|
+
const moved = all[from];
|
|
1669
|
+
if (values) setCells(moved, values);
|
|
1670
|
+
if (there === null || there === from) return;
|
|
1671
|
+
const nodes = [blankBefore(moved), moved];
|
|
1672
|
+
if (to.before) put(nodes, all[there], all[there].parentNode);
|
|
1673
|
+
else put(nodes, after(all[there], moved), all[there].parentNode);
|
|
1674
|
+
});
|
|
1675
|
+
},
|
|
1676
|
+
remove(row) {
|
|
1677
|
+
const from = placeOf(row);
|
|
1678
|
+
if (from === -1) return false;
|
|
1679
|
+
return edit((draft) => {
|
|
1680
|
+
const gone = [...draft.rows][from];
|
|
1681
|
+
blankBefore(gone)?.remove();
|
|
1682
|
+
gone.remove();
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
});
|
|
1686
|
+
}
|
|
1687
|
+
|
|
581
1688
|
// src/render/kit/runtime/shown-data.js
|
|
582
1689
|
var DEPTH = 3;
|
|
583
1690
|
var ITEMS = 20;
|
|
584
1691
|
var COLUMNS = 8;
|
|
585
|
-
var
|
|
586
|
-
var
|
|
1692
|
+
var TEXT2 = 200;
|
|
1693
|
+
var MOST2 = 400;
|
|
587
1694
|
var SHORT = 20;
|
|
588
1695
|
var isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
589
|
-
var
|
|
590
|
-
var cut = (text) => text.length >
|
|
1696
|
+
var isValue2 = (value) => value === null || typeof value !== "object";
|
|
1697
|
+
var cut = (text) => text.length > TEXT2 ? `${text.slice(0, TEXT2)}\u2026` : text;
|
|
591
1698
|
var sizeOf = (value) => Array.isArray(value) ? value.length : Object.keys(value).length;
|
|
592
1699
|
function made(doc, tag, text = null, className = null) {
|
|
593
1700
|
const node = doc.createElement(tag);
|
|
@@ -603,7 +1710,7 @@
|
|
|
603
1710
|
}
|
|
604
1711
|
function drawn(doc, value, depth, left) {
|
|
605
1712
|
left.values--;
|
|
606
|
-
if (
|
|
1713
|
+
if (isValue2(value)) return doc.createTextNode(scalar(value));
|
|
607
1714
|
if (sizeOf(value) === 0) return doc.createTextNode(sayRuntime("value-empty"));
|
|
608
1715
|
if (depth >= DEPTH || left.values <= 0) return doc.createTextNode(sayRuntime("value-deeper", String(sizeOf(value))));
|
|
609
1716
|
if (Array.isArray(value) && value.every(isObject)) return table(doc, value, depth, left);
|
|
@@ -644,7 +1751,7 @@
|
|
|
644
1751
|
return node;
|
|
645
1752
|
}
|
|
646
1753
|
function list(doc, items, depth, left) {
|
|
647
|
-
const node = made(doc, "ul", null, depth > 0 && items.every(
|
|
1754
|
+
const node = made(doc, "ul", null, depth > 0 && items.every(isValue2) ? DATA_LINE : null);
|
|
648
1755
|
let shown2 = 0;
|
|
649
1756
|
for (const value of items.slice(0, ITEMS)) {
|
|
650
1757
|
if (left.values <= 0) break;
|
|
@@ -673,7 +1780,7 @@
|
|
|
673
1780
|
const text = script.textContent.trim();
|
|
674
1781
|
let root;
|
|
675
1782
|
try {
|
|
676
|
-
root = text === "" ? doc.createTextNode(sayRuntime("value-empty")) : drawn(doc, JSON.parse(text), 0, { values:
|
|
1783
|
+
root = text === "" ? doc.createTextNode(sayRuntime("value-empty")) : drawn(doc, JSON.parse(text), 0, { values: MOST2 });
|
|
677
1784
|
} catch {
|
|
678
1785
|
root = doc.createTextNode(writing ? sayRuntime("not-json", cut(text)) : cut(text));
|
|
679
1786
|
}
|
|
@@ -686,12 +1793,162 @@
|
|
|
686
1793
|
return root;
|
|
687
1794
|
}
|
|
688
1795
|
|
|
1796
|
+
// src/shared/workspace-query.mjs
|
|
1797
|
+
var QUERY_KINDS = Object.freeze(["todos", "recent", "stats", "activity", "table"]);
|
|
1798
|
+
var FACT_KINDS = Object.freeze(["todos", "recent", "stats", "activity", "table"]);
|
|
1799
|
+
var QUERY_CODES = Object.freeze(["kind", "options", "unsupported", "missing", "offline", "failed"]);
|
|
1800
|
+
var QUERY_LIMITS = Object.freeze({ todos: { default: 200, most: 1e3 }, recent: { default: 10, most: 50 }, activity: { default: 365, most: 371 }, table: { default: 200, most: 1e3 } });
|
|
1801
|
+
var SNAPSHOT_LIMITS = Object.freeze({ todos: 200, recent: 50, activity: 371, tables: 20, rows: 1e3 });
|
|
1802
|
+
var TODO_EVENT = "doc-todo-set";
|
|
1803
|
+
var TODO_CODES = Object.freeze(["ref", "changed", "ambiguous", "locked", "missing", "busy", "offline", "failed"]);
|
|
1804
|
+
var SLUG2 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
1805
|
+
var BLOCK = /^[A-Za-z0-9_-]{1,64}$/;
|
|
1806
|
+
var VERSION = /^[a-f0-9]{16}$/;
|
|
1807
|
+
function todoRef(ref) {
|
|
1808
|
+
if (!ref || typeof ref !== "object" || Array.isArray(ref)) return null;
|
|
1809
|
+
const { slug, block = null, text, path, nth, version = null } = ref;
|
|
1810
|
+
if (typeof slug !== "string" || !SLUG2.test(slug) || block !== null && (typeof block !== "string" || !BLOCK.test(block))) return null;
|
|
1811
|
+
if (typeof text !== "string" || text.length > 4e3 || !Array.isArray(path) || path.length > 6 || !path.every((step) => typeof step === "string" && step.length <= 4e3)) return null;
|
|
1812
|
+
if (!Number.isInteger(nth) || nth < 0 || version !== null && (typeof version !== "string" || !VERSION.test(version))) return null;
|
|
1813
|
+
return { slug, block, text, path: [...path], nth, version };
|
|
1814
|
+
}
|
|
1815
|
+
var WORKSPACE_GLOBAL = "__galleryWorkspace";
|
|
1816
|
+
var OPEN_EVENT = "doc-open-request";
|
|
1817
|
+
function queryOptions(kind, options) {
|
|
1818
|
+
const given = options ?? {};
|
|
1819
|
+
if (typeof given !== "object" || Array.isArray(given)) return { problem: "its options are an object" };
|
|
1820
|
+
const count = (name, { default: fallback, most }) => {
|
|
1821
|
+
const value = given[name];
|
|
1822
|
+
if (value === void 0) return fallback;
|
|
1823
|
+
if (!Number.isInteger(value) || value < 1) throw new Error(`${name} is a whole number from 1`);
|
|
1824
|
+
return Math.min(value, most);
|
|
1825
|
+
};
|
|
1826
|
+
try {
|
|
1827
|
+
if (kind === "todos") {
|
|
1828
|
+
if (given.done !== void 0 && typeof given.done !== "boolean") return { problem: "done is true or false" };
|
|
1829
|
+
if (given.slugs !== void 0 && !(Array.isArray(given.slugs) && given.slugs.every((slug) => typeof slug === "string"))) return { problem: "slugs is a list of documents' slugs" };
|
|
1830
|
+
return { options: { done: given.done, slugs: given.slugs ?? null, limit: count("limit", QUERY_LIMITS.todos) } };
|
|
1831
|
+
}
|
|
1832
|
+
if (kind === "recent") return { options: { limit: count("limit", QUERY_LIMITS.recent) } };
|
|
1833
|
+
if (kind === "table") {
|
|
1834
|
+
if (typeof given.slug !== "string" || !SLUG2.test(given.slug)) return { problem: "slug is a document's slug" };
|
|
1835
|
+
if (typeof given.key !== "string" || !CHART_KEY.test(given.key)) return { problem: "key is a table's key (data-doc-chart-source)" };
|
|
1836
|
+
const where = given.where ?? {};
|
|
1837
|
+
if (typeof where !== "object" || Array.isArray(where) || !Object.values(where).every((value) => typeof value === "string")) return { problem: "where maps each column to the words its cells are to hold" };
|
|
1838
|
+
return { options: { slug: given.slug, key: given.key, where: { ...where }, limit: count("limit", QUERY_LIMITS.table) } };
|
|
1839
|
+
}
|
|
1840
|
+
if (kind === "activity") return { options: { days: count("days", QUERY_LIMITS.activity) } };
|
|
1841
|
+
return { options: {} };
|
|
1842
|
+
} catch (error) {
|
|
1843
|
+
return { problem: error.message };
|
|
1844
|
+
}
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
// src/render/kit/runtime/workspace.js
|
|
1848
|
+
var ASKED = /* @__PURE__ */ new Set(["kind", "options", "unsupported", "missing"]);
|
|
1849
|
+
var SLUG3 = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
1850
|
+
var BLOCK2 = /^[A-Za-z0-9_-]{1,64}$/;
|
|
1851
|
+
var embedded;
|
|
1852
|
+
var snapshotOf = () => {
|
|
1853
|
+
if (embedded !== void 0) return embedded;
|
|
1854
|
+
const tag = document.querySelector("script[data-doc-snapshot]");
|
|
1855
|
+
try {
|
|
1856
|
+
const value = JSON.parse(tag?.textContent ?? "null");
|
|
1857
|
+
embedded = value && typeof value === "object" ? { value, at: tag.getAttribute("data-at") ?? "" } : null;
|
|
1858
|
+
} catch {
|
|
1859
|
+
embedded = null;
|
|
1860
|
+
}
|
|
1861
|
+
return embedded;
|
|
1862
|
+
};
|
|
1863
|
+
function fromSnapshot(kind, used) {
|
|
1864
|
+
const value = snapshotOf()?.value;
|
|
1865
|
+
if (!value) return void 0;
|
|
1866
|
+
if (kind === "todos") {
|
|
1867
|
+
if (!Array.isArray(value.todos)) return void 0;
|
|
1868
|
+
return value.todos.filter((todo) => (used.done === void 0 || todo.done === used.done) && (!used.slugs || used.slugs.includes(todo.slug))).slice(0, used.limit);
|
|
1869
|
+
}
|
|
1870
|
+
if (kind === "recent") return Array.isArray(value.recent) ? value.recent.slice(0, used.limit) : void 0;
|
|
1871
|
+
if (kind === "stats") return value.stats && typeof value.stats === "object" ? value.stats : void 0;
|
|
1872
|
+
if (kind === "activity") return Array.isArray(value.activity) ? value.activity.slice(-used.days) : void 0;
|
|
1873
|
+
const table2 = value.tables?.[`${used.slug}#${used.key}`];
|
|
1874
|
+
if (!table2 || !Array.isArray(table2.columns) || !Array.isArray(table2.rows)) return void 0;
|
|
1875
|
+
const tidy = (text) => String(text).replace(/\s+/g, " ").trim();
|
|
1876
|
+
const words = (value2) => value2 === null || value2 === void 0 ? "" : tidy(value2);
|
|
1877
|
+
const rows = table2.rows.filter((row) => Object.entries(used.where).every(([name, wanted]) => (row.words ? tidy(row.words[name] ?? "") : words(row.values?.[name])) === tidy(wanted)));
|
|
1878
|
+
return { columns: table2.columns, rows: rows.slice(0, used.limit).map(({ values, links }) => ({ values, links })), total: rows.length };
|
|
1879
|
+
}
|
|
1880
|
+
function workspaceOf({ id, place, kinds }) {
|
|
1881
|
+
const refused = (message, code) => Promise.reject(Object.assign(new Error(`${id}: ${message}`), { code }));
|
|
1882
|
+
const own = () => document.querySelector(".doc-page")?.dataset.docId || null;
|
|
1883
|
+
const member = {
|
|
1884
|
+
query(kind, options = {}) {
|
|
1885
|
+
if (!QUERY_KINDS.includes(kind)) return refused(`workspace.query knows no kind "${kind}": todos, recent, stats, activity or table`, "kind");
|
|
1886
|
+
kinds.add(kind);
|
|
1887
|
+
if (place === "export") {
|
|
1888
|
+
const { problem, options: used } = queryOptions(kind, options);
|
|
1889
|
+
if (problem) return refused(`${kind}: ${problem}`, "options");
|
|
1890
|
+
const data = fromSnapshot(kind, used);
|
|
1891
|
+
if (data === void 0) return refused("an exported file has no workspace to read, and its export kept none of this: open it in Gallery", "offline");
|
|
1892
|
+
return Promise.resolve({ data, at: snapshotOf()?.at ?? "" });
|
|
1893
|
+
}
|
|
1894
|
+
const route = globalThis[WORKSPACE_GLOBAL];
|
|
1895
|
+
if (typeof route !== "string") return refused("an exported file has no workspace to read: open it in Gallery", "offline");
|
|
1896
|
+
let given;
|
|
1897
|
+
try {
|
|
1898
|
+
given = JSON.stringify(options ?? {});
|
|
1899
|
+
} catch {
|
|
1900
|
+
return refused("its options are no JSON", "options");
|
|
1901
|
+
}
|
|
1902
|
+
const doc = kind === "table" && place === "document" ? own() : null;
|
|
1903
|
+
const address = `${route}?kind=${encodeURIComponent(kind)}&options=${encodeURIComponent(given)}${doc ? `&doc=${encodeURIComponent(doc)}` : ""}`;
|
|
1904
|
+
return fetch(address, { cache: "no-store", credentials: "same-origin" }).then(
|
|
1905
|
+
(response) => response.json().then((answer) => {
|
|
1906
|
+
if (answer?.ok) return { data: answer.data, at: answer.at };
|
|
1907
|
+
const message = typeof answer?.message === "string" ? answer.message : `the server answered ${response.status}`;
|
|
1908
|
+
return ASKED.has(answer?.reason) ? refused(message, answer.reason) : refused(`the workspace could not be read: ${message}`, "failed");
|
|
1909
|
+
}, () => refused(`the workspace could not be read: the server answered ${response.status}`, "failed")),
|
|
1910
|
+
() => refused("the server that showed this page does not answer", "offline")
|
|
1911
|
+
);
|
|
1912
|
+
},
|
|
1913
|
+
open(target) {
|
|
1914
|
+
if (place === "export") return;
|
|
1915
|
+
const page = typeof target?.page === "string" ? target.page : null;
|
|
1916
|
+
const slug = typeof target?.slug === "string" ? target.slug : null;
|
|
1917
|
+
const block = typeof target?.block === "string" && target.block ? target.block : null;
|
|
1918
|
+
if (!(page ? SLUG3.test(page) : slug && SLUG3.test(slug)) || block !== null && !BLOCK2.test(block)) throw new Error(`${id}: workspace.open is given { slug, block? } of a document or { page } of a custom page`);
|
|
1919
|
+
const detail = page ? { page } : { slug, block };
|
|
1920
|
+
const asked = new CustomEvent(OPEN_EVENT, { cancelable: true, detail });
|
|
1921
|
+
if (!globalThis.dispatchEvent(asked)) return;
|
|
1922
|
+
globalThis.location.assign(page ? `/pages/${page}` : `/generated/${slug}.html${block ? `#${encodeURIComponent(block)}` : ""}`);
|
|
1923
|
+
}
|
|
1924
|
+
};
|
|
1925
|
+
if (place !== "export") {
|
|
1926
|
+
member.setTodo = (ref, done) => {
|
|
1927
|
+
const given = todoRef(ref);
|
|
1928
|
+
if (!given || typeof done !== "boolean") return refused(`workspace.setTodo is given a to-do's ref as query("todos") gave it, and true or false`, "ref");
|
|
1929
|
+
let answer = null;
|
|
1930
|
+
const asked = new CustomEvent(TODO_EVENT, { cancelable: true, detail: { ask: { slug: given.slug, ref: given, done }, answer: (promise) => {
|
|
1931
|
+
answer = promise;
|
|
1932
|
+
} } });
|
|
1933
|
+
globalThis.dispatchEvent(asked);
|
|
1934
|
+
if (!asked.defaultPrevented || !answer) return refused("nothing on this page writes the workspace: open it in Gallery's workbench", "offline");
|
|
1935
|
+
return Promise.resolve(answer).then((result) => {
|
|
1936
|
+
if (result?.ok) return result.changed === true;
|
|
1937
|
+
const code = TODO_CODES.includes(result?.reason) ? result.reason : "failed";
|
|
1938
|
+
return refused(typeof result?.message === "string" ? result.message : `the to-do could not be written (${result?.reason ?? "no answer"})`, code);
|
|
1939
|
+
}, () => refused("the server that showed this page does not answer", "offline"));
|
|
1940
|
+
};
|
|
1941
|
+
}
|
|
1942
|
+
return Object.freeze(member);
|
|
1943
|
+
}
|
|
1944
|
+
|
|
689
1945
|
// src/render/kit/runtime/kernel.js
|
|
690
1946
|
function createKit({ descriptions }) {
|
|
691
1947
|
const global2 = globalThis;
|
|
692
1948
|
const defs = /* @__PURE__ */ new Map();
|
|
693
1949
|
const instances = /* @__PURE__ */ new Map();
|
|
694
1950
|
const counters = { mounted: 0, destroyed: 0, failed: 0 };
|
|
1951
|
+
const tables = createKeyedTables();
|
|
695
1952
|
const preview = () => !document.querySelector('meta[name="generator"][content="Gallery"], meta[name="generator"][content="HTML Report Studio"], meta[name="doc-export-id"]');
|
|
696
1953
|
const writing = () => preview() && !new URLSearchParams(location.search).has("present");
|
|
697
1954
|
const selectorOf = (def) => def.selector ?? descriptions.get(def.id)?.match;
|
|
@@ -720,17 +1977,21 @@
|
|
|
720
1977
|
instance.note = null;
|
|
721
1978
|
}
|
|
722
1979
|
const queued = /* @__PURE__ */ new Map();
|
|
1980
|
+
const toHear = /* @__PURE__ */ new Map();
|
|
723
1981
|
let frame = 0;
|
|
724
1982
|
let asked = 0;
|
|
725
1983
|
function runFrame() {
|
|
726
1984
|
frame = 0;
|
|
1985
|
+
const told = [...toHear];
|
|
1986
|
+
toHear.clear();
|
|
1987
|
+
for (const [host, records] of told) tell(host, "source", records);
|
|
727
1988
|
const work = [...queued];
|
|
728
1989
|
queued.clear();
|
|
729
1990
|
for (const [host, run] of work) {
|
|
730
1991
|
const instance = instances.get(host);
|
|
731
1992
|
if (!instance) continue;
|
|
732
1993
|
try {
|
|
733
|
-
run
|
|
1994
|
+
guarded(instance, host, run, "drew in a frame");
|
|
734
1995
|
clearNote(instance);
|
|
735
1996
|
} catch (error) {
|
|
736
1997
|
report(instance.def, host, error);
|
|
@@ -739,10 +2000,58 @@
|
|
|
739
2000
|
asked = queued.size > 0 ? asked + 1 : 0;
|
|
740
2001
|
settle();
|
|
741
2002
|
}
|
|
2003
|
+
const ask = () => {
|
|
2004
|
+
if (!frame) frame = requestAnimationFrame(runFrame);
|
|
2005
|
+
};
|
|
742
2006
|
function schedule(host, run) {
|
|
743
2007
|
if (instances.get(host)?.failed) return;
|
|
744
2008
|
queued.set(host, run);
|
|
745
|
-
|
|
2009
|
+
ask();
|
|
2010
|
+
}
|
|
2011
|
+
function hearLater(host, records) {
|
|
2012
|
+
const pending = toHear.get(host);
|
|
2013
|
+
if (pending) pending.push(...records);
|
|
2014
|
+
else toHear.set(host, records);
|
|
2015
|
+
ask();
|
|
2016
|
+
}
|
|
2017
|
+
const GUARD = { childList: true, subtree: true, characterData: true, characterDataOldValue: true, attributes: true, attributeOldValue: true };
|
|
2018
|
+
function guarded(instance, host, run, when) {
|
|
2019
|
+
const slots = ofPackage(instance.def) ? slotsIn(host) : [];
|
|
2020
|
+
if (slots.length === 0) return run();
|
|
2021
|
+
const guard = new MutationObserver(() => {
|
|
2022
|
+
});
|
|
2023
|
+
guard.observe(host, GUARD);
|
|
2024
|
+
let result;
|
|
2025
|
+
let failure = null;
|
|
2026
|
+
try {
|
|
2027
|
+
result = run();
|
|
2028
|
+
} catch (error) {
|
|
2029
|
+
failure = error;
|
|
2030
|
+
}
|
|
2031
|
+
const records = guard.takeRecords();
|
|
2032
|
+
guard.disconnect();
|
|
2033
|
+
const touches = (slot2) => records.some((record) => slot2.contains(record.target) || record.type === "childList" && [...record.addedNodes, ...record.removedNodes].some((node) => node === slot2 || node.contains?.(slot2)));
|
|
2034
|
+
const slot = slots.find(touches);
|
|
2035
|
+
if (!slot) {
|
|
2036
|
+
if (failure) throw failure;
|
|
2037
|
+
return result;
|
|
2038
|
+
}
|
|
2039
|
+
putBack(records);
|
|
2040
|
+
throw Object.assign(new Error(`it wrote in its slot "${slot.getAttribute(SLOT)}" as it ${when}, which is put back: a slot holds the document's blocks, the reader's; read it with context.part, and draw outside it`), { made: result });
|
|
2041
|
+
}
|
|
2042
|
+
function putBack(records) {
|
|
2043
|
+
for (const record of [...records].reverse()) {
|
|
2044
|
+
const { target } = record;
|
|
2045
|
+
if (record.type === "characterData") target.data = record.oldValue ?? "";
|
|
2046
|
+
else if (record.type === "attributes") {
|
|
2047
|
+
if (record.oldValue === null) target.removeAttributeNS(record.attributeNamespace, record.attributeName);
|
|
2048
|
+
else target.setAttributeNS(record.attributeNamespace, record.attributeName, record.oldValue);
|
|
2049
|
+
} else {
|
|
2050
|
+
for (const node of record.addedNodes) if (node.parentNode === target) target.removeChild(node);
|
|
2051
|
+
const next = record.nextSibling?.parentNode === target ? record.nextSibling : null;
|
|
2052
|
+
for (const node of record.removedNodes) target.insertBefore(node, next);
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
746
2055
|
}
|
|
747
2056
|
const ENDLESS = 30;
|
|
748
2057
|
let drawn2 = false;
|
|
@@ -769,7 +2078,7 @@
|
|
|
769
2078
|
const instance = instances.get(host);
|
|
770
2079
|
if (!instance?.handle?.update) return;
|
|
771
2080
|
try {
|
|
772
|
-
instance.handle.update(reason, detail, options);
|
|
2081
|
+
guarded(instance, host, () => instance.handle.update(reason, detail, options), `heard ${reason}`);
|
|
773
2082
|
} catch (error) {
|
|
774
2083
|
report(instance.def, host, error);
|
|
775
2084
|
}
|
|
@@ -795,29 +2104,107 @@
|
|
|
795
2104
|
global2.addEventListener("resize", () => tellAll("viewport"));
|
|
796
2105
|
document.fonts?.ready.then(() => tellAll("fonts"));
|
|
797
2106
|
document.fonts?.addEventListener?.("loadingdone", (event) => tellAll("fonts", [...event.fontfaces ?? []]));
|
|
798
|
-
|
|
799
|
-
|
|
2107
|
+
global2.addEventListener("doc-workspace-change", (event) => listening("data").forEach(([host, instance]) => {
|
|
2108
|
+
if (instance.kinds?.has(event.detail)) tell(host, "data", event.detail);
|
|
2109
|
+
}));
|
|
2110
|
+
let clockTimer = 0;
|
|
2111
|
+
let today = null;
|
|
2112
|
+
function armClock() {
|
|
2113
|
+
if (clockTimer || listening("clock").length === 0) return;
|
|
2114
|
+
const now = /* @__PURE__ */ new Date();
|
|
2115
|
+
today ??= now.toDateString();
|
|
2116
|
+
clockTimer = global2.setTimeout(tick, 6e4 - (now.getSeconds() * 1e3 + now.getMilliseconds()) + 5);
|
|
2117
|
+
}
|
|
2118
|
+
function tick() {
|
|
2119
|
+
clockTimer = 0;
|
|
2120
|
+
const day = (/* @__PURE__ */ new Date()).toDateString();
|
|
2121
|
+
const detail = day === today ? "minute" : "day";
|
|
2122
|
+
today = day;
|
|
2123
|
+
tellAll("clock", detail);
|
|
2124
|
+
armClock();
|
|
2125
|
+
}
|
|
2126
|
+
const ownedBy = (node, host) => node.parentElement.closest(INSTANCE) === host && heldBy(node) === host;
|
|
2127
|
+
const partsIn = (host, at, edit = null) => [...host.querySelectorAll(at)].filter((node) => !node.matches(INSTANCE) && ownedBy(node, host) && edit === "flow" === node.matches(SLOT_PART));
|
|
2128
|
+
const placeOf = (host) => host.closest(PAGE2) ? "page" : preview() ? "document" : "export";
|
|
2129
|
+
const HASHED_OUT = /^(?:data-block-id|data-ge-.*|contenteditable|spellcheck|data-doc-fallback.*|inert)$/;
|
|
2130
|
+
const hashes = /* @__PURE__ */ new WeakMap();
|
|
2131
|
+
function markupHash(def, host) {
|
|
2132
|
+
if (hashes.has(host)) return hashes.get(host);
|
|
2133
|
+
const copy = host.cloneNode(true);
|
|
2134
|
+
try {
|
|
2135
|
+
def.dehydrate?.(copy);
|
|
2136
|
+
} catch {
|
|
2137
|
+
}
|
|
2138
|
+
takeRuntime(descriptions.get(def.id), copy);
|
|
2139
|
+
for (const { at, edit } of Object.values(descriptions.get(def.id)?.parts ?? {})) {
|
|
2140
|
+
if (edit === "text" || edit === "data" || edit === "flow") partsIn(copy, at, edit).forEach((node) => node.replaceChildren());
|
|
2141
|
+
}
|
|
2142
|
+
const attributes = (node) => [...node.attributes].filter(({ name }) => !HASHED_OUT.test(name)).map(({ name, value }) => ` ${name}="${value}"`).sort().join("");
|
|
2143
|
+
const shape = (node) => `<${node.localName}${attributes(node)}>${[...node.children].filter((child) => !child.matches(`[data-doc-dev], .${NOTE}, .${DATA_SHOWN}`)).map(shape).join("")}`;
|
|
2144
|
+
let hash = 2166136261;
|
|
2145
|
+
for (const char of shape(copy)) hash = Math.imul(hash ^ char.codePointAt(0), 16777619);
|
|
2146
|
+
const made2 = (hash >>> 0).toString(36);
|
|
2147
|
+
hashes.set(host, made2);
|
|
2148
|
+
return made2;
|
|
2149
|
+
}
|
|
2150
|
+
function stateName(def, host) {
|
|
2151
|
+
const card = placeOf(host) === "page" ? host.closest(CARD)?.getAttribute(CARD_ID) : null;
|
|
2152
|
+
if (card) return { id: `${def.id}:${card}` };
|
|
2153
|
+
const hashed = () => {
|
|
2154
|
+
const hash = markupHash(def, host);
|
|
2155
|
+
const alike = hostsIn(document, selectorOf(def)).filter((other) => !outsidePage(other) && !inOther(def, other) && markupHash(def, other) === hash);
|
|
2156
|
+
return `${def.id}:${hash}:${Math.max(0, alike.indexOf(host))}`;
|
|
2157
|
+
};
|
|
2158
|
+
const block = host.getAttribute("data-block-id");
|
|
2159
|
+
return block ? { id: `${def.id}:${block}`, formerId: hashed() } : { id: hashed() };
|
|
2160
|
+
}
|
|
2161
|
+
const ownSlug = () => document.querySelector(".doc-page")?.dataset.docId || null;
|
|
800
2162
|
const canEdit = (def, host) => editable && instances.get(host)?.failed === false && !schemaAhead(host.getAttribute(SCHEMA), descriptions.get(def.id)?.schema);
|
|
801
2163
|
const partNamed = (def, name) => {
|
|
802
2164
|
const part = descriptions.get(def.id)?.parts?.[name];
|
|
803
2165
|
if (!part) throw new Error(`no part "${name}" in ${def.id}'s manifest`);
|
|
804
2166
|
return part;
|
|
805
2167
|
};
|
|
806
|
-
|
|
807
|
-
part
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
2168
|
+
function packageContext(def, host, instance) {
|
|
2169
|
+
const part = (name) => partsIn(host, partNamed(def, name).at, partNamed(def, name).edit)[0] ?? null;
|
|
2170
|
+
const place = placeOf(host);
|
|
2171
|
+
const needs = descriptions.get(def.id)?.needs ?? [];
|
|
2172
|
+
const ended = () => instances.get(host) !== instance || instance.failed;
|
|
2173
|
+
const timers = /* @__PURE__ */ new Map();
|
|
2174
|
+
const timer = (set, clear2, run, ms, once) => {
|
|
2175
|
+
if (typeof run !== "function") throw new Error(`${def.id}: a timer runs a function`);
|
|
2176
|
+
const { signal } = instance.controller;
|
|
2177
|
+
if (signal.aborted) return 0;
|
|
2178
|
+
if (!timers.armed) {
|
|
2179
|
+
timers.armed = true;
|
|
2180
|
+
signal.addEventListener("abort", () => {
|
|
2181
|
+
for (const [id2, clearIt] of timers) clearIt.call(global2, id2);
|
|
2182
|
+
timers.clear();
|
|
2183
|
+
}, { once: true });
|
|
2184
|
+
}
|
|
2185
|
+
const id = set.call(global2, () => {
|
|
2186
|
+
if (once) timers.delete(id);
|
|
2187
|
+
if (ended()) return;
|
|
2188
|
+
try {
|
|
2189
|
+
guarded(instance, host, run, "ran a timer");
|
|
2190
|
+
} catch (error) {
|
|
2191
|
+
report(def, host, error);
|
|
2192
|
+
}
|
|
2193
|
+
}, ms);
|
|
2194
|
+
timers.set(id, clear2);
|
|
2195
|
+
return id;
|
|
2196
|
+
};
|
|
2197
|
+
const edit = (names, change) => {
|
|
811
2198
|
if (!canEdit(def, host)) return false;
|
|
812
2199
|
const several = Array.isArray(names);
|
|
813
2200
|
const parts = (several ? names : [names]).map((name) => {
|
|
814
|
-
const { at, edit } = partNamed(def, name);
|
|
815
|
-
if (
|
|
816
|
-
return { name, part: partsIn(host, at)[0] };
|
|
2201
|
+
const { at, edit: edit2 } = partNamed(def, name);
|
|
2202
|
+
if (edit2 !== "data") throw new Error(`the part "${name}" of ${def.id} is not edited as data`);
|
|
2203
|
+
return { name, part: partsIn(host, at, edit2)[0] };
|
|
817
2204
|
});
|
|
818
|
-
const apart = parts.find(({ part }, index) => parts.some((other, at) => at !== index &&
|
|
2205
|
+
const apart = parts.find(({ part: part2 }, index) => parts.some((other, at) => at !== index && part2 && other.part && (part2 === other.part || other.part.contains(part2))));
|
|
819
2206
|
if (apart) throw new Error(`the part "${apart.name}" of ${def.id} is in another this edit names, or is it: name the one around it`);
|
|
820
|
-
if (parts.length === 0 || parts.some(({ part }) => !
|
|
2207
|
+
if (parts.length === 0 || parts.some(({ part: part2 }) => !part2)) return false;
|
|
821
2208
|
const run = (drafts) => {
|
|
822
2209
|
try {
|
|
823
2210
|
if (typeof change(several ? drafts : drafts[names])?.then === "function") throw new Error(`a change of ${several ? names.map((name) => `"${name}"`).join(", ") : `"${names}"`} runs at once: context.edit does not wait for it`);
|
|
@@ -828,12 +2215,163 @@
|
|
|
828
2215
|
}
|
|
829
2216
|
};
|
|
830
2217
|
return !host.dispatchEvent(new CustomEvent("doc-component-edit", { bubbles: true, cancelable: true, detail: { parts, run } }));
|
|
2218
|
+
};
|
|
2219
|
+
return {
|
|
2220
|
+
part,
|
|
2221
|
+
state: ({ version, defaults, transientKeys }) => global2.DocState.getOrCreate({ ...stateName(def, host), version, defaults, transientKeys }),
|
|
2222
|
+
canEdit: () => canEdit(def, host),
|
|
2223
|
+
edit,
|
|
2224
|
+
// A part's JSON, parsed (JSON's null too, as any value it holds); undefined where there is nothing
|
|
2225
|
+
// to read, which no JSON is: an optional part the instance does not hold, and one that holds no
|
|
2226
|
+
// JSON, which fails the instance (context.fail), as its data cannot be read.
|
|
2227
|
+
readJSON(name) {
|
|
2228
|
+
const node = part(name);
|
|
2229
|
+
if (!node) return void 0;
|
|
2230
|
+
try {
|
|
2231
|
+
return JSON.parse(node.textContent ?? "");
|
|
2232
|
+
} catch (error) {
|
|
2233
|
+
report(def, host, new Error(`its part "${name}" holds no JSON: ${error.message}`));
|
|
2234
|
+
return void 0;
|
|
2235
|
+
}
|
|
2236
|
+
},
|
|
2237
|
+
// An edit of a part of JSON (a script of data): `change` is handed what it holds, parsed, and changes
|
|
2238
|
+
// it or returns what is to stand there instead; written back as it was laid out (json-layout.mjs
|
|
2239
|
+
// jsonIn), and not at all where it holds what it held.
|
|
2240
|
+
editJSON(name, change) {
|
|
2241
|
+
if (typeof name !== "string") throw new Error(`${def.id}: context.editJSON names one part`);
|
|
2242
|
+
return edit(name, (script) => {
|
|
2243
|
+
const text = script.textContent ?? "";
|
|
2244
|
+
let data;
|
|
2245
|
+
try {
|
|
2246
|
+
data = JSON.parse(text);
|
|
2247
|
+
} catch (error) {
|
|
2248
|
+
throw new Error(`its part "${name}" holds no JSON: ${error.message}`);
|
|
2249
|
+
}
|
|
2250
|
+
const result = change(data);
|
|
2251
|
+
if (typeof result?.then === "function") throw new Error(`a change of "${name}" runs at once: context.editJSON does not wait for it`);
|
|
2252
|
+
const next = result === void 0 ? data : result;
|
|
2253
|
+
if (JSON.stringify(next) !== JSON.stringify(JSON.parse(text))) script.textContent = jsonIn(text, next);
|
|
2254
|
+
});
|
|
2255
|
+
},
|
|
2256
|
+
// The rows of the table a part is or holds (rows.js), each write of them one edit of that part.
|
|
2257
|
+
rows(name) {
|
|
2258
|
+
const table2 = tableOf(part(name));
|
|
2259
|
+
if (!table2) return null;
|
|
2260
|
+
return rowSet(table2, (change) => edit(name, (draft) => {
|
|
2261
|
+
const drafted = tableOf(draft);
|
|
2262
|
+
if (!drafted) throw new Error(`its part "${name}" holds no table`);
|
|
2263
|
+
change(drafted);
|
|
2264
|
+
}), ownSlug());
|
|
2265
|
+
},
|
|
2266
|
+
// The table of the document this instance is a view of (a block whose needs hold "tables": VIEW_FROM
|
|
2267
|
+
// names its key), read now: its rows as context.rows gives them, and what changes it, each asked of
|
|
2268
|
+
// the page editor (tableView).
|
|
2269
|
+
table: () => tableView(def, host, instance, place),
|
|
2270
|
+
interval: (run, ms) => timer(global2.setInterval, global2.clearInterval, run, ms, false),
|
|
2271
|
+
timeout: (run, ms) => timer(global2.setTimeout, global2.clearTimeout, run, ms, true),
|
|
2272
|
+
// A listener that goes as the instance ends, or as the signal of its own options aborts.
|
|
2273
|
+
listen(target, type, run, options = {}) {
|
|
2274
|
+
const given = typeof options === "boolean" ? { capture: options } : { ...options ?? {} };
|
|
2275
|
+
const own = given.signal;
|
|
2276
|
+
if (own?.aborted || instance.controller.signal.aborted) return;
|
|
2277
|
+
target.addEventListener(type, run, { ...given, signal: instance.controller.signal });
|
|
2278
|
+
own?.addEventListener("abort", () => target.removeEventListener(type, run, { capture: Boolean(given.capture) }), { once: true });
|
|
2279
|
+
},
|
|
2280
|
+
place,
|
|
2281
|
+
// A block whose needs name a host of the net reaches it through the server (net.js), nothing else.
|
|
2282
|
+
...netHostsOf(descriptions.get(def.id)?.needs).length > 0 ? { fetch: net.fetchFor(def, host, place) } : {},
|
|
2283
|
+
// Its card's size on a custom page, in the grid's cells (what the board draws it at, never the raw
|
|
2284
|
+
// attributes: card-size.mjs drawnCells) and in pixels, what its card holds inside its padding; null
|
|
2285
|
+
// anywhere else. The page says when it changes: `layout`.
|
|
2286
|
+
get size() {
|
|
2287
|
+
const card = place === "page" ? host.closest(CARD) : null;
|
|
2288
|
+
if (!card) return null;
|
|
2289
|
+
const style = global2.getComputedStyle(card);
|
|
2290
|
+
const inner = (size, ...sides) => Math.max(0, Math.round(size - sides.reduce((sum, side) => sum + (parseFloat(style[side]) || 0), 0)));
|
|
2291
|
+
return { ...drawnCells(card), width: inner(card.clientWidth, "paddingLeft", "paddingRight"), height: inner(card.clientHeight, "paddingTop", "paddingBottom") };
|
|
2292
|
+
},
|
|
2293
|
+
// What it reads of the workspace, where its manifest's needs say "workspace" (workspace.js), and none elsewhere.
|
|
2294
|
+
...needs.includes("workspace") ? { workspace: workspaceOf({ id: def.id, place, kinds: instance.kinds = /* @__PURE__ */ new Set() }) } : {}
|
|
2295
|
+
};
|
|
2296
|
+
}
|
|
2297
|
+
const tablesTold = /* @__PURE__ */ new Set();
|
|
2298
|
+
const readsTables = (def) => descriptions.get(def.id)?.needs?.includes("tables") ?? false;
|
|
2299
|
+
function following(def, host, instance) {
|
|
2300
|
+
if (instance.view) return instance.view;
|
|
2301
|
+
const signature = () => {
|
|
2302
|
+
const key = host.getAttribute(VIEW_FROM);
|
|
2303
|
+
return key ? tables.signature(key, ownSlug()) : "none";
|
|
2304
|
+
};
|
|
2305
|
+
const view = { listeners: /* @__PURE__ */ new Set(), told: signature() };
|
|
2306
|
+
instance.view = view;
|
|
2307
|
+
const unfollow = tables.follow(() => host.getAttribute(VIEW_FROM), () => {
|
|
2308
|
+
if (instances.get(host) !== instance || instance.failed) return;
|
|
2309
|
+
const now = signature();
|
|
2310
|
+
if (now === view.told) return;
|
|
2311
|
+
view.told = now;
|
|
2312
|
+
for (const listener of [...view.listeners]) {
|
|
2313
|
+
try {
|
|
2314
|
+
guarded(instance, host, listener, "heard its table");
|
|
2315
|
+
} catch (error) {
|
|
2316
|
+
report(def, host, error);
|
|
2317
|
+
return;
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
if (def.on?.includes("data")) tell(host, "data", "table");
|
|
2321
|
+
});
|
|
2322
|
+
instance.controller.signal.addEventListener("abort", unfollow, { once: true });
|
|
2323
|
+
return view;
|
|
2324
|
+
}
|
|
2325
|
+
function tableView(def, host, instance, place) {
|
|
2326
|
+
if (!readsTables(def)) {
|
|
2327
|
+
if (!tablesTold.has(def.id)) console.error(`[DocKit] ${def.id}: context.table() reads a table for a block whose manifest's needs hold "tables"`);
|
|
2328
|
+
tablesTold.add(def.id);
|
|
2329
|
+
return null;
|
|
831
2330
|
}
|
|
832
|
-
|
|
2331
|
+
const key = host.getAttribute(VIEW_FROM);
|
|
2332
|
+
const reading = place === "page" || !key ? null : tables.reading(key);
|
|
2333
|
+
if (!reading || reading.merged) return null;
|
|
2334
|
+
const { table: table2 } = reading;
|
|
2335
|
+
const columns = Object.freeze([...reading.names]);
|
|
2336
|
+
const rows = Object.freeze([...tables.rows(key, ownSlug())]);
|
|
2337
|
+
const live2 = (row) => rows.includes(row) && table2.isConnected && table2.contains(row.el);
|
|
2338
|
+
const cellsOf2 = (values) => Object.entries(namedIn(columns, values)).map(([name, text]) => [columns.lastIndexOf(name), String(text ?? "")]);
|
|
2339
|
+
const ask2 = (detail) => place === "document" && canEdit(def, host) && !host.dispatchEvent(new CustomEvent("doc-table-intent", { bubbles: true, cancelable: true, detail: { table: table2, ...detail } }));
|
|
2340
|
+
return Object.freeze({
|
|
2341
|
+
columns,
|
|
2342
|
+
rows,
|
|
2343
|
+
canEdit: () => ask2({ op: "check" }),
|
|
2344
|
+
set(row, column, text) {
|
|
2345
|
+
const cells = cellsOf2({ [column]: text });
|
|
2346
|
+
return live2(row) && ask2({ op: "set", row: row.el, cells });
|
|
2347
|
+
},
|
|
2348
|
+
add(values, at = {}) {
|
|
2349
|
+
const cells = cellsOf2(values);
|
|
2350
|
+
if (at?.after && !live2(at.after)) return false;
|
|
2351
|
+
return ask2({ op: "add", after: at?.after?.el ?? null, cells });
|
|
2352
|
+
},
|
|
2353
|
+
move(row, to = {}) {
|
|
2354
|
+
const cells = to?.values ? cellsOf2(to.values) : [];
|
|
2355
|
+
const target = to?.before ?? to?.after ?? null;
|
|
2356
|
+
if (!live2(row) || target && !live2(target)) return false;
|
|
2357
|
+
return ask2({ op: "move", row: row.el, before: to?.before?.el ?? null, after: to?.before ? null : to?.after?.el ?? null, cells });
|
|
2358
|
+
},
|
|
2359
|
+
remove: (row) => live2(row) && ask2({ op: "remove", row: row.el }),
|
|
2360
|
+
subscribe(listener) {
|
|
2361
|
+
if (typeof listener !== "function") throw new Error(`${def.id}: context.table().subscribe takes a function`);
|
|
2362
|
+
if (instances.get(host) !== instance || instance.controller.signal.aborted) return () => {
|
|
2363
|
+
};
|
|
2364
|
+
const { listeners } = following(def, host, instance);
|
|
2365
|
+
listeners.add(listener);
|
|
2366
|
+
return () => void listeners.delete(listener);
|
|
2367
|
+
}
|
|
2368
|
+
});
|
|
2369
|
+
}
|
|
833
2370
|
function takeRuntime(description, root) {
|
|
834
2371
|
const { generated = [], attrs = {} } = description?.runtime ?? {};
|
|
835
|
-
|
|
836
|
-
for (const
|
|
2372
|
+
const own = (selector) => hostsIn(root, selector).filter((node) => node === root || heldBy(node) === root);
|
|
2373
|
+
for (const selector of generated) own(selector).forEach((node) => node.remove());
|
|
2374
|
+
for (const [selector, names] of Object.entries(attrs)) own(selector).forEach((node) => names.forEach((name) => node.removeAttribute(name)));
|
|
837
2375
|
}
|
|
838
2376
|
function clear(def, host) {
|
|
839
2377
|
try {
|
|
@@ -857,6 +2395,7 @@
|
|
|
857
2395
|
if (instance.failed) return;
|
|
858
2396
|
instance.failed = true;
|
|
859
2397
|
queued.delete(host);
|
|
2398
|
+
toHear.delete(host);
|
|
860
2399
|
resize.unobserve(host);
|
|
861
2400
|
instance.controller.abort();
|
|
862
2401
|
const { handle } = instance;
|
|
@@ -882,16 +2421,17 @@
|
|
|
882
2421
|
host,
|
|
883
2422
|
signal: controller.signal,
|
|
884
2423
|
frame: (run) => schedule(host, run),
|
|
885
|
-
fail: (error) => report(def, host, error)
|
|
886
|
-
...packaged ? packageContext(def, host) : {}
|
|
2424
|
+
fail: (error) => report(def, host, error)
|
|
887
2425
|
};
|
|
2426
|
+
if (packaged) Object.defineProperties(context2, Object.getOwnPropertyDescriptors(packageContext(def, host, instance)));
|
|
888
2427
|
instance.context = context2;
|
|
889
2428
|
let failure = null;
|
|
890
2429
|
let made2 = null;
|
|
891
2430
|
try {
|
|
892
|
-
made2 = make(context2);
|
|
2431
|
+
made2 = make(context2, (run) => guarded(instance, host, run, "mounted"));
|
|
893
2432
|
} catch (error) {
|
|
894
2433
|
failure = error;
|
|
2434
|
+
if (error?.made && typeof error.made.then !== "function") instance.handle = error.made;
|
|
895
2435
|
}
|
|
896
2436
|
if (packaged && (failure || instance.failed)) {
|
|
897
2437
|
const failedAsItRan = instance.failed;
|
|
@@ -909,6 +2449,9 @@
|
|
|
909
2449
|
}
|
|
910
2450
|
counters.mounted += 1;
|
|
911
2451
|
if (def.on?.includes("resize")) resize.observe(host);
|
|
2452
|
+
if (def.on?.includes("source")) watchSource();
|
|
2453
|
+
if (def.on?.includes("clock")) armClock();
|
|
2454
|
+
if (packaged && def.on?.includes("data") && readsTables(def)) following(def, host, instance);
|
|
912
2455
|
return instance.handle;
|
|
913
2456
|
}
|
|
914
2457
|
function whenMade(promise, instance, host, context2) {
|
|
@@ -925,16 +2468,18 @@
|
|
|
925
2468
|
}
|
|
926
2469
|
function mount(def, host) {
|
|
927
2470
|
if (instances.has(host)) return instances.get(host).handle;
|
|
928
|
-
return keep(def, host, (context2) => {
|
|
2471
|
+
return keep(def, host, (context2, guard) => {
|
|
929
2472
|
if (ofPackage(def)) clear(def, host);
|
|
930
|
-
return def.mount(host, context2);
|
|
2473
|
+
return guard(() => def.mount(host, context2));
|
|
931
2474
|
});
|
|
932
2475
|
}
|
|
933
2476
|
function destroy(host) {
|
|
934
2477
|
const instance = instances.get(host);
|
|
935
2478
|
if (!instance) return;
|
|
2479
|
+
net.forget(host);
|
|
936
2480
|
instances.delete(host);
|
|
937
2481
|
queued.delete(host);
|
|
2482
|
+
toHear.delete(host);
|
|
938
2483
|
counters.destroyed += 1;
|
|
939
2484
|
resize.unobserve(host);
|
|
940
2485
|
instance.controller.abort();
|
|
@@ -945,12 +2490,16 @@
|
|
|
945
2490
|
report(instance.def, host, error);
|
|
946
2491
|
}
|
|
947
2492
|
}
|
|
2493
|
+
function restart(host) {
|
|
2494
|
+
const instance = instances.get(host);
|
|
2495
|
+
if (!instance) return;
|
|
2496
|
+
destroy(host);
|
|
2497
|
+
if (host.isConnected) mount(instance.def, host);
|
|
2498
|
+
}
|
|
2499
|
+
const net = createNet({ restart, instances: () => [...instances].map(([host, { def }]) => [host, def]), describe: (id) => descriptions.get(id) });
|
|
948
2500
|
const hostsIn = (root, selector) => [...root.matches?.(selector) ? [root] : [], ...root.querySelectorAll?.(selector) ?? []];
|
|
949
2501
|
const outsidePage = (node) => Boolean(node.closest?.("[data-doc-dev]"));
|
|
950
|
-
const inOther = (def, host) =>
|
|
951
|
-
for (let around = host.closest(INSTANCE); around; around = around.parentElement?.closest(INSTANCE)) if (around.getAttribute(ATTRIBUTE) !== def.id) return true;
|
|
952
|
-
return false;
|
|
953
|
-
};
|
|
2502
|
+
const inOther = (def, host) => host.matches(INSTANCE) && host.getAttribute(ATTRIBUTE) !== def.id || (heldBy(host)?.getAttribute(ATTRIBUTE) ?? def.id) !== def.id;
|
|
954
2503
|
function scan(root, only, { later = false } = {}) {
|
|
955
2504
|
for (const def of only ? [only] : defs.values()) {
|
|
956
2505
|
if (!def.started || later && def.added === false) continue;
|
|
@@ -976,18 +2525,18 @@
|
|
|
976
2525
|
function showAsItStands(host) {
|
|
977
2526
|
host.setAttribute(FALLBACK, "");
|
|
978
2527
|
for (const control of host.querySelectorAll(CONTROLS2)) {
|
|
979
|
-
if (control.hasAttribute("inert")) continue;
|
|
2528
|
+
if (control.hasAttribute("inert") || heldBy(control) !== host) continue;
|
|
980
2529
|
control.setAttribute("inert", "");
|
|
981
2530
|
control.setAttribute(CONTROL_MARK, "");
|
|
982
2531
|
}
|
|
983
2532
|
showData(host);
|
|
984
2533
|
}
|
|
985
2534
|
const drawnFrom = /* @__PURE__ */ new WeakMap();
|
|
986
|
-
const dataShownIn = (host) => [...host.querySelectorAll(`.${DATA_SHOWN}`)].filter((node) => node
|
|
2535
|
+
const dataShownIn = (host) => [...host.querySelectorAll(`.${DATA_SHOWN}`)].filter((node) => ownedBy(node, host));
|
|
987
2536
|
function showData(host) {
|
|
988
2537
|
const kept = /* @__PURE__ */ new Set();
|
|
989
2538
|
for (const script of host.querySelectorAll("script")) {
|
|
990
|
-
if (script
|
|
2539
|
+
if (!ownedBy(script, host) || !isDataScript(script.localName, [...script.attributes])) continue;
|
|
991
2540
|
const next = script.nextElementSibling;
|
|
992
2541
|
if (next && drawnFrom.get(next) === script.textContent) {
|
|
993
2542
|
kept.add(next);
|
|
@@ -1006,7 +2555,7 @@
|
|
|
1006
2555
|
for (const host of hostsIn(root, INSTANCE)) {
|
|
1007
2556
|
const id = host.getAttribute(ATTRIBUTE);
|
|
1008
2557
|
const told = descriptions.get(id);
|
|
1009
|
-
if (outsidePage(host) || host
|
|
2558
|
+
if (outsidePage(host) || heldBy(host) || defs.has(id) || [...document.querySelectorAll(`script[${ARRIVING}]`)].some((script) => script.getAttribute(ARRIVING) === id)) continue;
|
|
1010
2559
|
if (told?.match && !(told.script && loaded2)) {
|
|
1011
2560
|
if (host.hasAttribute(FALLBACK)) takeFallback(host);
|
|
1012
2561
|
continue;
|
|
@@ -1027,7 +2576,19 @@
|
|
|
1027
2576
|
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", () => fallback(document), { once: true });
|
|
1028
2577
|
else fallback(document);
|
|
1029
2578
|
if (document.readyState !== "complete") global2.addEventListener("load", () => fallback(document), { once: true });
|
|
1030
|
-
const sourceParts = (host, id) => Object.values(descriptions.get(id)?.parts ?? {}).filter(({ edit }) => edit === "text" || edit === "data").flatMap(({ at }) => partsIn(host, at));
|
|
2579
|
+
const sourceParts = (host, id) => Object.values(descriptions.get(id)?.parts ?? {}).filter(({ edit }) => edit === "text" || edit === "data" || edit === "flow").flatMap(({ at, edit }) => partsIn(host, at, edit));
|
|
2580
|
+
const ownedHere = (target) => {
|
|
2581
|
+
const host = target.closest(owned);
|
|
2582
|
+
if (!host) return false;
|
|
2583
|
+
if (!host.matches(INSTANCE)) return true;
|
|
2584
|
+
return target === host || componentAt(target) && heldBy(target) === host;
|
|
2585
|
+
};
|
|
2586
|
+
function ofTheFile(host, target, record) {
|
|
2587
|
+
const region = record.type === "attributes" ? heldBy(target) : heldWithin(target);
|
|
2588
|
+
if (region === null || region === host) return true;
|
|
2589
|
+
return sourceParts(region, region.getAttribute(ATTRIBUTE)).some((part) => part.contains(target));
|
|
2590
|
+
}
|
|
2591
|
+
const ofSource = (record) => record.attributeName === "class" ? lookChanged(record.oldValue, record.target.getAttribute("class")) : SOURCE_ATTRIBUTES.includes(record.attributeName);
|
|
1031
2592
|
function changes(records, options) {
|
|
1032
2593
|
if (!global2.document?.defaultView) return;
|
|
1033
2594
|
const changed = [];
|
|
@@ -1035,19 +2596,24 @@
|
|
|
1035
2596
|
const sourced = options?.quiet ? [] : listening("source");
|
|
1036
2597
|
const written = [];
|
|
1037
2598
|
let removed = false;
|
|
1038
|
-
|
|
2599
|
+
let later = null;
|
|
1039
2600
|
for (const record of records) {
|
|
2601
|
+
const attribute = record.type === "attributes" ? record.attributeName : null;
|
|
2602
|
+
const reveals = attribute !== null && REVEALS.includes(attribute);
|
|
2603
|
+
if (attribute !== null && !reveals && (sourced.length === 0 || !ofSource(record))) continue;
|
|
1040
2604
|
const target = record.target.nodeType === 1 ? record.target : record.target.parentElement;
|
|
1041
2605
|
if (!target || outsidePage(target)) continue;
|
|
1042
|
-
if (sourced.length > 0 &&
|
|
1043
|
-
if (owned && target
|
|
1044
|
-
if (
|
|
1045
|
-
revealed.add(target);
|
|
2606
|
+
if (sourced.length > 0 && !reveals) written.push([target, record]);
|
|
2607
|
+
if (owned && ownedHere(target)) continue;
|
|
2608
|
+
if (attribute !== null) {
|
|
2609
|
+
if (reveals) revealed.add(target);
|
|
1046
2610
|
continue;
|
|
1047
2611
|
}
|
|
1048
2612
|
if (record.removedNodes.length > 0) removed = true;
|
|
1049
2613
|
for (const node of record.addedNodes) {
|
|
1050
|
-
if (node.nodeType !== 1 || !node.isConnected || outsidePage(node)
|
|
2614
|
+
if (node.nodeType !== 1 || !node.isConnected || outsidePage(node)) continue;
|
|
2615
|
+
later ??= [...defs.values()].filter((def) => def.started && def.added !== false).map(selectorOf).concat(INSTANCE).join(", ");
|
|
2616
|
+
if (!(node.matches(later) || node.querySelector(later))) continue;
|
|
1051
2617
|
scan(node, null, { later: true });
|
|
1052
2618
|
fallback(node);
|
|
1053
2619
|
}
|
|
@@ -1063,9 +2629,10 @@
|
|
|
1063
2629
|
for (const host of hosts) if (heard.get(host).length > 0) tell(host, "content", heard.get(host), options);
|
|
1064
2630
|
}
|
|
1065
2631
|
for (const [host, { def }] of sourced) {
|
|
2632
|
+
if (!instances.has(host) || written.length === 0) continue;
|
|
1066
2633
|
const parts = sourceParts(host, def.id);
|
|
1067
|
-
const heard = written.filter(([target]) => parts.some((part) => part.contains(target))).map(([, record]) => record);
|
|
1068
|
-
if (heard.length > 0)
|
|
2634
|
+
const heard = written.filter(([target, record]) => parts.some((part) => part.contains(target)) && ofTheFile(host, target, record)).map(([, record]) => record);
|
|
2635
|
+
if (heard.length > 0) hearLater(host, heard);
|
|
1069
2636
|
}
|
|
1070
2637
|
for (const [host] of listening("reveal")) {
|
|
1071
2638
|
for (const target of revealed) if (target.contains(host)) {
|
|
@@ -1074,8 +2641,16 @@
|
|
|
1074
2641
|
}
|
|
1075
2642
|
}
|
|
1076
2643
|
}
|
|
2644
|
+
const REVEALS = ["hidden", "open"];
|
|
2645
|
+
const WATCHED2 = { childList: true, subtree: true, characterData: true, attributes: true, attributeFilter: REVEALS };
|
|
1077
2646
|
const observer = new MutationObserver((records) => changes(records));
|
|
1078
|
-
observer.observe(document.documentElement,
|
|
2647
|
+
observer.observe(document.documentElement, WATCHED2);
|
|
2648
|
+
let watchingSource = false;
|
|
2649
|
+
function watchSource() {
|
|
2650
|
+
if (watchingSource) return;
|
|
2651
|
+
watchingSource = true;
|
|
2652
|
+
observer.observe(document.documentElement, { ...WATCHED2, attributeOldValue: true, attributeFilter: [...REVEALS, ...SOURCE_ATTRIBUTES, "class"] });
|
|
2653
|
+
}
|
|
1079
2654
|
function quietly(change) {
|
|
1080
2655
|
changes(observer.takeRecords());
|
|
1081
2656
|
try {
|
|
@@ -1096,10 +2671,11 @@
|
|
|
1096
2671
|
}
|
|
1097
2672
|
}
|
|
1098
2673
|
}
|
|
1099
|
-
for (const description of descriptions
|
|
2674
|
+
for (const [id, description] of descriptions) {
|
|
1100
2675
|
const marks = description.runtime ?? {};
|
|
1101
|
-
|
|
1102
|
-
for (const
|
|
2676
|
+
const of = (selector) => PACKAGE_ID.test(id) ? all(selector).filter((node) => (node.matches(INSTANCE) ? node : heldBy(node))?.getAttribute(ATTRIBUTE) === id) : all(selector);
|
|
2677
|
+
for (const selector of marks.generated ?? []) of(selector).forEach((node) => node.remove());
|
|
2678
|
+
for (const [selector, names] of Object.entries(marks.attrs ?? {})) of(selector).forEach((node) => names.forEach((name) => node.removeAttribute(name)));
|
|
1103
2679
|
for (const [selector, names] of Object.entries(marks.classes ?? {})) {
|
|
1104
2680
|
all(selector).forEach((node) => {
|
|
1105
2681
|
node.classList.remove(...names);
|
|
@@ -1126,7 +2702,9 @@
|
|
|
1126
2702
|
},
|
|
1127
2703
|
quietly,
|
|
1128
2704
|
dehydrate,
|
|
1129
|
-
/** The
|
|
2705
|
+
/** The tables of the page a key names, for the kit's charts drawn from a table and its views (table-reading.js createKeyedTables): the kit's own, no document's. */
|
|
2706
|
+
tables,
|
|
2707
|
+
/** The component on `host` makes its `example` of an edit, as gallery block check asks it. Whether it has one. */
|
|
1130
2708
|
example(host) {
|
|
1131
2709
|
const instance = instances.get(host);
|
|
1132
2710
|
if (!instance?.def.example) return false;
|
|
@@ -1204,7 +2782,7 @@
|
|
|
1204
2782
|
}
|
|
1205
2783
|
|
|
1206
2784
|
// src/render/kit/runtime/reveal.js
|
|
1207
|
-
var
|
|
2785
|
+
var CARD2 = "dialog.doc-dialog";
|
|
1208
2786
|
var shown = (panel) => {
|
|
1209
2787
|
const area = panel.parentElement;
|
|
1210
2788
|
const key = panel.getAttribute("data-doc-sheet");
|
|
@@ -1212,7 +2790,7 @@
|
|
|
1212
2790
|
if (panel.hidden) [...area.querySelectorAll("[data-sheet-tab]")].find((tab) => tab.getAttribute("data-sheet-tab") === key)?.click();
|
|
1213
2791
|
};
|
|
1214
2792
|
function reveal(target) {
|
|
1215
|
-
for (const card of [...document.querySelectorAll(`${
|
|
2793
|
+
for (const card of [...document.querySelectorAll(`${CARD2}[open]`)].reverse()) {
|
|
1216
2794
|
if (card.contains(target)) continue;
|
|
1217
2795
|
if (globalThis.DocDialogs) globalThis.DocDialogs.close(card, "outside");
|
|
1218
2796
|
else card.close();
|
|
@@ -1221,7 +2799,7 @@
|
|
|
1221
2799
|
for (let node = target; node; node = node.parentElement) around.unshift(node);
|
|
1222
2800
|
for (const node of around) {
|
|
1223
2801
|
if (node.hasAttribute("data-doc-sheet") && node.hidden && node.parentElement?.matches("[data-doc-sheets]")) shown(node);
|
|
1224
|
-
else if (node.matches(`${
|
|
2802
|
+
else if (node.matches(`${CARD2}:not([open])`)) {
|
|
1225
2803
|
if (globalThis.DocDialogs) globalThis.DocDialogs.open(node);
|
|
1226
2804
|
else node.showModal();
|
|
1227
2805
|
} else if (node !== target && node.localName === "details" && !node.open) node.open = true;
|
|
@@ -1247,18 +2825,18 @@
|
|
|
1247
2825
|
reveal(target);
|
|
1248
2826
|
target.scrollIntoView({ block: "center" });
|
|
1249
2827
|
};
|
|
1250
|
-
let order = [...doc.querySelectorAll(`${
|
|
2828
|
+
let order = [...doc.querySelectorAll(`${CARD2}[open]`)];
|
|
1251
2829
|
new win.MutationObserver((records) => {
|
|
1252
2830
|
for (const { target } of records) {
|
|
1253
|
-
if (!target.matches?.(
|
|
2831
|
+
if (!target.matches?.(CARD2)) continue;
|
|
1254
2832
|
order = order.filter((card) => card !== target);
|
|
1255
2833
|
if (target.open) order.push(target);
|
|
1256
2834
|
}
|
|
1257
2835
|
}).observe(root, { subtree: true, attributes: true, attributeFilter: ["open"] });
|
|
1258
2836
|
const contentOf2 = (card) => card.querySelector(".doc-dialog-content");
|
|
1259
2837
|
const cards = () => {
|
|
1260
|
-
const
|
|
1261
|
-
return [...order.filter((card) => card.open), ...
|
|
2838
|
+
const open2 = [...doc.querySelectorAll(`${CARD2}[open]`)];
|
|
2839
|
+
return [...order.filter((card) => card.open), ...open2.filter((card) => !order.includes(card))].filter((card) => card.id).map((card) => ({ id: card.id, top: contentOf2(card)?.scrollTop ?? 0 }));
|
|
1262
2840
|
};
|
|
1263
2841
|
let putting = 0;
|
|
1264
2842
|
let seen = win.location.hash;
|
|
@@ -1291,7 +2869,7 @@
|
|
|
1291
2869
|
});
|
|
1292
2870
|
for (const { id } of kept) {
|
|
1293
2871
|
const card = doc.getElementById(id);
|
|
1294
|
-
if (!card?.matches(`${
|
|
2872
|
+
if (!card?.matches(`${CARD2}:not([open])`)) continue;
|
|
1295
2873
|
if (globalThis.DocDialogs) globalThis.DocDialogs.open(card);
|
|
1296
2874
|
else card.showModal();
|
|
1297
2875
|
}
|
|
@@ -1346,69 +2924,14 @@
|
|
|
1346
2924
|
observer.observe(root, { attributes: true, attributeFilter: ["data-doc-drawn"] });
|
|
1347
2925
|
}
|
|
1348
2926
|
|
|
1349
|
-
// src/shared/inline-spacing.mjs
|
|
1350
|
-
var UNITS = /* @__PURE__ */ new Set([..."\u4E2A\u4E07\u4EBF\u5343\u767E\u5341\u5143\u89D2\u5206\u5398\u6BDB\u500D\u5E74\u6708\u65E5\u53F7\u65F6\u70B9\u79D2\u5929\u5468\u5C81\u4EBA\u4F4D\u540D\u6B21\u5BB6\u6761\u9879\u79CD\u53F0\u53EA\u4EF6\u7BC7\u9875\u5F20\u5957\u4EFD\u7EC4\u6279\u671F\u5C4A\u4EE3\u7EA7\u5C42\u8F6E\u6B65\u7C73\u514B\u65A4\u5428\u5EA6\u91CC\u516C\u6BEB\u5FAE\u5BF8\u5C3A\u4E24\u5347\u6237\u6240\u5EA7\u680B\u8F86\u67B6\u8258\u672C\u90E8\u7AE0\u8282\u573A\u5C40\u9996\u53E5\u5B57\u884C\u5217\u904D\u56DE\u756A\u6210"]);
|
|
1351
|
-
var ZWSP = String.fromCharCode(8203);
|
|
1352
|
-
var WORD = /[\p{L}\p{N}]/u;
|
|
1353
|
-
var ITEM = "code, .doc-math-inline, .katex";
|
|
1354
|
-
var LINE = /^(P|LI|H[1-6]|TD|TH|DT|DD|DIV|SECTION|ARTICLE|ASIDE|HEADER|FOOTER|MAIN|NAV|FIGURE|FIGCAPTION|CAPTION|SUMMARY|DETAILS|BLOCKQUOTE|UL|OL|TABLE|THEAD|TBODY|TR|PRE|BR|HR|DIALOG|BODY|BUTTON|svg)$/;
|
|
1355
|
-
var emptyFormula = (element) => element.matches(".doc-math-inline") && (element.getAttribute("data-ge-empty") === "formula" || !element.textContent.replace(/\\[()]/g, "").trim());
|
|
1356
|
-
var isInlineItem = (node) => node?.nodeType === 1 && node.matches(ITEM) && !emptyFormula(node);
|
|
1357
|
-
function inlineItems(root) {
|
|
1358
|
-
const items = root.nodeType === 1 && root.matches(ITEM) ? [root, ...root.querySelectorAll(ITEM)] : [...root.querySelectorAll(ITEM)];
|
|
1359
|
-
return items.filter((item2) => isInlineItem(item2) && !item2.parentElement?.closest(".doc-math-inline, .katex, .katex-display, code"));
|
|
1360
|
-
}
|
|
1361
|
-
function endOf(node, after) {
|
|
1362
|
-
if (node.nodeType === 3) {
|
|
1363
|
-
const characters = [...node.data.replaceAll(ZWSP, "")];
|
|
1364
|
-
return characters.length === 0 ? void 0 : after ? characters[0] : characters.at(-1);
|
|
1365
|
-
}
|
|
1366
|
-
if (node.nodeType !== 1) return void 0;
|
|
1367
|
-
if (LINE.test(node.tagName)) return null;
|
|
1368
|
-
if (node.matches(ITEM)) return emptyFormula(node) ? void 0 : true;
|
|
1369
|
-
if (node.hasAttribute("data-ge-empty")) return void 0;
|
|
1370
|
-
const children = [...node.childNodes];
|
|
1371
|
-
for (const child of after ? children : children.reverse()) {
|
|
1372
|
-
const found = endOf(child, after);
|
|
1373
|
-
if (found !== void 0) return found;
|
|
1374
|
-
}
|
|
1375
|
-
return void 0;
|
|
1376
|
-
}
|
|
1377
|
-
function sideOf(node, after) {
|
|
1378
|
-
for (let at = node; at; ) {
|
|
1379
|
-
const next = after ? at.nextSibling : at.previousSibling;
|
|
1380
|
-
if (!next) {
|
|
1381
|
-
at = at.parentElement;
|
|
1382
|
-
if (!at || LINE.test(at.tagName) || at.hasAttribute("contenteditable")) return null;
|
|
1383
|
-
continue;
|
|
1384
|
-
}
|
|
1385
|
-
const found = endOf(next, after);
|
|
1386
|
-
if (found !== void 0) return found;
|
|
1387
|
-
at = next;
|
|
1388
|
-
}
|
|
1389
|
-
return null;
|
|
1390
|
-
}
|
|
1391
|
-
function spaceAround(element) {
|
|
1392
|
-
const put = { before: null, after: null };
|
|
1393
|
-
for (const after of [false, true]) {
|
|
1394
|
-
const side = sideOf(element, after);
|
|
1395
|
-
if (side !== true && !(typeof side === "string" && WORD.test(side))) continue;
|
|
1396
|
-
const space = element.ownerDocument.createTextNode(" ");
|
|
1397
|
-
if (after) element.after(space);
|
|
1398
|
-
else element.before(space);
|
|
1399
|
-
put[after ? "after" : "before"] = space;
|
|
1400
|
-
}
|
|
1401
|
-
return put;
|
|
1402
|
-
}
|
|
1403
|
-
|
|
1404
2927
|
// src/render/kit/runtime/spacing.js
|
|
1405
|
-
var inert = (element) => element.closest(
|
|
2928
|
+
var inert = (element) => element.closest("pre, svg, [contenteditable], [data-doc-dev], script, style, textarea") || element.matches(INSTANCE) || componentAt(element);
|
|
1406
2929
|
var NUMBER = String.raw`\d(?:[\d.,]*\d)?(?:%|[A-Za-z]{1,3})?`;
|
|
1407
2930
|
var DASH = "[\u2013\u2014~\uFF5E]";
|
|
1408
2931
|
var CLOSING = new RegExp(String.raw`^(?:${DASH}${NUMBER})?[,。、;:!?)」』》】〉〕”’,.;:!?)\]]*`);
|
|
1409
|
-
var
|
|
1410
|
-
var OWN_TEXT = "code, kbd, samp, .katex, .doc-range, option";
|
|
1411
|
-
var
|
|
2932
|
+
var RANGE2 = new RegExp(`${NUMBER} ?${DASH} ?${NUMBER}`);
|
|
2933
|
+
var OWN_TEXT = "code, kbd, samp, .katex, .doc-range, .doc-long-run, option";
|
|
2934
|
+
var TEX2 = /\\[()[\]]|\$\$/;
|
|
1412
2935
|
var WRAPPER = /^(STRONG|B|EM|I|U|S|MARK|SPAN|A|SUB|SUP|SMALL)$/;
|
|
1413
2936
|
function tieClosing(formula) {
|
|
1414
2937
|
let at = formula;
|
|
@@ -1446,7 +2969,7 @@
|
|
|
1446
2969
|
function holdRanges(text) {
|
|
1447
2970
|
const held = [];
|
|
1448
2971
|
for (let rest = text; rest; ) {
|
|
1449
|
-
const found =
|
|
2972
|
+
const found = RANGE2.exec(rest.data);
|
|
1450
2973
|
if (!found) break;
|
|
1451
2974
|
const range = found.index > 0 ? rest.splitText(found.index) : rest;
|
|
1452
2975
|
rest = range.data.length > found[0].length ? range.splitText(found[0].length) : null;
|
|
@@ -1458,13 +2981,36 @@
|
|
|
1458
2981
|
}
|
|
1459
2982
|
return held;
|
|
1460
2983
|
}
|
|
1461
|
-
function
|
|
2984
|
+
function holdRuns(text) {
|
|
2985
|
+
const held = [];
|
|
2986
|
+
for (const { index, length } of longRuns(text.data).reverse()) {
|
|
2987
|
+
if (index + length < text.data.length) text.splitText(index + length);
|
|
2988
|
+
held.unshift(breaking(index > 0 ? text.splitText(index) : text));
|
|
2989
|
+
}
|
|
2990
|
+
return held;
|
|
2991
|
+
}
|
|
2992
|
+
function breaking(node) {
|
|
2993
|
+
const span = node.ownerDocument.createElement("span");
|
|
2994
|
+
span.className = "doc-long-run";
|
|
2995
|
+
node.before(span);
|
|
2996
|
+
span.append(node);
|
|
2997
|
+
return span;
|
|
2998
|
+
}
|
|
2999
|
+
function textsIn(root) {
|
|
1462
3000
|
const texts = [];
|
|
1463
3001
|
const walker = root.ownerDocument.createTreeWalker(root, 4);
|
|
1464
3002
|
for (let node = walker.nextNode(); node; node = walker.nextNode()) texts.push(node);
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
3003
|
+
return texts;
|
|
3004
|
+
}
|
|
3005
|
+
function looked(text) {
|
|
3006
|
+
const parent = text.parentElement;
|
|
3007
|
+
return Boolean(parent?.closest("main")) && !TEX2.test(text.data) && !inert(parent) && !parent.closest(OWN_TEXT) && !(text.data.includes("$") && parent.closest("[data-doc-math-dollar]"));
|
|
3008
|
+
}
|
|
3009
|
+
function holdIn(root) {
|
|
3010
|
+
for (const text of textsIn(root)) if (RANGE2.test(text.data) && looked(text)) holdRanges(text);
|
|
3011
|
+
for (const text of textsIn(root)) if (holdsLongRun(text.data) && looked(text)) holdRuns(text);
|
|
3012
|
+
for (const code of [...root.matches("code") ? [root] : [], ...root.querySelectorAll("code")]) {
|
|
3013
|
+
if (code.closest("main") && !inert(code) && !code.parentElement?.closest(`${OWN_TEXT}, td, th`) && holdsLongRun(code.textContent)) breaking(code);
|
|
1468
3014
|
}
|
|
1469
3015
|
}
|
|
1470
3016
|
function keepLines(root, flows) {
|
|
@@ -1506,8 +3052,7 @@
|
|
|
1506
3052
|
".doc-bookmark",
|
|
1507
3053
|
".doc-file",
|
|
1508
3054
|
".doc-zoom",
|
|
1509
|
-
"[data-doc-dev]"
|
|
1510
|
-
INSTANCE
|
|
3055
|
+
"[data-doc-dev]"
|
|
1511
3056
|
].join(", ");
|
|
1512
3057
|
var ZOOM_PICTURES = ".doc-page img";
|
|
1513
3058
|
var ZOOM_MARK = "data-doc-zoom";
|
|
@@ -1515,7 +3060,7 @@
|
|
|
1515
3060
|
var loaded = (img) => img.complete && (img.naturalWidth > 0 || /^data:image\/svg|\.svg(?:[?#]|$)/i.test(img.currentSrc || img.src));
|
|
1516
3061
|
function zoomable(img) {
|
|
1517
3062
|
const holder = img?.hasAttribute?.(ZOOM_MARK) ? img.parentElement : img;
|
|
1518
|
-
if (img?.localName !== "img" || !img.closest(".doc-page") || holder?.closest(ZOOM_SKIP) || !loaded(img)) return false;
|
|
3063
|
+
if (img?.localName !== "img" || !img.closest(".doc-page") || holder?.closest(ZOOM_SKIP) || holder.matches(INSTANCE) || componentAt(holder) || !loaded(img)) return false;
|
|
1519
3064
|
const box = img.getBoundingClientRect();
|
|
1520
3065
|
return box.width >= ZOOM_LEAST || box.height >= ZOOM_LEAST;
|
|
1521
3066
|
}
|
|
@@ -1690,18 +3235,23 @@
|
|
|
1690
3235
|
|
|
1691
3236
|
// src/render/kit/runtime/index.js
|
|
1692
3237
|
if (!globalThis.DocKit) {
|
|
3238
|
+
const platform = globalThis.navigator?.userAgentData?.platform || globalThis.navigator?.platform || "";
|
|
3239
|
+
if (/mac|iphone|ipad/i.test(platform)) document.documentElement.setAttribute("data-doc-platform", "mac");
|
|
3240
|
+
else document.documentElement.removeAttribute("data-doc-platform");
|
|
1693
3241
|
const kit = createKit({ descriptions: new Map(define_COMPONENT_RUNTIME_default.map((component) => [component.id, component])) });
|
|
1694
3242
|
const { store, bindControl, bindShow, CONTROLS: CONTROLS3 } = createBindings();
|
|
1695
3243
|
kit.component({ id: "bind", selector: CONTROLS3, mount: (element, context2) => bindControl(element, context2) });
|
|
1696
3244
|
kit.component({ id: "show", selector: "[data-doc-show]", mount: (element) => bindShow(element) });
|
|
1697
3245
|
kit.component({ id: "embed", mount: (figure) => showEmbed(figure), dehydrate: (figure) => dehydrateEmbed(figure) });
|
|
1698
|
-
kit.component({ id: "flowchart", selector: FLOWCHART, on: ["resize", "fonts", "content"], mount: (list2, context2) => startFlowchart(list2, context2), dehydrate: (list2) => dehydrateFlowchart(list2) });
|
|
1699
|
-
globalThis.DocKit = Object.freeze({ ...kit, bindings: store, flows: define_COMPONENT_FLOWS_default, reveal });
|
|
3246
|
+
kit.component({ id: "flowchart", selector: FLOWCHART, on: ["resize", "fonts", "content", "layout"], mount: (list2, context2) => startFlowchart(list2, context2), dehydrate: (list2) => dehydrateFlowchart(list2) });
|
|
3247
|
+
globalThis.DocKit = Object.freeze({ ...kit, bindings: store, flows: define_COMPONENT_FLOWS_default, reveal, input: fieldIn, drag: dragIn, choose });
|
|
1700
3248
|
globalThis.ReportKit = globalThis.DocKit;
|
|
1701
3249
|
globalThis.DocKit.component({ id: "range", selector: ".doc-range", added: false, mount: () => null, dehydrate: untie });
|
|
1702
|
-
|
|
3250
|
+
globalThis.DocKit.component({ id: "long-run", selector: ".doc-long-run", added: false, mount: () => null, dehydrate: untie });
|
|
3251
|
+
startSpacing(document, ".doc-page, .doc-section, .doc-summary, .doc-panel, .doc-callout, .doc-details-content, .doc-dialog-content, [data-doc-sheet], .doc-column, [data-doc-slot], :is(.doc-section, .doc-summary, .doc-panel, .doc-callout, .doc-details-content, .doc-dialog-content, .doc-column, [data-doc-slot]) > div:not([class])");
|
|
1703
3252
|
startZoom(document);
|
|
1704
3253
|
globalThis.DocKit.component({ id: "zoom", selector: ZOOM_PICTURES, on: ["resize", "reveal"], mount: (img, context2) => watchZoom(img, context2) });
|
|
1705
3254
|
startBlockLinks(document);
|
|
3255
|
+
startChoices(document);
|
|
1706
3256
|
}
|
|
1707
3257
|
})();
|