@heycys/gallery 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD-PARTY-NOTICES.md +51 -1
- package/browser/editor/components/callout/index.mjs +40 -15
- package/browser/editor/components/columns/page.mjs +45 -32
- package/browser/editor/components/details/index.mjs +2 -1
- package/browser/editor/components/dialog/index.mjs +2 -1
- package/browser/editor/components/dialog/page.mjs +0 -18
- package/browser/editor/components/divider/index.mjs +1 -1
- package/browser/editor/components/embed/index.mjs +2 -2
- package/browser/editor/components/figure/page.mjs +10 -1
- package/browser/editor/components/file/page.mjs +2 -2
- package/browser/editor/components/flowchart/add.mjs +7 -6
- package/browser/editor/components/flowchart/page.mjs +1 -1
- package/browser/editor/components/heading/index.mjs +2 -0
- package/browser/editor/components/heading/page.mjs +6 -0
- package/browser/editor/components/highlight/index.mjs +4 -20
- package/browser/editor/components/icons.mjs +13 -2
- package/browser/editor/components/image/crop.mjs +6 -9
- package/browser/editor/components/image/page.mjs +2 -2
- package/browser/editor/components/installed/index.mjs +82 -29
- package/browser/editor/components/installed/page.mjs +146 -34
- package/browser/editor/components/installed/served.mjs +6 -5
- package/browser/editor/components/instances.mjs +18 -0
- package/browser/editor/components/kit.mjs +3 -0
- package/browser/editor/components/list/page.mjs +3 -6
- package/browser/editor/components/media/page.mjs +44 -14
- package/browser/editor/components/pages.mjs +2 -2
- package/browser/editor/components/registry.mjs +68 -33
- package/browser/editor/components/section/index.mjs +2 -1
- package/browser/editor/components/set-apart.mjs +24 -0
- package/browser/editor/components/table/index.mjs +64 -5
- package/browser/editor/components/table/page.mjs +30 -19
- package/browser/editor/page/annotate/anchors.mjs +4 -3
- package/browser/editor/page/annotate/card.mjs +3 -6
- package/browser/editor/page/annotate/index.mjs +61 -34
- package/browser/editor/page/autosave.mjs +357 -38
- package/browser/editor/page/beside.mjs +5 -5
- package/browser/editor/page/block-menu/colors.mjs +3 -1
- package/browser/editor/page/block-menu/index.mjs +8 -6
- package/browser/editor/page/blocks.mjs +16 -7
- package/browser/editor/page/board/client.mjs +57 -0
- package/browser/editor/page/board/hint.mjs +145 -0
- package/browser/editor/page/board/history.mjs +119 -0
- package/browser/editor/page/board/index.mjs +970 -0
- package/browser/editor/page/board/settings.mjs +209 -0
- package/browser/editor/page/caret.mjs +5 -2
- package/browser/editor/page/changes/bar.mjs +94 -0
- package/browser/editor/page/changes/ghost.mjs +206 -0
- package/browser/editor/page/changes/gone-words.mjs +94 -0
- package/browser/editor/page/changes/index.mjs +447 -0
- package/browser/editor/page/changes/words.mjs +27 -0
- package/browser/editor/page/clipboard/import/colors.mjs +3 -3
- package/browser/editor/page/clipboard/import/html.mjs +29 -6
- package/browser/editor/page/clipboard/import/inline.mjs +32 -0
- package/browser/editor/page/clipboard/import/markdown.mjs +58 -13
- package/browser/editor/page/clipboard/import/read.mjs +6 -1
- package/browser/editor/page/clipboard/import/to-blocks.mjs +44 -12
- package/browser/editor/page/clipboard/import/yuque.mjs +622 -0
- package/browser/editor/page/clipboard/index.mjs +156 -26
- package/browser/editor/page/clipboard/own/blocks.mjs +25 -16
- package/browser/editor/page/clipboard/own/chart-keys.mjs +41 -28
- package/browser/editor/page/clipboard/own/describe.mjs +16 -7
- package/browser/editor/page/clipboard/own/export.mjs +6 -6
- package/browser/editor/page/clipboard/own/selection.mjs +3 -3
- package/browser/editor/page/clipboard/own/writers.mjs +0 -11
- package/browser/editor/page/columns/index.mjs +48 -46
- package/browser/editor/page/commit.mjs +98 -25
- package/browser/editor/page/conflicts.mjs +13 -33
- package/browser/editor/page/convert.mjs +8 -7
- package/browser/editor/page/core.mjs +81 -27
- package/browser/editor/page/custom-page.mjs +106 -0
- package/browser/editor/page/drag/index.mjs +40 -24
- package/browser/editor/page/drag/preview.mjs +9 -4
- package/browser/editor/page/editor.mjs +120 -28
- package/browser/editor/page/emoji-picker/emoji-tab.mjs +22 -13
- package/browser/editor/page/emoji-picker/grid.mjs +7 -5
- package/browser/editor/page/emoji-picker/icon-tab.mjs +4 -4
- package/browser/editor/page/emoji-picker/icons.mjs +0 -1
- package/browser/editor/page/emoji-picker/index.mjs +11 -9
- package/browser/editor/page/emoji-picker/styles.mjs +156 -2
- package/browser/editor/page/emoji-picker/support.mjs +6 -4
- package/browser/editor/page/emoji-picker/upload.mjs +14 -13
- package/browser/editor/page/fills.mjs +5 -3
- package/browser/editor/page/fold/index.mjs +348 -0
- package/browser/editor/page/fold/rule.mjs +125 -0
- package/browser/editor/page/folded.mjs +23 -0
- package/browser/editor/page/format-bar/bar.mjs +2 -1
- package/browser/editor/page/format-bar/index.mjs +1 -1
- package/browser/editor/page/geometry.mjs +8 -6
- package/browser/editor/page/handle/index.mjs +22 -14
- package/browser/editor/page/hints/index.mjs +1 -1
- package/browser/editor/page/history.mjs +24 -4
- package/browser/editor/page/insert/index.mjs +30 -17
- package/browser/editor/page/links/index.mjs +5 -3
- package/browser/editor/page/links/pages.mjs +27 -9
- package/browser/editor/page/long-runs.mjs +75 -0
- package/browser/editor/page/look.mjs +69 -6
- package/browser/editor/page/margin.mjs +63 -27
- package/browser/editor/page/media-menu/index.mjs +6 -7
- package/browser/editor/page/menu.mjs +86 -31
- package/browser/editor/page/merge.mjs +24 -0
- package/browser/editor/page/notices.mjs +3 -3
- package/browser/editor/page/offered.mjs +1 -1
- package/browser/editor/page/outline/folds.mjs +11 -10
- package/browser/editor/page/outline/index.mjs +131 -45
- package/browser/editor/page/outline/list.mjs +23 -11
- package/browser/editor/page/outline/read.mjs +1 -1
- package/browser/editor/page/outline/strip.mjs +7 -1
- package/browser/editor/page/page-objects.mjs +13 -2
- package/browser/editor/page/panel.mjs +9 -13
- package/browser/editor/page/present-links.mjs +11 -2
- package/browser/editor/page/resize/index.mjs +42 -29
- package/browser/editor/page/selection/delete.mjs +8 -6
- package/browser/editor/page/selection/index.mjs +10 -3
- package/browser/editor/page/served.mjs +14 -0
- package/browser/editor/page/session.mjs +101 -6
- package/browser/editor/page/slash-menu/index.mjs +3 -3
- package/browser/editor/page/table/cell-bar.mjs +4 -1
- package/browser/editor/page/table/cells.mjs +103 -47
- package/browser/editor/page/table/icons.mjs +3 -1
- package/browser/editor/page/table/index.mjs +40 -16
- package/browser/editor/page/table/pictures.mjs +299 -0
- package/browser/editor/page/table/views.mjs +150 -0
- package/browser/editor/page/table/widths.mjs +9 -4
- package/browser/editor/page/text-select/index.mjs +43 -14
- package/browser/editor/page/todo-writes.mjs +75 -0
- package/browser/editor/page/tooltip.mjs +1 -1
- package/browser/editor/page/type-grid.mjs +4 -3
- package/browser/editor/page/typing/code-edges.mjs +63 -17
- package/browser/editor/page/typing/index.mjs +65 -9
- package/browser/editor/page/typing/leave.mjs +1 -1
- package/browser/editor/page/ui.mjs +13 -0
- package/browser/shared/annotations.mjs +8 -10
- package/browser/shared/block-packs.mjs +404 -0
- package/browser/shared/board-places.mjs +224 -0
- package/browser/shared/card-size.mjs +59 -0
- package/browser/shared/code-folds.mjs +5 -1
- package/browser/shared/colors.mjs +17 -14
- package/browser/shared/component-catalog.mjs +345 -54
- package/browser/shared/component-source.mjs +37 -0
- package/browser/shared/components/callout.mjs +4 -2
- package/browser/shared/components/index.mjs +72 -9
- package/browser/shared/components/installed.mjs +110 -8
- package/browser/shared/components/page.mjs +22 -3
- package/browser/shared/components/state.mjs +5 -1
- package/browser/shared/components/table.mjs +1 -1
- package/browser/shared/components/text.mjs +2 -2
- package/browser/shared/document-look.mjs +183 -0
- package/browser/shared/drafts.mjs +432 -0
- package/browser/shared/emoji/data/LICENSE-lucide.txt +43 -0
- package/browser/shared/emoji/data/README.md +4 -2
- package/browser/shared/emoji/data/categories.json +1 -1
- package/browser/shared/emoji/data/keywords-en.json +1 -1
- package/browser/shared/emoji/data/keywords-zh.json +1 -1
- package/browser/shared/emoji/data/names.json +1 -1
- package/browser/shared/emoji/data/positions.json +1 -1
- package/browser/shared/emoji/data/twemoji-index.json +1 -1
- package/browser/shared/emoji/data/twemoji-svg.bin +0 -0
- package/browser/shared/emoji/data.mjs +10 -12
- package/browser/shared/emoji/emoji.mjs +8 -7
- package/browser/shared/emoji/icon-value.mjs +4 -3
- package/browser/shared/extension-sidebar.mjs +126 -0
- package/browser/shared/extensions.mjs +79 -0
- package/browser/shared/file-table.mjs +101 -0
- package/browser/shared/html-tree.mjs +11 -5
- package/browser/shared/i18n/en.mjs +374 -35
- package/browser/shared/json-layout.mjs +47 -0
- package/browser/shared/long-runs.mjs +39 -0
- package/browser/shared/net-cache.mjs +133 -0
- package/browser/shared/net-keys.mjs +32 -0
- package/browser/shared/net-policy.mjs +177 -0
- package/browser/shared/new-names.mjs +5 -2
- package/browser/shared/outline-shape.mjs +128 -0
- package/browser/shared/outline.mjs +458 -0
- package/browser/shared/pack-manifest.mjs +77 -0
- package/browser/shared/page-address.mjs +6 -3
- package/browser/shared/page-cards.mjs +308 -0
- package/browser/shared/page-links.mjs +69 -6
- package/browser/shared/pages.mjs +388 -0
- package/browser/shared/paths.mjs +6 -0
- package/browser/shared/preferences.mjs +10 -4
- package/browser/shared/preview-server.mjs +3 -7
- package/browser/shared/session.mjs +13 -5
- package/browser/shared/shipped-blocks.mjs +299 -0
- package/browser/shared/table-chart.mjs +33 -1
- package/browser/shared/todos.mjs +83 -0
- package/browser/shared/user-directory.mjs +24 -0
- package/browser/shared/versions.mjs +14 -0
- package/browser/shared/web-links.mjs +134 -0
- package/browser/shared/workspace-columns.mjs +120 -0
- package/browser/shared/workspace-look.mjs +91 -0
- package/browser/shared/workspace-name.mjs +154 -0
- package/browser/shared/workspace-query.mjs +125 -0
- package/browser/shared/workspace-registry.mjs +272 -0
- package/browser/shared/workspace.mjs +171 -20
- package/browser/shared/zoom.mjs +5 -5
- package/dist/chunk-2NRBY6AJ.mjs +2 -0
- package/dist/chunk-32ZUEFZ7.mjs +2 -0
- package/dist/chunk-35NQ4PLQ.mjs +2 -0
- package/dist/chunk-3KJHLHUO.mjs +2 -0
- package/dist/chunk-3NJACR4W.mjs +2 -0
- package/dist/chunk-4AV456RQ.mjs +2 -0
- package/dist/chunk-4OZWXZE5.mjs +5 -0
- package/dist/chunk-5XYHDBJ5.mjs +2 -0
- package/dist/chunk-5ZJA7CXT.mjs +2 -0
- package/dist/chunk-6A53MZYZ.mjs +2 -0
- package/dist/chunk-6EXH3ORZ.mjs +166 -0
- package/dist/chunk-6EZ7FNIK.mjs +3 -0
- package/dist/{chunk-UXUK4PMC.mjs → chunk-6QBHU4DF.mjs} +1 -1
- package/dist/{chunk-6U2SLSDN.mjs → chunk-6VTU6KEO.mjs} +1 -1
- package/dist/chunk-B4P2CM2J.mjs +3 -0
- package/dist/chunk-BPL64HGA.mjs +4 -0
- package/dist/chunk-BVEFGE4B.mjs +2 -0
- package/dist/chunk-BZ5RAF7L.mjs +2 -0
- package/dist/chunk-CRJEG7MT.mjs +2 -0
- package/dist/{chunk-B3VTYBYR.mjs → chunk-D4CKRD3V.mjs} +91 -91
- package/dist/chunk-D4EURAX4.mjs +4 -0
- package/dist/chunk-DQCE7TJY.mjs +5 -0
- package/dist/chunk-DR73Y2UJ.mjs +3 -0
- package/dist/{chunk-TMYZB6AV.mjs → chunk-EKNHM3P4.mjs} +1 -1
- package/dist/{chunk-DB4WKGYF.mjs → chunk-ERLAIBOA.mjs} +2 -2
- package/dist/chunk-EURLTOTZ.mjs +4 -0
- package/dist/chunk-FJYN7RTH.mjs +4 -0
- package/dist/chunk-FWNRPMCJ.mjs +12 -0
- package/dist/chunk-FWW4CSAZ.mjs +2 -0
- package/dist/{chunk-2B5E4CDJ.mjs → chunk-GPIWQ4X4.mjs} +1 -1
- package/dist/chunk-GY3FAUVM.mjs +2 -0
- package/dist/chunk-HLYV7RIH.mjs +2 -0
- package/dist/chunk-HMYTM3GT.mjs +15 -0
- package/dist/chunk-IA4PSIMD.mjs +2 -0
- package/dist/chunk-JEUK3ZO7.mjs +2 -0
- package/dist/chunk-JVHHHGEA.mjs +3 -0
- package/dist/chunk-KTKHRC6H.mjs +2 -0
- package/dist/chunk-L7UP52JO.mjs +2 -0
- package/dist/chunk-MHW7ZKOU.mjs +2 -0
- package/dist/chunk-N76HWBA3.mjs +10 -0
- package/dist/chunk-N7AZZLGT.mjs +548 -0
- package/dist/chunk-NAMN3RAF.mjs +2 -0
- package/dist/{chunk-YXAUQPVK.mjs → chunk-NFMCP2HI.mjs} +3 -3
- package/dist/chunk-NG375ILQ.mjs +2 -0
- package/dist/chunk-NVRNLK25.mjs +6 -0
- package/dist/chunk-NWFBE2YA.mjs +2 -0
- package/dist/chunk-NWR2LT5B.mjs +2 -0
- package/dist/chunk-OJKMINIU.mjs +20 -0
- package/dist/chunk-OUUP3WKT.mjs +2 -0
- package/dist/chunk-OW5NWPOJ.mjs +10 -0
- package/dist/chunk-PAREWQGB.mjs +4 -0
- package/dist/chunk-POQSE4C2.mjs +2 -0
- package/dist/chunk-PUOQ65NC.mjs +2 -0
- package/dist/{chunk-Z52HTUW7.mjs → chunk-PVER7LSC.mjs} +2 -2
- package/dist/chunk-PZDLJJTJ.mjs +3 -0
- package/dist/chunk-Q47PLKIJ.mjs +15 -0
- package/dist/chunk-Q4UEPUWF.mjs +2 -0
- package/dist/chunk-QKXMPUXC.mjs +2 -0
- package/dist/chunk-QOUEFUCH.mjs +16 -0
- package/dist/chunk-RFDZXFJF.mjs +13 -0
- package/dist/chunk-RKPWLGZ3.mjs +4 -0
- package/dist/chunk-RMECZA2K.mjs +2 -0
- package/dist/{chunk-EUX7IC5J.mjs → chunk-SQ6Y2ZMA.mjs} +2 -2
- package/dist/chunk-SX4LJYT6.mjs +8 -0
- package/dist/chunk-SXHBYZST.mjs +16 -0
- package/dist/chunk-TANZRINB.mjs +2 -0
- package/dist/chunk-TEZAWDSQ.mjs +2 -0
- package/dist/chunk-UBBRTJ2R.mjs +24 -0
- package/dist/chunk-UFNYFFKO.mjs +20 -0
- package/dist/chunk-UGWYKHBL.mjs +170 -0
- package/dist/chunk-UKSHDZZ6.mjs +2 -0
- package/dist/chunk-UMHUSOPJ.mjs +2 -0
- package/dist/chunk-UNOYVIYR.mjs +2 -0
- package/dist/chunk-V6RIYQZZ.mjs +4 -0
- package/dist/chunk-VJPFVNNW.mjs +15 -0
- package/dist/chunk-VS3ZMVGX.mjs +5 -0
- package/dist/chunk-VTKNEYT3.mjs +6 -0
- package/dist/chunk-VXACTLO3.mjs +3 -0
- package/dist/chunk-W3BGBJQW.mjs +2 -0
- package/dist/chunk-YI43RG4P.mjs +2 -0
- package/dist/chunk-YQGT4AB2.mjs +6 -0
- package/dist/chunk-ZB4H7ZN4.mjs +2 -0
- package/dist/{chunk-ACOPDCNB.mjs → chunk-ZHEHPMBK.mjs} +1 -1
- package/dist/chunk-ZTHICSSF.mjs +2 -0
- package/dist/chunk-ZUNVAXLH.mjs +2 -0
- package/dist/chunk-ZWPMCK7P.mjs +2 -0
- package/dist/cli.mjs +1 -1
- package/dist/server.mjs +1 -1
- package/dist/{chunk-EVJ3BX3M.mjs → update-fetch.mjs} +1 -1
- package/dist/worker.mjs +1 -1
- package/kit/board.css +95 -0
- package/kit/board.js +250 -0
- package/kit/charts.js +5 -71
- package/kit/code.js +14 -14
- package/kit/math.js +18 -2
- package/kit/report.css +500 -151
- package/kit/runtime.js +1720 -170
- package/kit/state.js +10 -1
- package/kit/tables.js +172 -37
- package/kit/ui.js +166 -27
- package/package.json +2 -1
- package/packs/gallery/card/component.json +14 -0
- package/packs/gallery/card/example.html +10 -0
- package/packs/gallery/card/preview.svg +1 -0
- package/packs/gallery/card/style.css +6 -0
- package/packs/gallery/card/template.html +6 -0
- package/packs/gallery/card/writing.md +14 -0
- package/packs/gallery/chart-card/component.json +15 -0
- package/packs/gallery/chart-card/example.html +14 -0
- package/packs/gallery/chart-card/kit.js +130 -0
- package/packs/gallery/chart-card/preview.svg +1 -0
- package/packs/gallery/chart-card/style.css +42 -0
- package/packs/gallery/chart-card/template.html +13 -0
- package/packs/gallery/chart-card/writing.md +20 -0
- package/packs/gallery/chart-view/component.json +20 -0
- package/packs/gallery/chart-view/example.html +13 -0
- package/packs/gallery/chart-view/kit.js +355 -0
- package/packs/gallery/chart-view/preview.svg +1 -0
- package/packs/gallery/chart-view/style.css +94 -0
- package/packs/gallery/chart-view/template.html +3 -0
- package/packs/gallery/chart-view/writing.md +22 -0
- package/packs/gallery/countdown/component.json +18 -0
- package/packs/gallery/countdown/example.html +3 -0
- package/packs/gallery/countdown/kit.js +156 -0
- package/packs/gallery/countdown/preview.svg +1 -0
- package/packs/gallery/countdown/style.css +130 -0
- package/packs/gallery/countdown/template.html +3 -0
- package/packs/gallery/countdown/writing.md +22 -0
- package/packs/gallery/habit/component.json +14 -0
- package/packs/gallery/habit/example.html +3 -0
- package/packs/gallery/habit/kit.js +295 -0
- package/packs/gallery/habit/preview.svg +1 -0
- package/packs/gallery/habit/style.css +246 -0
- package/packs/gallery/habit/template.html +3 -0
- package/packs/gallery/habit/writing.md +21 -0
- package/packs/gallery/heatmap/component.json +18 -0
- package/packs/gallery/heatmap/example.html +3 -0
- package/packs/gallery/heatmap/kit.js +351 -0
- package/packs/gallery/heatmap/preview.svg +1 -0
- package/packs/gallery/heatmap/style.css +201 -0
- package/packs/gallery/heatmap/template.html +3 -0
- package/packs/gallery/heatmap/writing.md +21 -0
- package/packs/gallery/kanban/component.json +18 -0
- package/packs/gallery/kanban/example.html +12 -0
- package/packs/gallery/kanban/kit.js +540 -0
- package/packs/gallery/kanban/preview.svg +1 -0
- package/packs/gallery/kanban/style.css +212 -0
- package/packs/gallery/kanban/template.html +3 -0
- package/packs/gallery/kanban/writing.md +20 -0
- package/packs/gallery/metric/component.json +22 -0
- package/packs/gallery/metric/example.html +15 -0
- package/packs/gallery/metric/kit.js +248 -0
- package/packs/gallery/metric/preview.svg +1 -0
- package/packs/gallery/metric/style.css +92 -0
- package/packs/gallery/metric/template.html +3 -0
- package/packs/gallery/metric/writing.md +23 -0
- package/packs/gallery/note/component.json +14 -0
- package/packs/gallery/note/example.html +3 -0
- package/packs/gallery/note/kit.js +102 -0
- package/packs/gallery/note/preview.svg +1 -0
- package/packs/gallery/note/style.css +76 -0
- package/packs/gallery/note/template.html +3 -0
- package/packs/gallery/note/writing.md +18 -0
- package/packs/gallery/pack.json +8 -0
- package/packs/gallery/recent/component.json +13 -0
- package/packs/gallery/recent/example.html +1 -0
- package/packs/gallery/recent/kit.js +238 -0
- package/packs/gallery/recent/preview.svg +1 -0
- package/packs/gallery/recent/style.css +158 -0
- package/packs/gallery/recent/template.html +1 -0
- package/packs/gallery/recent/writing.md +15 -0
- package/packs/gallery/static/component.json +13 -0
- package/packs/gallery/static/example.html +11 -0
- package/packs/gallery/static/preview.svg +1 -0
- package/packs/gallery/static/style.css +138 -0
- package/packs/gallery/static/template.html +1 -0
- package/packs/gallery/static/writing.md +18 -0
- package/packs/gallery/stats/component.json +13 -0
- package/packs/gallery/stats/example.html +1 -0
- package/packs/gallery/stats/kit.js +166 -0
- package/packs/gallery/stats/preview.svg +1 -0
- package/packs/gallery/stats/style.css +151 -0
- package/packs/gallery/stats/template.html +1 -0
- package/packs/gallery/stats/writing.md +11 -0
- package/packs/gallery/today/component.json +12 -0
- package/packs/gallery/today/example.html +1 -0
- package/packs/gallery/today/kit.js +185 -0
- package/packs/gallery/today/preview.svg +1 -0
- package/packs/gallery/today/style.css +120 -0
- package/packs/gallery/today/template.html +1 -0
- package/packs/gallery/today/writing.md +14 -0
- package/packs/gallery/todos/component.json +19 -0
- package/packs/gallery/todos/example.html +3 -0
- package/packs/gallery/todos/kit.js +342 -0
- package/packs/gallery/todos/preview.svg +1 -0
- package/packs/gallery/todos/style.css +267 -0
- package/packs/gallery/todos/template.html +3 -0
- package/packs/gallery/todos/writing.md +30 -0
- package/packs/gallery/weather/component.json +19 -0
- package/packs/gallery/weather/example.html +3 -0
- package/packs/gallery/weather/kit.js +312 -0
- package/packs/gallery/weather/preview.svg +1 -0
- package/packs/gallery/weather/style.css +258 -0
- package/packs/gallery/weather/template.html +3 -0
- package/packs/gallery/weather/writing.md +26 -0
- package/packs/gallery-soft/pack.json +8 -0
- package/release.json +13 -11
- package/sdk/doc-kit.d.ts +404 -7
- package/sdk/doc-state.d.ts +2 -0
- package/skill/SKILL.md +71 -26
- package/skill/references/block-script.md +140 -0
- package/skill/references/building-blocks.md +257 -0
- package/skill/references/example-report.html +1 -1
- package/skill/references/extensions.md +59 -0
- package/skill/references/pages-and-data.md +221 -0
- package/skill/references/writing-html.md +9 -7
- package/skill/sdk/doc-kit.d.ts +404 -7
- package/skill/sdk/doc-state.d.ts +2 -0
- package/web/assets/index-BK2e_07w.js +13 -0
- package/web/assets/index-CWFI83mF.css +1 -0
- package/web/index.html +2 -2
- package/browser/editor/components/callout/page.mjs +0 -13
- package/dist/chunk-2PBALTR3.mjs +0 -57
- package/dist/chunk-3LA3EMDE.mjs +0 -15
- package/dist/chunk-5FRMCDPY.mjs +0 -16
- package/dist/chunk-5LEK2CBS.mjs +0 -2
- package/dist/chunk-5OFN5AHC.mjs +0 -2
- package/dist/chunk-5SIYS5HN.mjs +0 -2
- package/dist/chunk-5TEK3RAD.mjs +0 -2
- package/dist/chunk-6CYG3Z4V.mjs +0 -2
- package/dist/chunk-7GHT2UCA.mjs +0 -15
- package/dist/chunk-7QQBR7PB.mjs +0 -2
- package/dist/chunk-ATCJYAR4.mjs +0 -2
- package/dist/chunk-C7HWOBIF.mjs +0 -2
- package/dist/chunk-E7VYDG2X.mjs +0 -2
- package/dist/chunk-EZY3WC6Z.mjs +0 -15
- package/dist/chunk-FQGQH4KM.mjs +0 -2
- package/dist/chunk-G7TOXONE.mjs +0 -6
- package/dist/chunk-GPF4YWWB.mjs +0 -9
- package/dist/chunk-GYQV7Y4J.mjs +0 -120
- package/dist/chunk-HMHK3EQ6.mjs +0 -2
- package/dist/chunk-HQQMJCQJ.mjs +0 -10
- package/dist/chunk-IERUOGC3.mjs +0 -6
- package/dist/chunk-ITNLYXXV.mjs +0 -3
- package/dist/chunk-L4DVONOG.mjs +0 -2
- package/dist/chunk-LAE5NQ4B.mjs +0 -2
- package/dist/chunk-LC7YNQFG.mjs +0 -2
- package/dist/chunk-LHTFLRB6.mjs +0 -4
- package/dist/chunk-NFIBI4IP.mjs +0 -26
- package/dist/chunk-NSKUTQ5J.mjs +0 -5
- package/dist/chunk-O52JMOCZ.mjs +0 -2
- package/dist/chunk-P2CAZPDP.mjs +0 -3
- package/dist/chunk-QMQUXTU4.mjs +0 -12
- package/dist/chunk-QVWVFC5K.mjs +0 -6
- package/dist/chunk-QYKCJ7FG.mjs +0 -8
- package/dist/chunk-QZY6Q64C.mjs +0 -2
- package/dist/chunk-TDQP3DKQ.mjs +0 -10
- package/dist/chunk-TX6JH7TR.mjs +0 -2
- package/dist/chunk-UNUEWH4S.mjs +0 -2
- package/dist/chunk-V4CPWKMZ.mjs +0 -2
- package/dist/chunk-VACRB2NE.mjs +0 -3
- package/dist/chunk-W63L7367.mjs +0 -7
- package/dist/chunk-W7CXPCRV.mjs +0 -6
- package/dist/chunk-XINNG4F2.mjs +0 -4
- package/dist/chunk-YL2DPWVS.mjs +0 -4
- package/dist/chunk-YZ5Z6H4W.mjs +0 -4
- package/dist/chunk-ZBIM6ARY.mjs +0 -216
- package/skill/references/building-components.md +0 -327
- package/web/assets/index-B6Ai3wsa.js +0 -13
- package/web/assets/index-SYPC3EZy.css +0 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { TODO_EVENT, TODO_MOST, TODO_ROUTE } from "../../shared/workspace-query.mjs";
|
|
2
|
+
import { postAnswer } from "./post.mjs";
|
|
3
|
+
|
|
4
|
+
// To-dos of documents checked from this page (workspace.setTodo, the plan's 5.1; docs/editor.md "To-dos
|
|
5
|
+
// checked from another page"): the kit's ask (TODO_EVENT, cancelable on the window: { ask: { slug, ref,
|
|
6
|
+
// done }, answer(promise) }) taken by whoever holds the page's token (a custom page's board, a document's
|
|
7
|
+
// editor) and written by the workspace's service (POST TODO_ROUTE, one document a request: the edit
|
|
8
|
+
// service's setTodos, one commit of the reader's). The checks of one document wait in a line of their own:
|
|
9
|
+
// those asked while one write of it is out go together in the next (its items in the order asked, the
|
|
10
|
+
// last of an item winning), so that a reader ticking five boxes quickly makes two commits, not five.
|
|
11
|
+
// Each ask is answered { ok: true, changed, block } (`block` the item's id now, which the commit gives
|
|
12
|
+
// one that had none) or { ok: false, reason, message? }, never rejected.
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* `token`: the page map's. `done(ask, answer)`: an ask answered (the board keeps an undo step of one that
|
|
16
|
+
* changed its document). Returns { write(ask) (a promise of its answer), idle() (once every write asked so
|
|
17
|
+
* far is answered), listen() (takes the kit's asks; returns the function that stops it) }.
|
|
18
|
+
*/
|
|
19
|
+
export function createTodoWrites({ token, done = () => {} }) {
|
|
20
|
+
const lines = new Map(); // slug -> { waiting: [{ ask, resolve }], out: Promise | null }
|
|
21
|
+
|
|
22
|
+
async function send(slug, line) {
|
|
23
|
+
const batch = line.waiting.splice(0, TODO_MOST);
|
|
24
|
+
const answer = await postAnswer(TODO_ROUTE, token, { slug, items: batch.map(({ ask }) => ({ ref: ask.ref, done: ask.done })) });
|
|
25
|
+
batch.forEach(({ ask, resolve }, index) => {
|
|
26
|
+
const result = answer?.ok ? answer.results?.[index] ?? { ok: false, reason: "failed" } : { ok: false, reason: answer?.reason === "offline" ? "offline" : answer?.reason ?? "failed", ...(typeof answer?.message === "string" ? { message: answer.message } : {}) };
|
|
27
|
+
try {
|
|
28
|
+
done(ask, result);
|
|
29
|
+
} finally {
|
|
30
|
+
resolve(result);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// The line of a document: written once nothing of it is out, what waits then going together.
|
|
36
|
+
function run(slug) {
|
|
37
|
+
const line = lines.get(slug);
|
|
38
|
+
if (line.out || line.waiting.length === 0) return;
|
|
39
|
+
// A microtask's wait, so that the asks of one gesture (a block checking several at once) go together.
|
|
40
|
+
line.out = Promise.resolve().then(() => send(slug, line)).catch(() => {}).finally(() => {
|
|
41
|
+
line.out = null;
|
|
42
|
+
if (line.waiting.length > 0) run(slug);
|
|
43
|
+
else lines.delete(slug);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function write(ask) {
|
|
48
|
+
return new Promise((resolve) => {
|
|
49
|
+
if (!lines.has(ask.slug)) lines.set(ask.slug, { waiting: [], out: null });
|
|
50
|
+
lines.get(ask.slug).waiting.push({ ask, resolve });
|
|
51
|
+
run(ask.slug);
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
write,
|
|
57
|
+
async idle() {
|
|
58
|
+
for (;;) {
|
|
59
|
+
const out = [...lines.values()].map((line) => line.out).filter(Boolean);
|
|
60
|
+
if (out.length === 0) return;
|
|
61
|
+
await Promise.all(out);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
listen() {
|
|
65
|
+
const take = (event) => {
|
|
66
|
+
const { ask, answer } = event.detail ?? {};
|
|
67
|
+
if (event.defaultPrevented || !ask || typeof answer !== "function") return;
|
|
68
|
+
event.preventDefault();
|
|
69
|
+
answer(write(ask));
|
|
70
|
+
};
|
|
71
|
+
addEventListener(TODO_EVENT, take);
|
|
72
|
+
return () => removeEventListener(TODO_EVENT, take);
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
@@ -22,7 +22,7 @@ const STYLE = `
|
|
|
22
22
|
const DELAY = 150;
|
|
23
23
|
const GAP = 6;
|
|
24
24
|
const MAC = /Mac|iPhone|iPad/.test(globalThis.navigator?.platform ?? "");
|
|
25
|
-
const KEYS = MAC ? { mod: "⌘", shift: "⇧", alt: "⌥" } : { mod: "Ctrl", shift: "⇧", alt: "Alt" };
|
|
25
|
+
const KEYS = MAC ? { mod: "⌘", shift: "⇧", alt: "⌥", enter: "↩" } : { mod: "Ctrl", shift: "⇧", alt: "Alt", enter: "Enter" };
|
|
26
26
|
let shown = null; // { node, tip }
|
|
27
27
|
let timer = 0;
|
|
28
28
|
|
|
@@ -6,8 +6,9 @@ import { t } from "../../shared/i18n/index.mjs";
|
|
|
6
6
|
|
|
7
7
|
// The types a block can be turned into, as icons side by side (as Feishu's block menu), the block's
|
|
8
8
|
// own type marked: the top of the block menu (block-menu/) and the format bar's "turn into"
|
|
9
|
-
// (format-bar/). The buttons are the format bar's (32×28px, 4px apart
|
|
10
|
-
//
|
|
9
|
+
// (format-bar/). The buttons are the format bar's (32×28px, 4px apart; the current one marked as
|
|
10
|
+
// a pressed tool of the bar is, its icon's lines in the bar's blue, --ge-accent, and no fill of its
|
|
11
|
+
// own, so the pointer's gray fills it as any other), so both read alike. Each icon names its type, and its Markdown shortcut, in a tooltip.
|
|
11
12
|
// A type that says `corner` has no cell of its own but the gray corner of that type's (a split
|
|
12
13
|
// button): 小字's of 文本's, so 文本 and the headings fill one line. The corner shows only with the
|
|
13
14
|
// pointer (or the keys) on the cell, or, blue, when the block is of that type. It is a click target
|
|
@@ -26,7 +27,7 @@ const STYLE = `
|
|
|
26
27
|
.ge-type { display: flex; align-items: center; justify-content: center; width: ${CELL}px; height: 28px; padding: 0; border: 0; border-radius: 6px; background: transparent; color: var(--ge-ico); cursor: pointer; transition: background 20ms ease-in; }
|
|
27
28
|
.ge-type:hover, .ge-type[data-active] { background: var(--ge-hover); }
|
|
28
29
|
.ge-type:active { background: var(--ge-press); }
|
|
29
|
-
.ge-type[aria-current="true"] {
|
|
30
|
+
.ge-type[aria-current="true"] { color: var(--ge-accent); }
|
|
30
31
|
.ge-type-pair { position: relative; border-radius: 6px; overflow: hidden; }
|
|
31
32
|
.ge-type-corner { position: absolute; right: 0; bottom: 0; width: ${CORNER}px; height: ${CORNER}px; padding: 0; border: 0; background: transparent; cursor: pointer; }
|
|
32
33
|
.ge-type-corner::before { content: ""; position: absolute; inset: 0; background: light-dark(rgb(55 53 47 / 12%), rgb(255 255 255 / 13%)); clip-path: path("${TRIANGLE}"); opacity: 0; transition: background 20ms ease-in, opacity 120ms ease-out; }
|
|
@@ -12,7 +12,11 @@ import { ENTRIES } from "../../components/registry.mjs";
|
|
|
12
12
|
// the caret in a pad (pads.mjs). Code blocks are text blocks of their own (components/code/) and
|
|
13
13
|
// have none of this. A component's entry in the text (`entry`: a chip as padded as code) has the
|
|
14
14
|
// same stops, and Backspace at the stop after it (Delete at the one before it) takes the whole
|
|
15
|
-
// entry away (
|
|
15
|
+
// entry away (takeEntry, on the key's keydown through beforeDelete and on its beforeinput where an
|
|
16
|
+
// input method's keydown says 229; it says what the page says of that, editor.mjs records the step).
|
|
17
|
+
// A Backspace that takes the last character between inline code or an entry and the caret after it
|
|
18
|
+
// leaves the caret outside it, at the stop after it (deletingBack, deletedBack): the browser puts it
|
|
19
|
+
// in at the end (an entry's: left of its icon), its end and the text after it one place to it.
|
|
16
20
|
|
|
17
21
|
const EDGED = ["code", ...ENTRIES.map(({ at }) => at)].join(", ");
|
|
18
22
|
const isEdged = (node) => node?.nodeType === 1 && node.matches(EDGED);
|
|
@@ -187,28 +191,48 @@ export function codePress(host, x, y) {
|
|
|
187
191
|
}
|
|
188
192
|
|
|
189
193
|
/**
|
|
190
|
-
* Backspace
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
+
* Backspace (`back`) at the stop after a component's entry, or Delete at the one before it: the whole
|
|
195
|
+
* entry goes, as a chip of the text does, the caret where it stood, and what the page says of that is
|
|
196
|
+
* returned; nothing otherwise. The keydown's (beforeDelete) and the beforeinput's, for a key whose
|
|
197
|
+
* keydown the editor passed by (an input method's, keyCode 229: editor.mjs). The pads beside it go
|
|
198
|
+
* with it, before the text either side of it is joined, so that no zero-width space is left in that
|
|
199
|
+
* text (a pad an undo step put back is part of the text beside it by then).
|
|
194
200
|
*/
|
|
195
|
-
export function
|
|
201
|
+
export function takeEntry(host, back) {
|
|
196
202
|
const selection = getSelection();
|
|
197
203
|
if (!selection.rangeCount || !selection.isCollapsed) return;
|
|
198
|
-
const back = key === "Backspace";
|
|
199
|
-
// At the stop after an entry (or before it, for Delete): the whole entry goes.
|
|
200
204
|
const outside = caretAtEdge(host);
|
|
201
205
|
const entry = outside && !outside.inside ? entryOf(outside.code) : undefined;
|
|
202
|
-
if (entry
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
return entry.removed;
|
|
206
|
+
if (!entry || (back ? outside.side !== "end" : outside.side !== "start")) return;
|
|
207
|
+
const { code } = outside;
|
|
208
|
+
for (const [next, trim] of [["previousSibling", new RegExp(`${ZWSP}+$`)], ["nextSibling", new RegExp(`^${ZWSP}+`)]]) {
|
|
209
|
+
for (let node = code[next]; node?.nodeType === 3; node = code[next]) {
|
|
210
|
+
node.data = node.data.replace(trim, "");
|
|
211
|
+
if (node.data !== "") break;
|
|
212
|
+
node.remove();
|
|
213
|
+
}
|
|
211
214
|
}
|
|
215
|
+
const caret = host.ownerDocument.createRange();
|
|
216
|
+
caret.setStartBefore(code);
|
|
217
|
+
caret.collapse(true);
|
|
218
|
+
code.remove();
|
|
219
|
+
host.normalize();
|
|
220
|
+
select(caret);
|
|
221
|
+
return entry.removed;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Backspace or Delete with the caret in a pad at an edge: the pad goes first, the caret where the
|
|
226
|
+
* key then takes the character beside it, as it would without the pad (keydown, before the browser
|
|
227
|
+
* deletes or the editor merges blocks). At the stop beside a component's entry the whole entry goes
|
|
228
|
+
* (takeEntry), and what the page says of that is returned; nothing otherwise.
|
|
229
|
+
*/
|
|
230
|
+
export function beforeDelete(host, key) {
|
|
231
|
+
const back = key === "Backspace";
|
|
232
|
+
const removed = takeEntry(host, back);
|
|
233
|
+
if (removed) return removed;
|
|
234
|
+
const selection = getSelection();
|
|
235
|
+
if (!selection.rangeCount || !selection.isCollapsed) return;
|
|
212
236
|
const pad = selection.anchorNode;
|
|
213
237
|
if (!isPad(pad) || !host.contains(pad)) return;
|
|
214
238
|
const edge = caretAtEdge(host);
|
|
@@ -226,3 +250,25 @@ export function beforeDelete(host, key) {
|
|
|
226
250
|
caret.collapse(true);
|
|
227
251
|
select(caret);
|
|
228
252
|
}
|
|
253
|
+
|
|
254
|
+
// The host whose caret a deletion backward found in text outside any inline code or entry (no pad),
|
|
255
|
+
// for the input after it (deletedBack).
|
|
256
|
+
let backFrom = null;
|
|
257
|
+
|
|
258
|
+
/** A deletion backward about to happen (its beforeinput): where the caret stands, for deletedBack. */
|
|
259
|
+
export function deletingBack(host) {
|
|
260
|
+
const selection = getSelection();
|
|
261
|
+
const node = selection.rangeCount && selection.isCollapsed ? selection.anchorNode : null;
|
|
262
|
+
backFrom = node?.nodeType === 3 && !isPad(node) && !node.parentElement.closest(EDGED) ? host : null;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* The deletion done (its input): a caret it took from the text after inline code or an entry into
|
|
267
|
+
* it, at its end, goes back out to the stop after it, where the reader deleting back stays.
|
|
268
|
+
*/
|
|
269
|
+
export function deletedBack(host) {
|
|
270
|
+
const was = backFrom === host;
|
|
271
|
+
backFrom = null;
|
|
272
|
+
const edge = was && caretAtEdge(host);
|
|
273
|
+
if (edge && edge.inside && edge.side === "end") padCaret(edge.code, "after");
|
|
274
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
boxKind, can, emptyContainer, isEmpty, isFirstLine, isHost, limitText, mergeWithPrevious, nestedBlocks, nestedLists, nextLine, parentItem, previousLine, removalTarget, splitBlock, takeOut, textEnd, unitElement,
|
|
2
|
+
UNIT, boxKind, can, emptyContainer, isEmpty, isFirstLine, isHost, limitText, mergeWithPrevious, nestedBlocks, nestedLists, nextLine, parentItem, previousLine, removalTarget, splitBlock, takeOut, textEnd, unitElement, newParagraphHost, withLeads,
|
|
3
3
|
} from "../core.mjs";
|
|
4
4
|
import { atEdge, caretAt, hosts, select, textNear } from "../caret.mjs";
|
|
5
5
|
import { convertible } from "../convert.mjs";
|
|
6
6
|
import { joinCode } from "../marks.mjs";
|
|
7
7
|
import { numberWithUnit, sideOf, WORD } from "../../../shared/inline-spacing.mjs";
|
|
8
8
|
import { pageOf, pagesAround } from "../page-objects.mjs";
|
|
9
|
-
import { BLOCK_TYPES, HOSTS, firstSaysOf, placeholderOf, textFilters, textTypeOf } from "../../components/registry.mjs";
|
|
9
|
+
import { BLOCK_TYPES, HOSTS, accepts, firstSaysOf, placeholderOf, textFilters, textTypeOf } from "../../components/registry.mjs";
|
|
10
10
|
import { t } from "../../../shared/i18n/index.mjs";
|
|
11
11
|
|
|
12
12
|
// Typing in a block (docs/editor.md, "Browser side"): every key goes first to the component the block
|
|
@@ -25,6 +25,8 @@ import { t } from "../../../shared/i18n/index.mjs";
|
|
|
25
25
|
// 3万5千), and a block written without such spaces is typed in its own way (none added).
|
|
26
26
|
const HAN = /[\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30fa\u30fc-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]/;
|
|
27
27
|
const LATIN = /[A-Za-z0-9]/;
|
|
28
|
+
// The text blocks that say their placeholder whenever they are empty (HOSTS' `untitled`: the page's title).
|
|
29
|
+
const UNTITLED = Object.keys(HOSTS).filter((kind) => HOSTS[kind].untitled).map((kind) => `main [data-ge-kind="${kind}"]`).join(", ");
|
|
28
30
|
const needsSpace = (a, b, before) => ((HAN.test(a) && LATIN.test(b)) || (LATIN.test(a) && HAN.test(b))) && !numberWithUnit(a, b, before);
|
|
29
31
|
// The block's own way with Chinese beside Latin letters and digits, from its text but what was just
|
|
30
32
|
// typed: true when it writes them together more often than apart (a number's unit is no sign either way).
|
|
@@ -47,13 +49,12 @@ function writtenTogether(host, node, start, end) {
|
|
|
47
49
|
/**
|
|
48
50
|
* struct(parents, touched, mutate): the editor's undoable structural change (history.mjs). say: the
|
|
49
51
|
* status line. keepText(unit): why a block may not go (block-info.mjs). paragraphBefore(host): an
|
|
50
|
-
* empty paragraph before the block, the caret staying (insert/).
|
|
51
|
-
* block, the caret in it, where its box takes one (insert/). removeBlocks(units): the blocks
|
|
52
|
+
* empty paragraph before the block, the caret staying (insert/). removeBlocks(units): the blocks
|
|
52
53
|
* deleted as the selected ones are (selection/delete.mjs). adding(): the block the "/" menu the
|
|
53
54
|
* handle's "+" opened is open in (slash-menu/), or null. leave: where Enter and Backspace leave a
|
|
54
|
-
* container (leave.mjs).
|
|
55
|
+
* container (leave.mjs). showHidden(node): the folds hiding a block opened (fold/ showAround).
|
|
55
56
|
*/
|
|
56
|
-
export function createTyping({ struct, say, keepText, paragraphBefore,
|
|
57
|
+
export function createTyping({ struct, say, keepText, paragraphBefore, removeBlocks, selectBlock = () => {}, adding = () => null, leave, showHidden = () => {} }) {
|
|
57
58
|
// A key, asked of the component of the text block `host` and then of what stands around it, nearest
|
|
58
59
|
// first (docs/editor.md, "The order of keys"): whether it was theirs. `ctx` is notion-lite's, as
|
|
59
60
|
// much of it as a key reads, the block being an element here.
|
|
@@ -62,8 +63,43 @@ export function createTyping({ struct, say, keepText, paragraphBefore, paragraph
|
|
|
62
63
|
return Boolean(key(pageOf(host)?.keys ?? {})?.(ctx, ...rest) || pagesAround(host).some((page) => key(page.keys?.around ?? {})?.(ctx, ...rest)));
|
|
63
64
|
}
|
|
64
65
|
|
|
66
|
+
// Enter in the page's title (HOSTS' `opensBody`): notion-lite's splitBlock for the page (enter.js, its
|
|
67
|
+
// first rule): what is selected goes, what follows the caret leaves the title for a new paragraph right
|
|
68
|
+
// below it, the first block of the page (an empty one at its end, a new untitled document's too), and
|
|
69
|
+
// the caret goes to its start; the title keeps what stands before the caret, never a line break. One
|
|
70
|
+
// undo step, the caret back in the title where it was. Below the title is the header's first line when it has one
|
|
71
|
+
// (the paragraph goes before it, in the header), else the first block after the header.
|
|
72
|
+
function enterBody(title) {
|
|
73
|
+
const selection = getSelection();
|
|
74
|
+
if (!selection.rangeCount || !title.contains(selection.getRangeAt(0).startContainer) || !title.contains(selection.getRangeAt(0).endContainer)) return;
|
|
75
|
+
const range = selection.getRangeAt(0);
|
|
76
|
+
const header = title.parentElement;
|
|
77
|
+
let line = title.nextElementSibling;
|
|
78
|
+
while (line && !line.matches(UNIT)) line = line.nextElementSibling;
|
|
79
|
+
const [box, before] = line ? [header, withLeads(line)[0]] : [header.parentElement, header.nextSibling];
|
|
80
|
+
const paragraph = newParagraphHost(document);
|
|
81
|
+
if (!box?.hasAttribute("data-ge-box") || !accepts(box.getAttribute("data-ge-box-kind"), paragraph.getAttribute("data-ge-type"))) {
|
|
82
|
+
say(limitText(title, "split"));
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
struct([...new Set([header, box])], [title], () => {
|
|
86
|
+
range.deleteContents();
|
|
87
|
+
const tail = document.createRange();
|
|
88
|
+
tail.setStart(range.startContainer, range.startOffset);
|
|
89
|
+
tail.setEnd(title, title.childNodes.length);
|
|
90
|
+
const moved = tail.extractContents();
|
|
91
|
+
if (moved.textContent.length > 0) paragraph.append(document.createTextNode(moved.textContent)); // the title's words, plain
|
|
92
|
+
title.normalize();
|
|
93
|
+
if (isEmpty(title)) title.replaceChildren();
|
|
94
|
+
box.insertBefore(paragraph, before);
|
|
95
|
+
return { touched: [title, paragraph], focus: paragraph };
|
|
96
|
+
}, { caret: true });
|
|
97
|
+
caretAt(paragraph, "start");
|
|
98
|
+
}
|
|
99
|
+
|
|
65
100
|
// Enter.
|
|
66
101
|
function split(host) {
|
|
102
|
+
if (HOSTS[host.getAttribute("data-ge-kind")]?.opensBody) return enterBody(host);
|
|
67
103
|
// The caret at the very start of a block with text: an empty paragraph goes before the block and
|
|
68
104
|
// the caret stays (a block that splits does this itself, splitBlock). This comes first: in a code
|
|
69
105
|
// block too, whose own Enter breaks the line.
|
|
@@ -75,8 +111,7 @@ export function createTyping({ struct, say, keepText, paragraphBefore, paragraph
|
|
|
75
111
|
// in any editor, and so does the empty last paragraph of a panel), the rule of every block.
|
|
76
112
|
if (asked((keys) => keys.enter, host) || leave.enter(host)) return;
|
|
77
113
|
if (!can(host, "split")) {
|
|
78
|
-
|
|
79
|
-
if (!HOSTS[host.getAttribute("data-ge-kind")]?.opensAfter || !atEdge(host, true) || !paragraphAfter(host)) say(limitText(host, "split"));
|
|
114
|
+
say(limitText(host, "split"));
|
|
80
115
|
return;
|
|
81
116
|
}
|
|
82
117
|
const selection = getSelection();
|
|
@@ -159,8 +194,15 @@ export function createTyping({ struct, say, keepText, paragraphBefore, paragraph
|
|
|
159
194
|
return true;
|
|
160
195
|
}
|
|
161
196
|
|
|
197
|
+
// A block on the line above or below that a folded heading hides (fold/: data-ge-folded on it or
|
|
198
|
+
// around it): its fold opens first, so a join never takes in words out of sight.
|
|
199
|
+
const opened = (line) => {
|
|
200
|
+
if (line?.closest?.("[data-ge-folded]")) showHidden(line);
|
|
201
|
+
};
|
|
202
|
+
|
|
162
203
|
// Backspace at the start of a block. Returns whether it was handled.
|
|
163
204
|
function backspace(host) {
|
|
205
|
+
opened(previousLine(host));
|
|
164
206
|
// The block's component (a list item's: a nested item moves out a level, the first or last item of
|
|
165
207
|
// a top-level list leaves it as body text, an emptied item holding lists stays), then what stands
|
|
166
208
|
// around it (the item a block stands under; a node, at the start of its first line, holding
|
|
@@ -192,6 +234,7 @@ export function createTyping({ struct, say, keepText, paragraphBefore, paragraph
|
|
|
192
234
|
|
|
193
235
|
// Delete at the end of a block. Returns whether it was handled.
|
|
194
236
|
function forwardDelete(host) {
|
|
237
|
+
opened(nextLine(host));
|
|
195
238
|
// Its component (an empty item holding blocks stays), then what stands around it (at the end of a
|
|
196
239
|
// node's last block nothing is taken in).
|
|
197
240
|
if (asked((keys) => keys.delete, host)) return true;
|
|
@@ -260,10 +303,23 @@ export function createTyping({ struct, say, keepText, paragraphBefore, paragraph
|
|
|
260
303
|
if (hint) host.setAttribute("data-ge-placeholder", hint);
|
|
261
304
|
else host?.removeAttribute("data-ge-placeholder");
|
|
262
305
|
host?.toggleAttribute("data-ge-adding", add);
|
|
306
|
+
untitled();
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// The page's title says 未命名文档 whenever it is empty, the caret in it or not (HOSTS' `untitled`:
|
|
310
|
+
// notion-lite's page title, data-ph 新页面); asked again on every move of the caret and every input,
|
|
311
|
+
// so an undo, a deletion across blocks and the workbench's renaming are followed too.
|
|
312
|
+
function untitled() {
|
|
313
|
+
if (!UNTITLED) return;
|
|
314
|
+
for (const host of document.querySelectorAll(UNTITLED)) {
|
|
315
|
+
if (!isHost(host)) continue;
|
|
316
|
+
if (isEmpty(host)) host.setAttribute("data-ge-placeholder", placeholderOf(host));
|
|
317
|
+
else if (host !== placeholder) host.removeAttribute("data-ge-placeholder");
|
|
318
|
+
}
|
|
263
319
|
}
|
|
264
320
|
|
|
265
321
|
return {
|
|
266
|
-
split, backspace, forwardDelete, autoSpace, updatePlaceholder,
|
|
322
|
+
split, backspace, forwardDelete, autoSpace, updatePlaceholder, untitled,
|
|
267
323
|
/** Tab (`back`: Shift+Tab). Whether the key was taken. */
|
|
268
324
|
tab: (host, back) => asked((keys) => keys.tab, host, back),
|
|
269
325
|
/** Ctrl+Enter. Whether the key was taken. */
|
|
@@ -15,7 +15,7 @@ import { BLOCK_TYPES, LEAVES_BY_ENTER, accepts } from "../../components/registry
|
|
|
15
15
|
// - A block of a type that says `resettable` (a quote's paragraph, a list item) turns into a
|
|
16
16
|
// paragraph where it stands, its container splitting around it (convert.mjs).
|
|
17
17
|
// Enter in a title that goes into its content (a disclosure, a card, a code block) is another rule
|
|
18
|
-
// (their components')
|
|
18
|
+
// (their components').
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* The empty last block of a box that says `leaveByEnter`, moved out after the box (the box goes if
|
|
@@ -55,6 +55,19 @@ export function button(label, action, { primary = false, ...props } = {}) {
|
|
|
55
55
|
return node;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* A text button in the editor's one button look (look.mjs BUTTONS, `.ge-btn`): no line, no fill, a gray
|
|
60
|
+
* under the pointer. `primary` the pale blue one (add, confirm, save; `data-primary`), `danger` with it the
|
|
61
|
+
* pale red (a delete), `quiet` a small one for looking, not deciding (`data-quiet`). A press on it leaves
|
|
62
|
+
* the selection where it is (button()).
|
|
63
|
+
*/
|
|
64
|
+
export function textButton(label, action, { primary = false, danger = false, quiet = false, class: own = "", ...props } = {}) {
|
|
65
|
+
const node = button(label, action, { primary, class: `ge-btn${own ? ` ${own}` : ""}`, ...props });
|
|
66
|
+
if (danger) node.dataset.danger = "";
|
|
67
|
+
if (quiet) node.dataset.quiet = "";
|
|
68
|
+
return node;
|
|
69
|
+
}
|
|
70
|
+
|
|
58
71
|
// Editor UI lives in the top layer with an open modal dialog, otherwise it would be inert.
|
|
59
72
|
export function layer() {
|
|
60
73
|
return document.querySelector(DIALOG.open) ?? document.body;
|
|
@@ -2,8 +2,8 @@ import { attr, hasClass } from "./html-tree.mjs";
|
|
|
2
2
|
import { BLOCK_ID, randomId } from "./ids.mjs";
|
|
3
3
|
|
|
4
4
|
// 批注 (docs/workbench.md "Annotations", docs/editor.md "Annotations"): the reader's suggestions for a
|
|
5
|
-
// local Agent, each about a piece of a report: words of its text, or blocks taken whole. One
|
|
6
|
-
//
|
|
5
|
+
// local Agent, each about a piece of a report: words of its text, or blocks taken whole. One has
|
|
6
|
+
// words: an item with none is none (cleanItem). Kept in reports/<slug>/annotations.json, never in report.html:
|
|
7
7
|
//
|
|
8
8
|
// { v: 1, items: [{ id, created, updated, text, anchor }] }
|
|
9
9
|
// anchor: { kind: "text", blocks: [data-block-id…], quote, prefix, suffix }
|
|
@@ -389,12 +389,13 @@ export function cleanAnchor(anchor) {
|
|
|
389
389
|
export const sameWords = (a, b) => Boolean(a && b) && a.kind === b.kind && (a.blocks ?? []).join() === (b.blocks ?? []).join() && squash(a.quote) === squash(b.quote)
|
|
390
390
|
&& squash(a.prefix).slice(-CONTEXT_KEPT) === squash(b.prefix).slice(-CONTEXT_KEPT) && squash(a.suffix).slice(0, CONTEXT_KEPT) === squash(b.suffix).slice(0, CONTEXT_KEPT);
|
|
391
391
|
|
|
392
|
-
/** An annotation as the file keeps it, from what was sent (`now`: when it is saved), or null when it is none. */
|
|
392
|
+
/** An annotation as the file keeps it, from what was sent (`now`: when it is saved), or null when it is none (no id, no anchor, no words). */
|
|
393
393
|
export function cleanItem(item, now = new Date().toISOString()) {
|
|
394
394
|
if (!item || typeof item !== "object" || typeof item.id !== "string" || !ID.test(item.id) || typeof item.text !== "string") return null;
|
|
395
395
|
const anchor = cleanAnchor(item.anchor);
|
|
396
396
|
if (!anchor) return null;
|
|
397
397
|
const text = item.text.replace(/\r\n?/g, "\n").slice(0, TEXT_MOST);
|
|
398
|
+
if (!text.trim()) return null;
|
|
398
399
|
return { id: item.id, created: typeof item.created === "string" ? item.created : now, updated: now, text, anchor };
|
|
399
400
|
}
|
|
400
401
|
|
|
@@ -421,7 +422,6 @@ export const itemsText = (items) => (items.length === 0 ? null : `${JSON.stringi
|
|
|
421
422
|
export const MARKDOWN_WORDS = {
|
|
422
423
|
head: "以下是我对这份文档的批注,共 {0} 条。请逐条按“建议”修改底稿;每条给出它在文档里的位置、块的 data-block-id 和批注的原文。",
|
|
423
424
|
headOne: "以下是我对这份文档的一条批注。请按“建议”修改底稿;它给出在文档里的位置、块的 data-block-id 和批注的原文。",
|
|
424
|
-
marks: "没有“建议”的批注只是标记了一个位置,不用改。",
|
|
425
425
|
report: "文档",
|
|
426
426
|
source: "底稿",
|
|
427
427
|
block: "块",
|
|
@@ -441,22 +441,20 @@ const fill = (text, ...values) => text.replace(/\{(\d+)\}/g, (whole, index) => (
|
|
|
441
441
|
* then each annotation in page order: where it is (`where`: the tab, the headings above it, the
|
|
442
442
|
* disclosure it is in; `top`: before the report's first heading, said 页首, which no tab or heading
|
|
443
443
|
* named 正文 is taken for), its blocks' ids (as the file has them), its quote and the suggestion, each
|
|
444
|
-
* of its lines a paragraph (blank lines in it make no more of them).
|
|
445
|
-
* place: it has no such line, and a line under the first says what such a one is.
|
|
444
|
+
* of its lines a paragraph (blank lines in it make no more of them).
|
|
446
445
|
* data: { title, path, items: [{ where: [text], top, blocks: [id], whole, quote, text }] }.
|
|
447
446
|
*/
|
|
448
447
|
export function annotationsMarkdown({ title, path, items }, words = MARKDOWN_WORDS) {
|
|
449
448
|
const w = { ...MARKDOWN_WORDS, ...words };
|
|
450
449
|
const head = items.length === 1 && w.headOne ? w.headOne : fill(w.head, items.length);
|
|
451
|
-
const
|
|
452
|
-
const lines = [head, ...(suggestions.some((said) => said.length === 0) ? [w.marks] : []), "", `- ${w.report}${w.colon}${title}`, `- ${w.source}${w.colon}${path}`];
|
|
450
|
+
const lines = [head, "", `- ${w.report}${w.colon}${title}`, `- ${w.source}${w.colon}${path}`];
|
|
453
451
|
items.forEach((item, index) => {
|
|
454
452
|
const where = item.where?.length ? item.where.join(" › ") : item.top ? w.top : w.body;
|
|
455
453
|
const ids = item.blocks?.length ? item.blocks.map((id) => `\`data-block-id="${id}"\``).join(w.comma) + (item.whole ? w.whole : "") : w.noId;
|
|
456
454
|
lines.push("", `## ${index + 1}. ${where}`, "", `${w.block}${w.colon}${ids}`, "");
|
|
457
455
|
for (const line of String(item.quote ?? "").split("\n")) lines.push(`> ${line}`);
|
|
458
|
-
const said =
|
|
459
|
-
|
|
456
|
+
const said = String(item.text ?? "").replace(/\r\n?/g, "\n").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
457
|
+
lines.push("", `${w.suggestion}${w.colon}${said[0] ?? ""}`);
|
|
460
458
|
for (const line of said.slice(1)) lines.push("", line);
|
|
461
459
|
});
|
|
462
460
|
return `${lines.join("\n")}\n`;
|