@heycys/gallery 0.1.1 → 0.2.0
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 +2 -2
- package/browser/editor/components/align.mjs +58 -0
- package/browser/editor/components/code/index.mjs +1 -1
- package/browser/editor/components/columns/page.mjs +4 -4
- package/browser/editor/components/embed/index.mjs +2 -2
- package/browser/editor/components/embed/page.mjs +1 -1
- package/browser/editor/components/file/page.mjs +4 -4
- 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 +7 -6
- package/browser/editor/components/icons.mjs +11 -0
- package/browser/editor/components/image/crop.mjs +6 -9
- package/browser/editor/components/image/index.mjs +2 -0
- package/browser/editor/components/image/page.mjs +172 -90
- package/browser/editor/components/installed/index.mjs +15 -4
- package/browser/editor/components/installed/page.mjs +103 -25
- package/browser/editor/components/installed/served.mjs +6 -5
- package/browser/editor/components/instances.mjs +18 -0
- package/browser/editor/components/list/page.mjs +3 -6
- package/browser/editor/components/media/icons.mjs +13 -8
- package/browser/editor/components/media/page.mjs +5 -3
- package/browser/editor/components/media/toolbar.mjs +12 -3
- package/browser/editor/components/paragraph/index.mjs +4 -3
- package/browser/editor/components/registry.mjs +30 -9
- package/browser/editor/components/table/index.mjs +61 -2
- package/browser/editor/components/table/page.mjs +1 -1
- package/browser/editor/page/after/index.mjs +288 -0
- package/browser/editor/page/align.mjs +91 -0
- package/browser/editor/page/annotate/card.mjs +3 -6
- package/browser/editor/page/autosave.mjs +310 -37
- package/browser/editor/page/beside.mjs +5 -6
- package/browser/editor/page/block-menu/index.mjs +6 -3
- package/browser/editor/page/blocks.mjs +3 -1
- package/browser/editor/page/board/client.mjs +57 -0
- package/browser/editor/page/board/hint.mjs +182 -0
- package/browser/editor/page/board/history.mjs +119 -0
- package/browser/editor/page/board/index.mjs +1059 -0
- package/browser/editor/page/board/motion.mjs +177 -0
- package/browser/editor/page/board/settings.mjs +210 -0
- package/browser/editor/page/caret.mjs +1 -1
- package/browser/editor/page/changes/bar.mjs +6 -14
- package/browser/editor/page/changes/index.mjs +2 -2
- 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 +133 -15
- package/browser/editor/page/clipboard/own/blocks.mjs +13 -14
- package/browser/editor/page/clipboard/own/chart-keys.mjs +41 -28
- package/browser/editor/page/clipboard/own/describe.mjs +6 -2
- package/browser/editor/page/clipboard/own/selection.mjs +1 -1
- package/browser/editor/page/columns/index.mjs +48 -46
- package/browser/editor/page/commit.mjs +80 -22
- package/browser/editor/page/conflicts.mjs +7 -7
- package/browser/editor/page/core.mjs +34 -16
- package/browser/editor/page/custom-page.mjs +110 -0
- package/browser/editor/page/editor.mjs +71 -17
- package/browser/editor/page/emoji-picker/styles.mjs +7 -12
- package/browser/editor/page/emoji-picker/upload.mjs +2 -2
- package/browser/editor/page/handle/index.mjs +5 -8
- package/browser/editor/page/history.mjs +41 -6
- package/browser/editor/page/insert/index.mjs +20 -22
- package/browser/editor/page/links/index.mjs +5 -3
- package/browser/editor/page/links/pages.mjs +27 -9
- package/browser/editor/page/look.mjs +54 -3
- package/browser/editor/page/margin.mjs +18 -3
- package/browser/editor/page/media-menu/index.mjs +6 -7
- package/browser/editor/page/menu.mjs +33 -14
- package/browser/editor/page/notices.mjs +2 -2
- package/browser/editor/page/page-objects.mjs +9 -2
- package/browser/editor/page/panel.mjs +4 -9
- package/browser/editor/page/present-links.mjs +15 -5
- package/browser/editor/page/present-shell.mjs +63 -0
- package/browser/editor/page/resize/index.mjs +42 -29
- package/browser/editor/page/selection/index.mjs +10 -2
- package/browser/editor/page/served.mjs +14 -0
- package/browser/editor/page/session.mjs +48 -4
- package/browser/editor/page/slash-menu/index.mjs +3 -3
- package/browser/editor/page/table/binding.mjs +87 -0
- package/browser/editor/page/table/cells.mjs +102 -46
- package/browser/editor/page/table/index.mjs +24 -9
- package/browser/editor/page/table/pictures.mjs +299 -0
- package/browser/editor/page/table/views.mjs +103 -0
- package/browser/editor/page/table/widths.mjs +82 -10
- package/browser/editor/page/text-select/index.mjs +26 -12
- package/browser/editor/page/todo-writes.mjs +75 -0
- package/browser/editor/page/typing/index.mjs +97 -15
- package/browser/editor/page/typing/leave.mjs +19 -5
- package/browser/editor/page/ui.mjs +13 -0
- package/browser/shared/block-packs.mjs +419 -0
- package/browser/shared/board-places.mjs +224 -0
- package/browser/shared/card-size.mjs +59 -0
- package/browser/shared/colors.mjs +3 -2
- package/browser/shared/component-catalog.mjs +330 -46
- package/browser/shared/component-source.mjs +39 -0
- package/browser/shared/components/heading.mjs +2 -1
- package/browser/shared/components/index.mjs +12 -3
- package/browser/shared/components/installed.mjs +35 -3
- package/browser/shared/components/page.mjs +20 -8
- package/browser/shared/components/paragraph.mjs +8 -1
- package/browser/shared/components/state.mjs +5 -1
- package/browser/shared/components/table.mjs +1 -0
- package/browser/shared/document-look.mjs +10 -5
- package/browser/shared/drafts.mjs +432 -0
- package/browser/shared/emoji/line-icons.mjs +37 -0
- 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/http.mjs +9 -0
- package/browser/shared/i18n/en.mjs +330 -27
- package/browser/shared/json-layout.mjs +47 -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/outline-shape.mjs +128 -0
- package/browser/shared/outline.mjs +359 -67
- package/browser/shared/pack-manifest.mjs +88 -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 +500 -0
- package/browser/shared/paths.mjs +6 -0
- package/browser/shared/pinyin.mjs +92 -0
- package/browser/shared/present-step.mjs +17 -0
- package/browser/shared/preview-server.mjs +3 -7
- package/browser/shared/session.mjs +8 -1
- package/browser/shared/shipped-blocks.mjs +299 -0
- package/browser/shared/sidebar-head.mjs +70 -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 +139 -0
- package/browser/shared/workspace-columns.mjs +120 -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/dist/chunk-2OHANJ6Q.mjs +2 -0
- package/dist/chunk-3MBRL2PM.mjs +16 -0
- package/dist/chunk-4OKWZY5E.mjs +2 -0
- package/dist/chunk-4OZWXZE5.mjs +5 -0
- package/dist/chunk-5K44HLTZ.mjs +2 -0
- package/dist/{chunk-5ZKJ3H4P.mjs → chunk-5XA2ZBAE.mjs} +3 -3
- package/dist/{chunk-4FS7Z7WR.mjs → chunk-67N2QJYT.mjs} +1 -1
- package/dist/chunk-6KBYRA2C.mjs +2 -0
- package/dist/chunk-6N3PX4XX.mjs +8 -0
- package/dist/{chunk-V5JTW2LH.mjs → chunk-6QBHU4DF.mjs} +1 -1
- package/dist/chunk-7JDX4E65.mjs +13 -0
- package/dist/chunk-7M2BQQGZ.mjs +2 -0
- package/dist/chunk-7OG26PGF.mjs +2 -0
- package/dist/chunk-AHN3NFKJ.mjs +3 -0
- package/dist/chunk-ALZ6ZENZ.mjs +3 -0
- package/dist/chunk-AR5D57ZD.mjs +170 -0
- package/dist/{chunk-W3BGBJQW.mjs → chunk-BFJGHSQN.mjs} +1 -1
- package/dist/{chunk-LS4F7JUM.mjs → chunk-BZ5RAF7L.mjs} +1 -1
- package/dist/chunk-CMA72MAG.mjs +2 -0
- package/dist/{chunk-LCTHTZIL.mjs → chunk-DAZL73VK.mjs} +91 -91
- package/dist/{chunk-Y6RLRPG3.mjs → chunk-DJISHPUL.mjs} +1 -1
- package/dist/chunk-DR73Y2UJ.mjs +3 -0
- package/dist/{chunk-FDLXYYG4.mjs → chunk-EAIFITAV.mjs} +1 -1
- package/dist/{chunk-TMYZB6AV.mjs → chunk-EKNHM3P4.mjs} +1 -1
- package/dist/chunk-EP25HDAJ.mjs +2 -0
- package/dist/{chunk-GB5SOYQJ.mjs → chunk-ERLAIBOA.mjs} +2 -2
- package/dist/chunk-EURLTOTZ.mjs +4 -0
- package/dist/chunk-F4ZA6JRZ.mjs +3 -0
- package/dist/chunk-F6HVDZR4.mjs +2 -0
- package/dist/chunk-FDMAXMQA.mjs +2 -0
- package/dist/chunk-FETSREUN.mjs +5 -0
- package/dist/chunk-GHOYKMQ3.mjs +4 -0
- package/dist/{chunk-2B5E4CDJ.mjs → chunk-GPIWQ4X4.mjs} +1 -1
- package/dist/chunk-HDWTZ763.mjs +12 -0
- package/dist/chunk-HPOI4ZX7.mjs +6 -0
- package/dist/{chunk-BGGDRNYQ.mjs → chunk-HXG7EOPJ.mjs} +1 -1
- package/dist/chunk-IA4PSIMD.mjs +2 -0
- package/dist/{chunk-E7LWZRXY.mjs → chunk-ITOH5EGO.mjs} +1 -1
- package/dist/chunk-IV64FFI4.mjs +2 -0
- package/dist/chunk-J43Z6LSS.mjs +2 -0
- package/dist/chunk-J5PUIV3Y.mjs +4 -0
- package/dist/chunk-JA7G53PC.mjs +2 -0
- package/dist/chunk-JEUK3ZO7.mjs +2 -0
- package/dist/chunk-JLTZF4LA.mjs +2 -0
- package/dist/chunk-JZT7I2OJ.mjs +2 -0
- package/dist/chunk-K5XATEOO.mjs +2 -0
- package/dist/chunk-L2SUIS5S.mjs +2 -0
- package/dist/chunk-L7UP52JO.mjs +2 -0
- package/dist/chunk-LM4XFQHZ.mjs +2 -0
- package/dist/chunk-MN7BZL4R.mjs +2 -0
- package/dist/chunk-MTYYHM2G.mjs +15 -0
- package/dist/chunk-MXUBKDRO.mjs +15 -0
- package/dist/chunk-NAMN3RAF.mjs +2 -0
- package/dist/{chunk-SYGN7GLU.mjs → chunk-OEXWRJME.mjs} +1 -1
- package/dist/chunk-OFHXGWOX.mjs +2 -0
- package/dist/chunk-ORID3AE7.mjs +166 -0
- package/dist/chunk-PAREWQGB.mjs +4 -0
- package/dist/chunk-PGDE24N5.mjs +2 -0
- package/dist/chunk-POTA2FV4.mjs +2 -0
- package/dist/chunk-PUOQ65NC.mjs +2 -0
- package/dist/chunk-Q4UEPUWF.mjs +2 -0
- package/dist/chunk-QE5RG76S.mjs +549 -0
- package/dist/chunk-R2ZDLJYT.mjs +10 -0
- package/dist/{chunk-7DTINW6U.mjs → chunk-SQ6Y2ZMA.mjs} +2 -2
- package/dist/chunk-SWUTTZCN.mjs +2 -0
- package/dist/chunk-TANZRINB.mjs +2 -0
- package/dist/chunk-TR7TWGHB.mjs +2 -0
- package/dist/chunk-U5XL7D6A.mjs +3 -0
- package/dist/{chunk-XNROSH2T.mjs → chunk-U7NZI6N4.mjs} +2 -2
- package/dist/chunk-UGWMMEJ5.mjs +15 -0
- package/dist/chunk-UJQJKNGK.mjs +2 -0
- package/dist/chunk-UYVCQK3H.mjs +22 -0
- package/dist/chunk-VFX2KNHP.mjs +4 -0
- package/dist/chunk-VS7JIGJW.mjs +24 -0
- package/dist/chunk-W7665ZEC.mjs +6 -0
- package/dist/chunk-WQDQWCX5.mjs +2 -0
- package/dist/chunk-YI43RG4P.mjs +2 -0
- package/dist/chunk-YLPSMDIS.mjs +5 -0
- package/dist/chunk-YNAWBAYN.mjs +3 -0
- package/dist/chunk-YROX2O22.mjs +2 -0
- package/dist/chunk-ZDLPUOAG.mjs +6 -0
- package/dist/{chunk-IVDLMMBD.mjs → chunk-ZHEHPMBK.mjs} +1 -1
- package/dist/chunk-ZQS6H473.mjs +16 -0
- package/dist/chunk-ZTHICSSF.mjs +2 -0
- package/dist/chunk-ZWWC4KLF.mjs +20 -0
- package/dist/cli.mjs +1 -1
- package/dist/server.mjs +1 -1
- package/dist/{chunk-U6KNPJPR.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 +17 -17
- package/kit/report.css +335 -18
- package/kit/runtime.js +1638 -125
- package/kit/state.js +10 -1
- package/kit/tables.js +130 -43
- package/kit/ui.js +79 -35
- 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 +216 -0
- package/packs/gallery/countdown/preview.svg +1 -0
- package/packs/gallery/countdown/style.css +118 -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 +334 -0
- package/packs/gallery/habit/preview.svg +1 -0
- package/packs/gallery/habit/style.css +174 -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 +513 -0
- package/packs/gallery/heatmap/preview.svg +1 -0
- package/packs/gallery/heatmap/style.css +189 -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 +129 -0
- package/packs/gallery/note/preview.svg +1 -0
- package/packs/gallery/note/style.css +97 -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 +293 -0
- package/packs/gallery/recent/preview.svg +1 -0
- package/packs/gallery/recent/style.css +85 -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 +171 -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 +347 -0
- package/packs/gallery/stats/preview.svg +1 -0
- package/packs/gallery/stats/style.css +73 -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 +220 -0
- package/packs/gallery/today/preview.svg +1 -0
- package/packs/gallery/today/style.css +149 -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 +489 -0
- package/packs/gallery/todos/preview.svg +1 -0
- package/packs/gallery/todos/style.css +214 -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 +387 -0
- package/packs/gallery/weather/preview.svg +1 -0
- package/packs/gallery/weather/style.css +140 -0
- package/packs/gallery/weather/template.html +3 -0
- package/packs/gallery/weather/writing.md +26 -0
- package/packs/gallery-soft/countdown/component.json +18 -0
- package/packs/gallery-soft/countdown/example.html +3 -0
- package/packs/gallery-soft/countdown/kit.js +206 -0
- package/packs/gallery-soft/countdown/preview.svg +1 -0
- package/packs/gallery-soft/countdown/style.css +211 -0
- package/packs/gallery-soft/countdown/template.html +3 -0
- package/packs/gallery-soft/countdown/writing.md +24 -0
- package/packs/gallery-soft/habit/component.json +14 -0
- package/packs/gallery-soft/habit/example.html +3 -0
- package/packs/gallery-soft/habit/kit.js +366 -0
- package/packs/gallery-soft/habit/preview.svg +1 -0
- package/packs/gallery-soft/habit/style.css +251 -0
- package/packs/gallery-soft/habit/template.html +3 -0
- package/packs/gallery-soft/habit/writing.md +23 -0
- package/packs/gallery-soft/heatmap/component.json +18 -0
- package/packs/gallery-soft/heatmap/example.html +3 -0
- package/packs/gallery-soft/heatmap/kit.js +498 -0
- package/packs/gallery-soft/heatmap/preview.svg +1 -0
- package/packs/gallery-soft/heatmap/style.css +181 -0
- package/packs/gallery-soft/heatmap/template.html +3 -0
- package/packs/gallery-soft/heatmap/writing.md +23 -0
- package/packs/gallery-soft/note/component.json +14 -0
- package/packs/gallery-soft/note/example.html +3 -0
- package/packs/gallery-soft/note/kit.js +162 -0
- package/packs/gallery-soft/note/preview.svg +1 -0
- package/packs/gallery-soft/note/style.css +148 -0
- package/packs/gallery-soft/note/template.html +3 -0
- package/packs/gallery-soft/note/writing.md +20 -0
- package/packs/gallery-soft/pack.json +8 -0
- package/packs/gallery-soft/recent/component.json +13 -0
- package/packs/gallery-soft/recent/example.html +1 -0
- package/packs/gallery-soft/recent/kit.js +335 -0
- package/packs/gallery-soft/recent/preview.svg +1 -0
- package/packs/gallery-soft/recent/style.css +160 -0
- package/packs/gallery-soft/recent/template.html +1 -0
- package/packs/gallery-soft/recent/writing.md +17 -0
- package/packs/gallery-soft/static/component.json +13 -0
- package/packs/gallery-soft/static/example.html +12 -0
- package/packs/gallery-soft/static/preview.svg +1 -0
- package/packs/gallery-soft/static/style.css +186 -0
- package/packs/gallery-soft/static/template.html +1 -0
- package/packs/gallery-soft/static/writing.md +20 -0
- package/packs/gallery-soft/stats/component.json +13 -0
- package/packs/gallery-soft/stats/example.html +1 -0
- package/packs/gallery-soft/stats/kit.js +341 -0
- package/packs/gallery-soft/stats/preview.svg +1 -0
- package/packs/gallery-soft/stats/style.css +119 -0
- package/packs/gallery-soft/stats/template.html +1 -0
- package/packs/gallery-soft/stats/writing.md +13 -0
- package/packs/gallery-soft/today/component.json +12 -0
- package/packs/gallery-soft/today/example.html +1 -0
- package/packs/gallery-soft/today/kit.js +222 -0
- package/packs/gallery-soft/today/preview.svg +1 -0
- package/packs/gallery-soft/today/style.css +178 -0
- package/packs/gallery-soft/today/template.html +1 -0
- package/packs/gallery-soft/today/writing.md +16 -0
- package/packs/gallery-soft/todos/component.json +19 -0
- package/packs/gallery-soft/todos/example.html +3 -0
- package/packs/gallery-soft/todos/kit.js +527 -0
- package/packs/gallery-soft/todos/preview.svg +1 -0
- package/packs/gallery-soft/todos/style.css +212 -0
- package/packs/gallery-soft/todos/template.html +3 -0
- package/packs/gallery-soft/todos/writing.md +32 -0
- package/packs/gallery-soft/weather/component.json +19 -0
- package/packs/gallery-soft/weather/example.html +3 -0
- package/packs/gallery-soft/weather/kit.js +411 -0
- package/packs/gallery-soft/weather/preview.svg +1 -0
- package/packs/gallery-soft/weather/style.css +185 -0
- package/packs/gallery-soft/weather/template.html +3 -0
- package/packs/gallery-soft/weather/writing.md +28 -0
- package/release.json +12 -10
- package/sdk/doc-kit.d.ts +396 -5
- package/sdk/doc-state.d.ts +2 -0
- package/skill/SKILL.md +56 -23
- package/skill/references/block-script.md +140 -0
- package/skill/references/building-blocks.md +257 -0
- package/skill/references/extensions.md +59 -0
- package/skill/references/pages-and-data.md +225 -0
- package/skill/references/writing-html.md +8 -4
- package/skill/sdk/doc-kit.d.ts +396 -5
- package/skill/sdk/doc-state.d.ts +2 -0
- package/web/assets/index-BM_K-Auu.css +1 -0
- package/web/assets/index-DRslOBiv.js +15 -0
- package/web/index.html +2 -2
- package/dist/chunk-3HIRPVLU.mjs +0 -2
- package/dist/chunk-5MHMDLZD.mjs +0 -4
- package/dist/chunk-64K7IPLO.mjs +0 -255
- package/dist/chunk-6QXGZM36.mjs +0 -8
- package/dist/chunk-6RGJOMJP.mjs +0 -16
- package/dist/chunk-AJ73XJF3.mjs +0 -2
- package/dist/chunk-AUZGSZJH.mjs +0 -13
- package/dist/chunk-BFE45AKL.mjs +0 -2
- package/dist/chunk-BXO2ZY5P.mjs +0 -2
- package/dist/chunk-CEH4MRCC.mjs +0 -2
- package/dist/chunk-CY2FNNAB.mjs +0 -16
- package/dist/chunk-DFUDV4LX.mjs +0 -2
- package/dist/chunk-DKXG4XDG.mjs +0 -2
- package/dist/chunk-EZQ34M3F.mjs +0 -124
- package/dist/chunk-EZY3WC6Z.mjs +0 -15
- package/dist/chunk-FUKQNOQS.mjs +0 -9
- package/dist/chunk-JPOSLGOC.mjs +0 -6
- package/dist/chunk-JVHHHGEA.mjs +0 -3
- package/dist/chunk-L3QKH4OK.mjs +0 -26
- package/dist/chunk-LAE5NQ4B.mjs +0 -2
- package/dist/chunk-LEF6DRCK.mjs +0 -59
- package/dist/chunk-NO5NJCHO.mjs +0 -2
- package/dist/chunk-NQPVAU63.mjs +0 -2
- package/dist/chunk-NSKUTQ5J.mjs +0 -5
- package/dist/chunk-O35FIXRB.mjs +0 -2
- package/dist/chunk-P2CAZPDP.mjs +0 -3
- package/dist/chunk-PL6GHLGD.mjs +0 -15
- package/dist/chunk-QJIR2BLP.mjs +0 -6
- package/dist/chunk-QUPLVPB2.mjs +0 -7
- package/dist/chunk-R7BNENLY.mjs +0 -4
- package/dist/chunk-S6O4UHLC.mjs +0 -2
- package/dist/chunk-SGJWQKEI.mjs +0 -2
- package/dist/chunk-TX6JH7TR.mjs +0 -2
- package/dist/chunk-TYK6VNAB.mjs +0 -10
- package/dist/chunk-UALRNVSE.mjs +0 -4
- package/dist/chunk-V3HXVQEM.mjs +0 -2
- package/dist/chunk-V5VXUJKG.mjs +0 -2
- package/dist/chunk-VBXMADMP.mjs +0 -2
- package/dist/chunk-VNV55RUA.mjs +0 -2
- package/dist/chunk-VPD2PS35.mjs +0 -2
- package/dist/chunk-W4VKN3GF.mjs +0 -7
- package/dist/chunk-W5BXXPDJ.mjs +0 -3
- package/dist/chunk-XUNHRCOG.mjs +0 -6
- package/skill/references/building-components.md +0 -367
- package/web/assets/index-Bh74DfsV.css +0 -1
- package/web/assets/index-UW0RyFFt.js +0 -13
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { pageLink, pageOfLink } from "./page-links.mjs";
|
|
1
|
+
import { earlierLink, pageLink, pageOfLink } from "./page-links.mjs";
|
|
2
2
|
|
|
3
3
|
// A document's address, as a link, a paste or the address bar may write it (docs/workbench.md, "A
|
|
4
4
|
// document's addresses"), read in one place: { slug, block }, block null for the page itself. Pure: the
|
|
@@ -19,7 +19,8 @@ import { pageLink, pageOfLink } from "./page-links.mjs";
|
|
|
19
19
|
// which has the list. pageAddress reads no port, as a link outlives a server; but this computer runs
|
|
20
20
|
// other programs too, and other workspaces, whose folder of one name has one page id, so an address
|
|
21
21
|
// on another port (elsewhere) is a document's only if the list holds it, by its folder name or its
|
|
22
|
-
// link of now (addressOn)
|
|
22
|
+
// link of now (addressOn), or for a folder named doc- and eight characters, the link it had before
|
|
23
|
+
// those eight were its id (shared/page-links.mjs earlierId).
|
|
23
24
|
|
|
24
25
|
const SLUG = "[a-z0-9]+(?:-[a-z0-9]+)*"; // shared/workspace.mjs slugPattern, which needs Node
|
|
25
26
|
const FILE = "(?:doc|report)\\.html";
|
|
@@ -96,7 +97,9 @@ export function workbenchHash(text) {
|
|
|
96
97
|
export function addressOn(text, links, origin = "http://127.0.0.1") {
|
|
97
98
|
const place = pageAddress(text, links);
|
|
98
99
|
const name = place && elsewhere(text, origin) ? workbenchHash(text)?.split("/")[0] : undefined;
|
|
99
|
-
|
|
100
|
+
if (name === undefined || links.has(name)) return place;
|
|
101
|
+
const link = links.get(place.slug);
|
|
102
|
+
return link === name || earlierLink(place.slug, link) === name ? place : null;
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
/** Whether `text` is an address of a document of this workspace, as far as can be told with no list. */
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { parse } from "parse5";
|
|
3
|
+
import { cellsOf } from "./card-size.mjs";
|
|
4
|
+
import { escapeAttribute } from "./escape.mjs";
|
|
5
|
+
import { attr, elementsOf, hasClass, walk } from "./html-tree.mjs";
|
|
6
|
+
import { ATTRIBUTE } from "./components/installed.mjs";
|
|
7
|
+
|
|
8
|
+
// The cards of a custom page's page.html as the server reads and writes them (the spec
|
|
9
|
+
// notes/plans/custom-blocks-spec-2026-11-07.md §5, §8; docs/render.md "A custom page"): its boards
|
|
10
|
+
// (div.gallery-board, data-board-id), each card a direct child of one (.gallery-card, data-card-id,
|
|
11
|
+
// data-x, data-y, data-w, data-h) around one instance of a custom block. What the page service
|
|
12
|
+
// (src/editor/page-service.mjs), gallery page add and the page as it is served (src/server/routes.mjs)
|
|
13
|
+
// read of a page, and the text they write: every change is a splice of the file's own text (an
|
|
14
|
+
// attribute's value, a card put in or taken out), every other byte staying, as a document's commits
|
|
15
|
+
// write. A card's id is what everything goes by: one that has none (or one that is no id, or one a
|
|
16
|
+
// card before it took) is given the lowest c<n> no card holds, in the file's order, the same ids
|
|
17
|
+
// however often it is read, so that the page shows a card by the id its first write gives it. A card's
|
|
18
|
+
// base (what a write to it is held to, the spec §8) is a hash of its markup, its frame's attributes and
|
|
19
|
+
// its instance, once those ids are in. Node's (parse5), the server's and the command line's.
|
|
20
|
+
|
|
21
|
+
/** What a card's id and a board's may be (the spec §5). */
|
|
22
|
+
export const CARD_ID_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The attributes the author of a custom page writes on its boards and cards (the spec §5): the page's
|
|
26
|
+
* own, which no document's component describes (tests/unit/components.mjs takes them as known names).
|
|
27
|
+
*/
|
|
28
|
+
export const PAGE_ATTRIBUTES = Object.freeze(["data-board-id", "data-card-id", "data-x", "data-y", "data-w", "data-h"]);
|
|
29
|
+
|
|
30
|
+
const BOARD_CLASS = "gallery-board";
|
|
31
|
+
const CARD_CLASS = "gallery-card";
|
|
32
|
+
const isInstanceNode = (node) => (node.tagName === "div" || node.tagName === "section") && attr(node, ATTRIBUTE) !== undefined;
|
|
33
|
+
|
|
34
|
+
/** A hash of `text` as the page service names a version of a card by: 16 hex digits, line endings as \n. */
|
|
35
|
+
export const hashOf = (text) => createHash("sha256").update(text.replace(/\r\n?/g, "\n")).digest("hex").slice(0, 16);
|
|
36
|
+
|
|
37
|
+
const parsed = (text) => parse(text.replace(/^/, " "), { sourceCodeLocationInfo: true });
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* What page.html `text` holds: { boards: [{ id, node, cards }], cards } where each card is { id (as
|
|
41
|
+
* written: null where it has none), node, board (its board's id, or null), x, y, w, h (the cells the
|
|
42
|
+
* board draws it at: card-size.mjs cellsOf), instance (the instance it holds, or null), block (its
|
|
43
|
+
* block's id, or null), start, end (its place in the text), closed (written with its own end tag) }.
|
|
44
|
+
* A card is a board's child; a board is any element of the class, its cards in the file's order.
|
|
45
|
+
*/
|
|
46
|
+
export function readPage(text) {
|
|
47
|
+
const boards = [];
|
|
48
|
+
walk(parsed(text), (node) => {
|
|
49
|
+
if (!hasClass(node, BOARD_CLASS)) return;
|
|
50
|
+
const cards = elementsOf(node).filter((child) => hasClass(child, CARD_CLASS) && child.sourceCodeLocation).map((child) => {
|
|
51
|
+
let instance = elementsOf(child).find(isInstanceNode) ?? null;
|
|
52
|
+
if (!instance) walk(child, (inner) => { instance ??= isInstanceNode(inner) ? inner : null; });
|
|
53
|
+
const place = child.sourceCodeLocation;
|
|
54
|
+
const dataset = { x: attr(child, "data-x"), y: attr(child, "data-y"), w: attr(child, "data-w"), h: attr(child, "data-h") };
|
|
55
|
+
return {
|
|
56
|
+
id: attr(child, "data-card-id") ?? null, node: child, board: attr(node, "data-board-id") ?? null, ...cellsOf({ dataset }),
|
|
57
|
+
instance, block: instance ? attr(instance, ATTRIBUTE) : null, start: place.startOffset, end: place.endOffset, closed: Boolean(place.endTag),
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
boards.push({ id: attr(node, "data-board-id") ?? null, node, cards });
|
|
61
|
+
}, { inTemplates: false });
|
|
62
|
+
return { boards, cards: boards.flatMap((board) => board.cards) };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The ids the cards of a page go by, in the file's order: each its own where it is an id no card before it took, else the lowest c<n> none holds. */
|
|
66
|
+
export function cardIds(cards) {
|
|
67
|
+
const held = new Set(cards.map(({ id }) => id).filter((id) => typeof id === "string" && CARD_ID_PATTERN.test(id)));
|
|
68
|
+
const taken = new Set();
|
|
69
|
+
let next = 1;
|
|
70
|
+
return cards.map(({ id }) => {
|
|
71
|
+
if (typeof id === "string" && CARD_ID_PATTERN.test(id) && !taken.has(id)) {
|
|
72
|
+
taken.add(id);
|
|
73
|
+
return id;
|
|
74
|
+
}
|
|
75
|
+
while (held.has(`c${next}`) || taken.has(`c${next}`)) next++;
|
|
76
|
+
const made = `c${next}`;
|
|
77
|
+
taken.add(made);
|
|
78
|
+
return made;
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** The lowest c<n> none of `ids` is. */
|
|
83
|
+
export function freeCardId(ids) {
|
|
84
|
+
const held = new Set(ids);
|
|
85
|
+
let n = 1;
|
|
86
|
+
while (held.has(`c${n}`)) n++;
|
|
87
|
+
return `c${n}`;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// The splices that set an element's attributes (`values`: name -> value, null to take one off),
|
|
91
|
+
// [{ start, end, text }]: an attribute there gets its value written anew, in double quotes; one not
|
|
92
|
+
// there goes in after its class (or its tag's name), in the order given.
|
|
93
|
+
function attributeSplices(text, node, values) {
|
|
94
|
+
const { startTag } = node.sourceCodeLocation;
|
|
95
|
+
const places = startTag.attrs ?? {};
|
|
96
|
+
const splices = [];
|
|
97
|
+
const fresh = [];
|
|
98
|
+
for (const [name, value] of Object.entries(values)) {
|
|
99
|
+
const place = places[name];
|
|
100
|
+
if (place) {
|
|
101
|
+
splices.push({ start: place.startOffset, end: place.endOffset, text: value === null ? "" : `${name}="${escapeAttribute(String(value))}"` });
|
|
102
|
+
if (value === null && text[place.startOffset - 1] === " ") splices.at(-1).start -= 1;
|
|
103
|
+
} else if (value !== null) fresh.push(` ${name}="${escapeAttribute(String(value))}"`);
|
|
104
|
+
}
|
|
105
|
+
if (fresh.length) {
|
|
106
|
+
const at = places.class?.endOffset ?? startTag.startOffset + 1 + node.tagName.length;
|
|
107
|
+
splices.push({ start: at, end: at, text: fresh.join("") });
|
|
108
|
+
}
|
|
109
|
+
return splices;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** `text` with `splices` ([{ start, end, text }], none overlapping) made, from the last on. */
|
|
113
|
+
export function spliced(text, splices) {
|
|
114
|
+
return [...splices].sort((a, b) => b.start - a.start || b.end - a.end).reduce((out, { start, end, text: put }) => out.slice(0, start) + put + out.slice(end), text);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Page.html `text` with every card given an id (cardIds): { text, filled: the ids given, by the
|
|
119
|
+
* cards' order }. The same text when each has its own.
|
|
120
|
+
*/
|
|
121
|
+
export function withCardIds(text) {
|
|
122
|
+
const { cards } = readPage(text);
|
|
123
|
+
const ids = cardIds(cards);
|
|
124
|
+
const splices = cards.flatMap((card, index) => (card.id === ids[index] ? [] : attributeSplices(text, card.node, { "data-card-id": ids[index] })));
|
|
125
|
+
return { text: splices.length ? spliced(text, splices) : text, filled: cards.flatMap((card, index) => (card.id === ids[index] ? [] : [ids[index]])) };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** A card's base: the hash of its markup as `text` writes it (its frame's attributes and its instance). */
|
|
129
|
+
export const baseOf = (text, card) => hashOf(text.slice(card.start, card.end));
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The cards of page.html `text` as the page service answers with them, once every card has its id
|
|
133
|
+
* (withCardIds; `text` already so when it was written): [{ id, board, x, y, w, h, base, block }].
|
|
134
|
+
*/
|
|
135
|
+
export function cardsOf(text) {
|
|
136
|
+
const own = withCardIds(text).text;
|
|
137
|
+
return readPage(own).cards.map((card) => ({ id: card.id, board: card.board, x: card.x, y: card.y, w: card.w, h: card.h, base: baseOf(own, card), block: card.block }));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// A card's place as page.html writes it: its board, then its data-x, -y, -w and -h as written.
|
|
141
|
+
const placeWritten = (card) => [card.board, ...["x", "y", "w", "h"].map((axis) => attr(card.node, `data-${axis}`))].join(",");
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* A card's markup in `text` without its place (the data-x, -y, -w and -h of its start tag): what tells
|
|
145
|
+
* a change of its own (its frame's other attributes, its instance) from a move.
|
|
146
|
+
*/
|
|
147
|
+
export function unplacedOf(text, card) {
|
|
148
|
+
const end = card.node.sourceCodeLocation.startTag.endOffset;
|
|
149
|
+
return text.slice(card.start, end).replace(/\s+data-[xywh]="[^"]*"/g, "") + text.slice(end, card.end);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* The cards page.html `after` changed of `before`, each by the id the page service gives it
|
|
154
|
+
* (withCardIds): { <id>: kinds }, a kind "added", "removed", "cells" (another board, or its data-x, -y,
|
|
155
|
+
* -w or -h as written: placeWritten) or "content" (its markup but its place: unplacedOf); a card that
|
|
156
|
+
* did not change is none of it. What the page service tells of each write (its writes.jsonl).
|
|
157
|
+
*/
|
|
158
|
+
export function cardsChanged(before, after) {
|
|
159
|
+
const [was, now] = [withCardIds(before).text, withCardIds(after).text];
|
|
160
|
+
const [a, b] = [readPage(was).cards, readPage(now).cards];
|
|
161
|
+
const changed = {};
|
|
162
|
+
for (const card of a) if (!b.some((one) => one.id === card.id)) changed[card.id] = ["removed"];
|
|
163
|
+
for (const card of b) {
|
|
164
|
+
const old = a.find((one) => one.id === card.id);
|
|
165
|
+
if (!old) {
|
|
166
|
+
changed[card.id] = ["added"];
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
const kinds = [...(placeWritten(old) !== placeWritten(card) ? ["cells"] : []), ...(unplacedOf(was, old) !== unplacedOf(now, card) ? ["content"] : [])];
|
|
170
|
+
if (kinds.length) changed[card.id] = kinds;
|
|
171
|
+
}
|
|
172
|
+
return changed;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** `text` (every card with its id) with each card `cells` names (id -> { x, y, w, h }) at those cells: its data-x, -y, -w and -h written. */
|
|
176
|
+
export function withCells(text, cells) {
|
|
177
|
+
const { cards } = readPage(text);
|
|
178
|
+
const splices = cards.flatMap((card) => {
|
|
179
|
+
const to = cells.get(card.id);
|
|
180
|
+
if (!to) return [];
|
|
181
|
+
const values = {};
|
|
182
|
+
for (const axis of ["x", "y", "w", "h"]) if (to[axis] !== undefined && attr(card.node, `data-${axis}`) !== String(to[axis])) values[`data-${axis}`] = to[axis];
|
|
183
|
+
return Object.keys(values).length ? attributeSplices(text, card.node, values) : [];
|
|
184
|
+
});
|
|
185
|
+
return splices.length ? spliced(text, splices) : text;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Where a card's markup stands with what goes with it: its whole line, its line break with it (the
|
|
189
|
+
// file's last line to the end of the text), when only blanks stand before and after it there; else the
|
|
190
|
+
// markup alone, whatever shares its line with it staying where it is, its indent too (a page written on
|
|
191
|
+
// one line: the cards after it and the closing tags).
|
|
192
|
+
function lineOf(text, start, end) {
|
|
193
|
+
const before = text.lastIndexOf("\n", start - 1) + 1;
|
|
194
|
+
const after = text.indexOf("\n", end);
|
|
195
|
+
const rest = after === -1 ? text.slice(end) : text.slice(end, after);
|
|
196
|
+
if (!/^[ \t]*$/.test(text.slice(before, start)) || !/^[ \t\r]*$/.test(rest)) return { from: start, to: end };
|
|
197
|
+
return { from: before, to: after === -1 ? text.length : after + 1 };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** `text` with card `id` taken out, and the card as it was written: { text, html }, or null when no card has that id. */
|
|
201
|
+
export function withoutCard(text, id) {
|
|
202
|
+
const card = readPage(text).cards.find((one) => one.id === id);
|
|
203
|
+
if (!card) return null;
|
|
204
|
+
const { from, to } = lineOf(text, card.start, card.end);
|
|
205
|
+
return { text: text.slice(0, from) + text.slice(to), html: text.slice(card.start, card.end) };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// The blanks a line of `text` starts with, at `offset`.
|
|
209
|
+
const indentAt = (text, offset) => /^[ \t]*/.exec(text.slice(text.lastIndexOf("\n", offset - 1) + 1))[0];
|
|
210
|
+
|
|
211
|
+
/** `markup` with each line after its first taken `by` further in. */
|
|
212
|
+
const indented = (markup, by) => markup.replace(/\r?\n/g, (eol) => `${eol}${by}`);
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* The markup of a new card: `<section class="gallery-card" data-card-id data-x data-y data-w data-h>`
|
|
216
|
+
* around `instance` (one instance's markup, as a block's template is), at `indent` (its first line's
|
|
217
|
+
* blanks, which the text it goes in gives), the instance two spaces further in.
|
|
218
|
+
*/
|
|
219
|
+
export function cardMarkup({ id, x, y, w, h }, instance, indent = "", eol = "\n") {
|
|
220
|
+
const open = `<section class="${CARD_CLASS}" data-card-id="${escapeAttribute(id)}" data-x="${x}" data-y="${y}" data-w="${w}" data-h="${h}">`;
|
|
221
|
+
return `${open}${eol}${indent} ${indented(instance.trim().replace(/\r?\n/g, eol), `${indent} `)}${eol}${indent}</section>`;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* `text` with the card `markup` (cardMarkup's, or a card as withoutCard gave it) put last in board
|
|
226
|
+
* `board` (its data-board-id), on a line of its own, as far in as its cards are (two spaces further in
|
|
227
|
+
* than the board where it has none): { text, start } (where the card starts), or null when no board
|
|
228
|
+
* has that id. `markup` that starts at an indent of its own is put back at the board's.
|
|
229
|
+
*/
|
|
230
|
+
export function withCard(text, board, markup) {
|
|
231
|
+
const found = readPage(text).boards.find((one) => one.id === board);
|
|
232
|
+
if (!found) return null;
|
|
233
|
+
const { node } = found;
|
|
234
|
+
const place = node.sourceCodeLocation;
|
|
235
|
+
const eol = text.includes("\r\n") ? "\r\n" : "\n";
|
|
236
|
+
const last = found.cards.at(-1);
|
|
237
|
+
const indent = last ? indentAt(text, last.start) : `${indentAt(text, place.startOffset)} `;
|
|
238
|
+
// The indent the card's markup stood at (its end tag's line, what withoutCard leaves of it), each of its
|
|
239
|
+
// lines moved from there to this board's: none where the two are one, so that a card put back where it
|
|
240
|
+
// was is its old text again, byte for byte.
|
|
241
|
+
const from = markup.match(/\n([ \t]*)<\/[a-z]+>\s*$/)?.[1] ?? "";
|
|
242
|
+
const body = markup.trim().replace(/\r?\n/g, "\n").split("\n").map((line, index) => (index === 0 || from === indent ? line : line.startsWith(from) ? `${indent}${line.slice(from.length)}` : line)).join(eol);
|
|
243
|
+
if (place.endTag) {
|
|
244
|
+
const close = place.endTag.startOffset;
|
|
245
|
+
const lineStart = text.lastIndexOf("\n", close - 1) + 1;
|
|
246
|
+
const onOwnLine = /^[ \t]*$/.test(text.slice(lineStart, close));
|
|
247
|
+
const at = onOwnLine ? lineStart : close;
|
|
248
|
+
const put = `${onOwnLine ? "" : eol}${indent}${body}${eol}`;
|
|
249
|
+
return { text: text.slice(0, at) + put + text.slice(at), start: at + put.indexOf(body) };
|
|
250
|
+
}
|
|
251
|
+
const at = place.endOffset;
|
|
252
|
+
const put = `${eol}${indent}${body}`;
|
|
253
|
+
return { text: text.slice(0, at) + put + text.slice(at), start: at + put.indexOf(body) };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Page.html `text` as it is served (src/server/routes.mjs): every card with its id (withCardIds), and
|
|
258
|
+
* on each card what the page's board reads of it and no file holds (all data-ge-*, which nothing writes
|
|
259
|
+
* back): `data-ge-base`, its base; and by what `blockOf(id)` says of its block ({ fit, bare, runs }, or
|
|
260
|
+
* null for one there is none of), `data-ge-fit="content"`, `data-ge-bare`, and `data-ge-state`
|
|
261
|
+
* (`document`: a block whose places lack page; `disabled`: turned off; `missing`: none there) with its
|
|
262
|
+
* instance put in a <template> (`data-ge-held`) where the block does not run on the page, so that no
|
|
263
|
+
* script starts it and the board shows a note instead.
|
|
264
|
+
*/
|
|
265
|
+
export function servedPage(text, { blockOf = () => null } = {}) {
|
|
266
|
+
const own = withCardIds(text).text;
|
|
267
|
+
const splices = [];
|
|
268
|
+
for (const card of readPage(own).cards) {
|
|
269
|
+
const block = card.block ? blockOf(card.block) : null;
|
|
270
|
+
const values = { "data-ge-base": baseOf(own, card) };
|
|
271
|
+
if (block?.fit === "content") values["data-ge-fit"] = "content";
|
|
272
|
+
if (block?.bare) values["data-ge-bare"] = "";
|
|
273
|
+
const state = card.block === null ? null : block?.state ?? "missing";
|
|
274
|
+
if (state && state !== "page") values["data-ge-state"] = state;
|
|
275
|
+
splices.push(...attributeSplices(own, card.node, values));
|
|
276
|
+
if (card.instance && block && state !== "page" && state !== "missing") {
|
|
277
|
+
const { startOffset, endOffset } = card.instance.sourceCodeLocation;
|
|
278
|
+
splices.push({ start: startOffset, end: startOffset, text: "<template data-ge-held>" }, { start: endOffset, end: endOffset, text: "</template>" });
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return spliced(own, splices);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
// A card's markup read on a board of its own: { text, card, from, to } (where the markup is in the text).
|
|
285
|
+
function alone(markup) {
|
|
286
|
+
const before = `<!doctype html><html><head></head><body><div class="${BOARD_CLASS}">`;
|
|
287
|
+
const text = `${before}${markup}</div></body></html>`;
|
|
288
|
+
const [board] = readPage(text).boards;
|
|
289
|
+
return { text, board, from: before.length, to: before.length + markup.length };
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** Whether `markup` reads as one card and nothing else (a comment aside), closed by its own end tag, holding one instance of a block: its card, or null. */
|
|
293
|
+
export function oneCard(markup) {
|
|
294
|
+
const { board } = alone(markup);
|
|
295
|
+
if (!board || board.cards.length !== 1) return null;
|
|
296
|
+
const strays = elementsOf(board.node).length !== 1 || board.node.childNodes.some((node) => node.nodeName === "#text" && node.value.trim());
|
|
297
|
+
const [card] = board.cards;
|
|
298
|
+
return strays || !card.closed || !card.instance || card.instance.parentNode !== card.node ? null : card;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/** A card's `markup` (oneCard's) with its id and cells set: { id, x, y, w, h }. */
|
|
302
|
+
export function cardWith(markup, { id, x, y, w, h }) {
|
|
303
|
+
const { text, board, from, to } = alone(markup);
|
|
304
|
+
const values = { "data-card-id": id, "data-x": x, "data-y": y, "data-w": w, "data-h": h };
|
|
305
|
+
const splices = attributeSplices(text, board.cards[0].node, values);
|
|
306
|
+
const grown = splices.reduce((sum, { start, end, text: put }) => sum + put.length - (end - start), 0);
|
|
307
|
+
return spliced(text, splices).slice(from, to + grown);
|
|
308
|
+
}
|
|
@@ -5,8 +5,14 @@
|
|
|
5
5
|
// one title need nothing to tell them apart.
|
|
6
6
|
//
|
|
7
7
|
// A page id has the look of a block id (shared/ids.mjs) and is worked out from the folder name, the
|
|
8
|
-
// document's identity, which a title never changes
|
|
9
|
-
//
|
|
8
|
+
// document's identity, which a title never changes: a hash of the name, but for a name of the shape
|
|
9
|
+
// doc-<eight> (DOC_SLUG), which has those eight as its id. The workbench names a new document so
|
|
10
|
+
// (shared/workspace.mjs newDocSlug: doc- and a random id no name of the workspace has), so that the
|
|
11
|
+
// folder and the address read alike (doc-tacti90g, #反馈文档-tacti90g); every name made before has the
|
|
12
|
+
// id it had, but for one of that very shape (an Agent's slug may be doc-overview), which keeps the
|
|
13
|
+
// address it had besides: its hash opens it too (earlierId, pageOfLink). So nothing is kept anywhere:
|
|
14
|
+
// no file, no list to keep in step, and a page alone in a tab or with no list read yet can always say
|
|
15
|
+
// its own address.
|
|
10
16
|
// The folder name opens its document too, for what was written by it. A document in the trash has its
|
|
11
17
|
// id, and has its address back when it is restored; one restored under another folder name goes by
|
|
12
18
|
// that name's id, as the links of files to it change too.
|
|
@@ -19,11 +25,17 @@
|
|
|
19
25
|
const NOT_WORDS = /(?:[^\p{L}\p{M}\p{N}_]\p{M}*)+/gu;
|
|
20
26
|
|
|
21
27
|
/**
|
|
22
|
-
* A
|
|
23
|
-
*
|
|
28
|
+
* A folder name that is a page id's own: "doc-" and the eight characters of an id, a lowercase letter
|
|
29
|
+
* first and lowercase letters or digits after it. Its group is the id (pageId).
|
|
30
|
+
*/
|
|
31
|
+
export const DOC_SLUG = /^doc-([a-z][a-z0-9]{7})$/;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The id a name has from a 53-bit hash of it (cyrb53): eight letters and digits, a letter first. Every
|
|
35
|
+
* name had it before the folders of the shape DOC_SLUG had their own (pageId, earlierId).
|
|
24
36
|
* @param {string} slug
|
|
25
37
|
*/
|
|
26
|
-
|
|
38
|
+
function hashId(slug) {
|
|
27
39
|
let one = 0xdeadbeef;
|
|
28
40
|
let two = 0x41c6ce57;
|
|
29
41
|
for (let at = 0; at < slug.length; at++) {
|
|
@@ -36,6 +48,40 @@ export function pageId(slug) {
|
|
|
36
48
|
return String.fromCharCode(97 + hash % 26) + Math.floor(hash / 26).toString(36).padStart(7, "0").slice(-7);
|
|
37
49
|
}
|
|
38
50
|
|
|
51
|
+
/**
|
|
52
|
+
* A document's page id: eight letters and digits, a letter first. A folder named doc-<eight> (DOC_SLUG)
|
|
53
|
+
* has those eight; any other name, a hash of it. So only a name of that one shape reads otherwise than
|
|
54
|
+
* it did, and it keeps the address it had besides (earlierId).
|
|
55
|
+
* @param {string} slug
|
|
56
|
+
*/
|
|
57
|
+
export const pageId = (slug) => DOC_SLUG.exec(slug)?.[1] ?? hashId(slug);
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The id a name of the shape DOC_SLUG went by before its own eight were its id, its hash, or null for
|
|
61
|
+
* any other name, whose id has not changed. An Agent's slug may have that shape (doc-overview was
|
|
62
|
+
* #Overview-f3md3kg4 before), and an address written down then opens it still (pageOfLink, earlierLink).
|
|
63
|
+
* @param {string} slug
|
|
64
|
+
*/
|
|
65
|
+
export const earlierId = (slug) => (DOC_SLUG.test(slug) ? hashId(slug) : null);
|
|
66
|
+
|
|
67
|
+
const ID_FIRST = "abcdefghijklmnopqrstuvwxyz";
|
|
68
|
+
const ID_REST = `${ID_FIRST}0123456789`;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* A new page id, one `taken` (a Set of ids) does not hold: eight characters of the shape DOC_SLUG has,
|
|
72
|
+
* each picked by `random` (a function giving a number from 0 up to 1, Math.random's way: the tests give
|
|
73
|
+
* their own), another picked while it is held.
|
|
74
|
+
* @param {Set<string>} taken
|
|
75
|
+
* @param {() => number} [random]
|
|
76
|
+
*/
|
|
77
|
+
export function newPageId(taken, random = Math.random) {
|
|
78
|
+
for (;;) {
|
|
79
|
+
let id = ID_FIRST[Math.min(25, Math.floor(random() * 26))];
|
|
80
|
+
for (let at = 1; at < 8; at++) id += ID_REST[Math.min(35, Math.floor(random() * 36))];
|
|
81
|
+
if (!taken.has(id)) return id;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
39
85
|
/**
|
|
40
86
|
* A document's link, what stands after # in its address: its title's words and its page id, the id
|
|
41
87
|
* alone for a title that leaves no words or one not known here.
|
|
@@ -46,6 +92,20 @@ export function pageLink({ slug, title }) {
|
|
|
46
92
|
return words ? `${words}-${pageId(slug)}` : pageId(slug);
|
|
47
93
|
}
|
|
48
94
|
|
|
95
|
+
/**
|
|
96
|
+
* The link a document had before its own eight were its id, if it has an earlier id (earlierId): its
|
|
97
|
+
* `link` of now with the id at its end swapped for that one, its words as they are; else null. Only
|
|
98
|
+
* an address on another server is held to be a document's by its words (addressOn), and one written
|
|
99
|
+
* for such a document before reads so.
|
|
100
|
+
* @param {string} slug
|
|
101
|
+
* @param {string | undefined} link the link the document has now (pageLink)
|
|
102
|
+
*/
|
|
103
|
+
export function earlierLink(slug, link) {
|
|
104
|
+
const was = earlierId(slug);
|
|
105
|
+
const now = pageId(slug);
|
|
106
|
+
return was !== null && link?.endsWith(now) ? link.slice(0, link.length - now.length) + was : null;
|
|
107
|
+
}
|
|
108
|
+
|
|
49
109
|
/**
|
|
50
110
|
* Each document's link: a Map of slug to link, which is also the list of documents an address is read
|
|
51
111
|
* against (pageOfLink).
|
|
@@ -56,7 +116,9 @@ export const pageLinks = (pages) => new Map(pages.map((page) => [page.slug, page
|
|
|
56
116
|
|
|
57
117
|
/**
|
|
58
118
|
* The document `value` names of those in `links`: by its folder name, else by the page id after the
|
|
59
|
-
* last dash of a link, or that id alone, whatever words stand before it
|
|
119
|
+
* last dash of a link, or that id alone, whatever words stand before it; else, for a folder of the
|
|
120
|
+
* shape DOC_SLUG, by the id it went by before (earlierId), which never takes a document that has the
|
|
121
|
+
* id for its own. Its slug, or null.
|
|
60
122
|
* @param {Map<string, string>} links
|
|
61
123
|
* @param {string} value
|
|
62
124
|
*/
|
|
@@ -64,6 +126,7 @@ export function pageOfLink(links, value) {
|
|
|
64
126
|
if (links.has(value)) return value;
|
|
65
127
|
const id = value.slice(value.lastIndexOf("-") + 1);
|
|
66
128
|
for (const slug of links.keys()) if (pageId(slug) === id) return slug;
|
|
129
|
+
for (const slug of links.keys()) if (earlierId(slug) === id) return slug;
|
|
67
130
|
return null;
|
|
68
131
|
}
|
|
69
132
|
|