@heycys/gallery 0.1.1 → 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 +1 -1
- package/browser/editor/components/columns/page.mjs +4 -4
- package/browser/editor/components/embed/index.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/icons.mjs +8 -0
- package/browser/editor/components/image/crop.mjs +6 -9
- package/browser/editor/components/installed/index.mjs +11 -4
- package/browser/editor/components/installed/page.mjs +27 -16
- 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/registry.mjs +13 -4
- package/browser/editor/components/table/index.mjs +59 -2
- package/browser/editor/components/table/page.mjs +1 -1
- package/browser/editor/page/annotate/card.mjs +3 -6
- package/browser/editor/page/autosave.mjs +310 -37
- 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 +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 +124 -13
- package/browser/editor/page/clipboard/own/blocks.mjs +11 -11
- package/browser/editor/page/clipboard/own/chart-keys.mjs +41 -28
- 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 +31 -15
- package/browser/editor/page/custom-page.mjs +106 -0
- package/browser/editor/page/editor.mjs +51 -14
- 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 +24 -4
- 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 +18 -7
- package/browser/editor/page/notices.mjs +2 -2
- package/browser/editor/page/page-objects.mjs +13 -2
- package/browser/editor/page/panel.mjs +4 -9
- package/browser/editor/page/present-links.mjs +11 -2
- package/browser/editor/page/resize/index.mjs +42 -29
- 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/cells.mjs +102 -46
- package/browser/editor/page/table/icons.mjs +2 -0
- package/browser/editor/page/table/index.mjs +29 -10
- package/browser/editor/page/table/pictures.mjs +299 -0
- package/browser/editor/page/table/views.mjs +150 -0
- 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 +53 -3
- package/browser/editor/page/ui.mjs +13 -0
- 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/colors.mjs +3 -2
- package/browser/shared/component-catalog.mjs +323 -46
- package/browser/shared/component-source.mjs +37 -0
- package/browser/shared/components/index.mjs +12 -3
- package/browser/shared/components/installed.mjs +35 -3
- package/browser/shared/components/page.mjs +18 -8
- package/browser/shared/components/state.mjs +5 -1
- package/browser/shared/document-look.mjs +10 -5
- package/browser/shared/drafts.mjs +432 -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/i18n/en.mjs +307 -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 +331 -67
- 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/preview-server.mjs +3 -7
- package/browser/shared/session.mjs +8 -1
- 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-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-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-V5JTW2LH.mjs → chunk-6QBHU4DF.mjs} +1 -1
- package/dist/{chunk-Y6RLRPG3.mjs → chunk-6VTU6KEO.mjs} +1 -1
- package/dist/chunk-B4P2CM2J.mjs +3 -0
- package/dist/{chunk-FDLXYYG4.mjs → chunk-BPL64HGA.mjs} +1 -1
- package/dist/chunk-BVEFGE4B.mjs +2 -0
- package/dist/{chunk-LS4F7JUM.mjs → chunk-BZ5RAF7L.mjs} +1 -1
- package/dist/chunk-CRJEG7MT.mjs +2 -0
- package/dist/{chunk-LCTHTZIL.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-GB5SOYQJ.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-KTKHRC6H.mjs +2 -0
- package/dist/chunk-L7UP52JO.mjs +2 -0
- package/dist/{chunk-SYGN7GLU.mjs → chunk-MHW7ZKOU.mjs} +1 -1
- package/dist/chunk-N76HWBA3.mjs +10 -0
- package/dist/chunk-N7AZZLGT.mjs +548 -0
- package/dist/chunk-NAMN3RAF.mjs +2 -0
- package/dist/{chunk-5ZKJ3H4P.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-4FS7Z7WR.mjs → chunk-OUUP3WKT.mjs} +1 -1
- package/dist/{chunk-BGGDRNYQ.mjs → chunk-OW5NWPOJ.mjs} +1 -1
- package/dist/chunk-PAREWQGB.mjs +4 -0
- package/dist/chunk-POQSE4C2.mjs +2 -0
- package/dist/chunk-PUOQ65NC.mjs +2 -0
- package/dist/{chunk-XNROSH2T.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-7DTINW6U.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-UNOYVIYR.mjs +2 -0
- package/dist/{chunk-E7LWZRXY.mjs → chunk-V6RIYQZZ.mjs} +1 -1
- 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-YI43RG4P.mjs +2 -0
- package/dist/chunk-YQGT4AB2.mjs +6 -0
- package/dist/chunk-ZB4H7ZN4.mjs +2 -0
- package/dist/{chunk-IVDLMMBD.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-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 +14 -14
- package/kit/report.css +255 -17
- package/kit/runtime.js +1600 -125
- package/kit/state.js +10 -1
- package/kit/tables.js +128 -43
- package/kit/ui.js +77 -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 +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 +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 +221 -0
- package/skill/references/writing-html.md +6 -4
- package/skill/sdk/doc-kit.d.ts +396 -5
- 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/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-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
package/THIRD-PARTY-NOTICES.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Third-party notices
|
|
2
2
|
|
|
3
|
-
@heycys/gallery 0.1.
|
|
3
|
+
@heycys/gallery 0.1.2 carries the following code and data of others, bundled into dist/ and web/, built into kit/, or as files in vendor/ and browser/.
|
|
4
4
|
|
|
5
5
|
## @asamuzakjp/css-color 5.1.11
|
|
6
6
|
|
|
@@ -49,11 +49,11 @@ export function ratiosAfterRemove(ratios, removed) {
|
|
|
49
49
|
/**
|
|
50
50
|
* The gap after column `index` dragged by `fraction` of the row's width: only the two columns
|
|
51
51
|
* beside it change, snapping to their equal split or to a tenth of the row for the left one when
|
|
52
|
-
* within 1
|
|
52
|
+
* within `near` of the row (page/columns/ gives 5px of it; 1% when not said; 0: no snapping), both keeping the least share (1/24, or more where `least` says so for a part: the
|
|
53
53
|
* share its content needs, a flowchart's node as narrow as the kit lets it be, page/columns/).
|
|
54
54
|
* `ratios` are those when the drag started.
|
|
55
55
|
*/
|
|
56
|
-
export function ratiosAfterResize(ratios, index, fraction, least = []) {
|
|
56
|
+
export function ratiosAfterResize(ratios, index, fraction, least = [], near = 0.01) {
|
|
57
57
|
const left = ratios[index];
|
|
58
58
|
const right = ratios[index + 1];
|
|
59
59
|
const low = Math.max(MIN_RATIO, least[index] ?? 0);
|
|
@@ -62,8 +62,8 @@ export function ratiosAfterResize(ratios, index, fraction, least = []) {
|
|
|
62
62
|
let moved = fraction;
|
|
63
63
|
const equal = (left + right) / 2 - left;
|
|
64
64
|
const step = Math.round(10 * (left + moved)) / 10 - left;
|
|
65
|
-
if (Math.abs(equal - moved) <
|
|
66
|
-
else if (Math.abs(step - moved) <
|
|
65
|
+
if (Math.abs(equal - moved) < near) moved = equal;
|
|
66
|
+
else if (Math.abs(step - moved) < near) moved = step;
|
|
67
67
|
moved = Math.min(Math.max(moved, low - left), right - high);
|
|
68
68
|
const out = [...ratios];
|
|
69
69
|
out[index] = left + moved;
|
|
@@ -24,8 +24,8 @@ export const HEIGHT = "--doc-embed-height";
|
|
|
24
24
|
/** The frame's height as a size: the least and the most (px) it may be given. */
|
|
25
25
|
export const HEIGHT_SIZE = { min: 96, max: 2000, px: true };
|
|
26
26
|
|
|
27
|
-
/** The sandbox of a web page's frame (Notion's), and of an HTML file's (no origin of its own). */
|
|
28
|
-
export
|
|
27
|
+
/** The sandbox of a web page's frame (Notion's: the sidebar's web links have it too, shared/web-links.mjs), and of an HTML file's (no origin of its own). */
|
|
28
|
+
export { WEB_SANDBOX } from "../../../shared/web-links.mjs";
|
|
29
29
|
export const FILE_SANDBOX = "allow-scripts allow-popups allow-forms allow-modals";
|
|
30
30
|
|
|
31
31
|
/**
|
|
@@ -10,20 +10,21 @@ import { t } from "../../../shared/i18n/index.mjs";
|
|
|
10
10
|
// card's vertical middle (the layer over the page draws it: overlay-layer.mjs, so it scrolls with
|
|
11
11
|
// the node and never touches the report's markup; above the handle and a section's bar there,
|
|
12
12
|
// IN_LAYER button, so the half of a row's last node's button over its section's bar is the
|
|
13
|
-
// button's), a white surface
|
|
14
|
-
// is on it
|
|
13
|
+
// button's), a white surface lifted by a soft shadow (no line round it) and a thin outline plus, the plus
|
|
14
|
+
// darker once the pointer is on it and the surface grey only while it is pressed (the editor's icon button
|
|
15
|
+
// look, look.mjs BUTTONS; Notion-flat: no blue). A click adds a node right
|
|
15
16
|
// after it (page.mjs addAfter: one undo step, the caret in its empty first line, bold armed); the
|
|
16
17
|
// press itself moves no caret and starts no box selection. It goes as the pointer leaves the node
|
|
17
18
|
// (and the button), as a drag or a box selection begins, and with any structural change that takes
|
|
18
19
|
// its node away.
|
|
19
20
|
|
|
20
21
|
const STYLE = `
|
|
21
|
-
.ge-flow-add { z-index: ${IN_LAYER.button}; box-sizing: border-box; width: 22px; height: 22px; padding: 0; border:
|
|
22
|
-
background: var(--doc-surface, #fff); color: var(--ge-ico2); cursor: pointer; pointer-events: auto; box-shadow: 0 1px
|
|
23
|
-
opacity: 0; transition: opacity .12s, background-color .12s, color .12s
|
|
22
|
+
.ge-flow-add { z-index: ${IN_LAYER.button}; box-sizing: border-box; width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%;
|
|
23
|
+
background: var(--doc-surface, #fff); color: var(--ge-ico2); cursor: pointer; pointer-events: auto; box-shadow: 0 1px 3px light-dark(rgb(25 25 25 / 18%), rgb(0 0 0 / 45%));
|
|
24
|
+
opacity: 0; transition: opacity .12s, background-color .12s, color .12s; }
|
|
24
25
|
.ge-flow-add[data-shown] { opacity: 1; }
|
|
25
26
|
.ge-flow-add > svg { display: block; width: 14px; height: 14px; margin: 3px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; }
|
|
26
|
-
.ge-flow-add:hover {
|
|
27
|
+
.ge-flow-add:hover { color: var(--ge-ico); }
|
|
27
28
|
.ge-flow-add:active { background: light-dark(#ebebea, #404040); }
|
|
28
29
|
@media (prefers-reduced-motion: reduce) { .ge-flow-add { transition: none; } }
|
|
29
30
|
`;
|
|
@@ -266,7 +266,7 @@ const NODE_CHOICES = [
|
|
|
266
266
|
const STYLE = `
|
|
267
267
|
[data-ge-editing] ol.doc-flow > li { --ge-text-radius: 8px; }
|
|
268
268
|
[data-ge-editing] ol.doc-flow > li > * { --ge-text-radius: 3px; }
|
|
269
|
-
[data-ge-editing] ol.doc-flow > li > p[data-ge-placeholder]:first-of-type::before { font-weight:
|
|
269
|
+
[data-ge-editing] ol.doc-flow > li > p[data-ge-placeholder]:first-of-type::before { font-weight: 700; }
|
|
270
270
|
`;
|
|
271
271
|
|
|
272
272
|
/**
|
|
@@ -24,6 +24,14 @@ export const PAGE_ICON = svg('<path d="M5 18.33a1.67 1.67 0 0 1-1.67-1.66V3.33a1
|
|
|
24
24
|
/** A section (分区): blocks gathered between brackets, the block menu's 组成新分区 and the section's line in 设置 › 组件列表. */
|
|
25
25
|
export const SECTION_ICON = svg('<path d="M6 3.75h-.75a2 2 0 0 0-2 2v8.5a2 2 0 0 0 2 2H6M14 3.75h.75a2 2 0 0 1 2 2v8.5a2 2 0 0 1-2 2H14"/><path d="M7.25 7.75h5.5M7.25 12.25h5.5"/>');
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* A custom block (自定义块): a card of text, a rounded square with a short title line over two longer
|
|
29
|
+
* ones. The one mark of a block that has no picture of its own: the "/" menu's row and a block's menu,
|
|
30
|
+
* 添加自定义块's library, and a custom block's line in 设置 › 组件列表. On the 20 box of the icons beside
|
|
31
|
+
* it, so that the menus' stroke (1.25 at 20px) is its stroke too.
|
|
32
|
+
*/
|
|
33
|
+
export const BLOCK_ICON = svg('<rect x="3.25" y="3.25" width="13.5" height="13.5" rx="2.5"/><path d="M6.75 7h3.5M6.75 10h6.5M6.75 13h4.5"/>');
|
|
34
|
+
|
|
27
35
|
/** A detail card (详情卡片): a card with two lines of text. */
|
|
28
36
|
export const DIALOG_ICON = svg('<rect x="3.25" y="3.75" width="13.5" height="12.5" rx="2.5"/><path d="M6.5 8h7M6.5 11.5h4.5"/>');
|
|
29
37
|
export const LINK_ICON = svg('<g transform="rotate(45 10 10)"><path d="M7 8.5V6a3 3 0 0 1 6 0v2.5M7 11.5V14a3 3 0 0 0 6 0v-2.5M10 7.5v5"/></g>'); // two U's and the line between them, turned 45°
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Z } from "../../../shared/layers.mjs";
|
|
2
|
-
import { addStyle, element, mount } from "../../page/ui.mjs";
|
|
2
|
+
import { addStyle, element, mount, textButton } from "../../page/ui.mjs";
|
|
3
3
|
import { t } from "../../../shared/i18n/index.mjs";
|
|
4
4
|
|
|
5
5
|
// 裁剪图片 (notion-lite's blocks/image/edit/crop.js, Notion's 31868): a dialog over the page, the
|
|
@@ -19,13 +19,10 @@ const STYLE = `
|
|
|
19
19
|
box-shadow: 0 0 0 1px var(--ge-outline), 0 20px 40px rgb(0 0 0 / 30%); }
|
|
20
20
|
.ge-crop-bar { display: flex; align-items: center; gap: 6px; padding: 10px 12px; border-bottom: 1px solid var(--ge-line); }
|
|
21
21
|
.ge-crop-title { flex: 1; text-align: center; font-weight: 500; white-space: nowrap; }
|
|
22
|
-
.ge-crop-shape
|
|
23
|
-
.ge-crop-shape { color: var(--ge-tx2); }
|
|
22
|
+
.ge-crop-shape { height: 28px; padding: 0 10px; border: 0; border-radius: 6px; background: transparent; color: var(--ge-tx2); font: inherit; cursor: pointer; }
|
|
24
23
|
.ge-crop-shape[aria-pressed="true"] { background: var(--ge-fill); color: var(--ge-accent-text); }
|
|
25
|
-
.ge-crop-shape:hover
|
|
26
|
-
.ge-crop-
|
|
27
|
-
.ge-crop-save { background: var(--ge-accent); color: #fff; font-weight: 500; }
|
|
28
|
-
.ge-crop-save:hover { background: var(--ge-accent-hover); }
|
|
24
|
+
.ge-crop-shape:hover { background: var(--ge-hover); }
|
|
25
|
+
.ge-crop-shape[aria-pressed="true"]:hover { background: var(--ge-btn-primary-hover); }
|
|
29
26
|
.ge-crop-body { display: flex; justify-content: center; padding: 30px; background: light-dark(#f7f6f3, #1f1f1f); }
|
|
30
27
|
.ge-crop-stage { position: relative; overflow: hidden; }
|
|
31
28
|
.ge-crop-stage > img { display: block; max-width: 70vw; max-height: 75vh; pointer-events: none; }
|
|
@@ -56,8 +53,8 @@ export function openCrop(img, save, from = {}) {
|
|
|
56
53
|
button.addEventListener("click", () => shape(ratio, button));
|
|
57
54
|
return button;
|
|
58
55
|
});
|
|
59
|
-
const cancel =
|
|
60
|
-
const done =
|
|
56
|
+
const cancel = textButton(t("取消"), null, { class: "ge-crop-cancel" });
|
|
57
|
+
const done = textButton(t("保存"), null, { class: "ge-crop-save", primary: true });
|
|
61
58
|
const dialog = element("div", { class: "ge-crop-dialog", role: "dialog", "aria-label": t("裁剪图片") },
|
|
62
59
|
element("div", { class: "ge-crop-bar" }, ...shapes, element("div", { class: "ge-crop-title", text: t("裁剪图片") }), cancel, done),
|
|
63
60
|
element("div", { class: "ge-crop-body" }, stage));
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { escapeText } from "../../../shared/escape.mjs";
|
|
2
2
|
import { ATTRIBUTE, FALLBACK, INSTANCE, PACKAGE_ID, SLOT, SLOT_PART, componentAt, heldBy, instanceMatch, refusedInCopy, slotsIn } from "../../../shared/components/installed.mjs";
|
|
3
3
|
import { wordsIn } from "../../page/clipboard/own/writers.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { BLOCK_ICON } from "../icons.mjs";
|
|
5
|
+
import { VIEW_FROM } from "../../../shared/table-chart.mjs";
|
|
5
6
|
import { t } from "../../../shared/i18n/index.mjs";
|
|
6
7
|
|
|
7
8
|
// 组件: the one kind of block every component package is to the engines, the host of a package's
|
|
@@ -86,8 +87,8 @@ function elementOf(html, doc = globalThis.document) {
|
|
|
86
87
|
// The most a description carries of one piece of markup (blocks.mjs `string`).
|
|
87
88
|
const CARRIED = 1e6;
|
|
88
89
|
|
|
89
|
-
//
|
|
90
|
-
export const ICON =
|
|
90
|
+
// The mark of any custom block with no picture of its own: a card of text (icons.mjs).
|
|
91
|
+
export const ICON = BLOCK_ICON;
|
|
91
92
|
|
|
92
93
|
export default {
|
|
93
94
|
name: "installed",
|
|
@@ -102,7 +103,7 @@ export default {
|
|
|
102
103
|
sealed: INSTANCE,
|
|
103
104
|
units: {
|
|
104
105
|
installed: {
|
|
105
|
-
name: t("
|
|
106
|
+
name: t("自定义块@block"),
|
|
106
107
|
icon: ICON,
|
|
107
108
|
match: [{ rank: 0, tag: ["div", "section"], attr: ATTRIBUTE }],
|
|
108
109
|
boxed: true,
|
|
@@ -130,11 +131,17 @@ export default {
|
|
|
130
131
|
// Its markup is the file's, from its template or what was carried (`data-ge-copy`, its slots
|
|
131
132
|
// empty); what its slots hold goes apart, blocks made on the page as any (`children`, each in the
|
|
132
133
|
// slot `boxKeys` names), so that the commit's answer names each, as for a block made in a column.
|
|
134
|
+
// A view of a table (a table's 视图 › made it of its template, or a paste carried one) says the key
|
|
135
|
+
// of the table it reads as the page has it (`from`, its VIEW_FROM, which a paste may have given it
|
|
136
|
+
// anew: clipboard/own/chart-keys.mjs), which the file writes on it (file.mjs source); one carried
|
|
137
|
+
// with none on it says null (a view pasted into another document, its key taken off there), so
|
|
138
|
+
// that the file has none either, whatever its markup carried.
|
|
133
139
|
extras(element, { nodes }) {
|
|
134
140
|
const held = slotsIn(element).filter((slot) => slot.hasAttribute("data-ge-box")).flatMap((slot) => (nodes?.(slot) ?? []).map((node) => [slot.getAttribute(SLOT), node]));
|
|
135
141
|
return {
|
|
136
142
|
package: element.getAttribute(ATTRIBUTE),
|
|
137
143
|
...(element.hasAttribute("data-ge-copy") ? { html: element.getAttribute("data-ge-copy") } : {}),
|
|
144
|
+
...(element.hasAttribute(VIEW_FROM) ? { from: element.getAttribute(VIEW_FROM) } : element.hasAttribute("data-ge-copy") ? { from: null } : {}),
|
|
138
145
|
...(slotsIn(element).length > 0 ? { children: held.map(([, node]) => node), boxKeys: held.map(([key]) => key) } : {}),
|
|
139
146
|
};
|
|
140
147
|
},
|
|
@@ -398,22 +398,33 @@ export function create({ map, newParagraph, active, sourceStep, struct }) {
|
|
|
398
398
|
// insertTypedBlock: the caret in its first text part; with none, in an empty paragraph after it, as
|
|
399
399
|
// for a divider). Its slots are boxes made on the page at once, what the template has in each made
|
|
400
400
|
// blocks of the page's (an empty paragraph where it has none), so that the reader writes in one
|
|
401
|
-
// before the instance is saved, and Enter in a text part goes into the slot after it.
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
401
|
+
// before the instance is saved, and Enter in a text part goes into the slot after it. One whose needs
|
|
402
|
+
// hold "tables" is a view a table's 视图 › offers too (`readsTables`: page/table/views.mjs), which
|
|
403
|
+
// binds the one it makes to the table (VIEW_FROM). Where two offered have one name (the same block
|
|
404
|
+
// of two packs: 我的待办 of Gallery 风格 and of 柔光风格), each row says its pack's name after it in grey
|
|
405
|
+
// (`of`: the menu's ge-pop-of).
|
|
406
|
+
menuVariants: () => {
|
|
407
|
+
const offered = (map.components ?? []).filter(({ template, state }) => template && state === "normal");
|
|
408
|
+
const counts = new Map();
|
|
409
|
+
for (const entry of offered) counts.set(entry.name[language], (counts.get(entry.name[language]) ?? 0) + 1);
|
|
410
|
+
return Object.fromEntries(offered.map((entry) => [entry.id, {
|
|
411
|
+
label: entry.name[language],
|
|
412
|
+
...(counts.get(entry.name[language]) > 1 ? { of: entry.pack?.name?.[language] ?? entry.id.split("/")[0] } : {}),
|
|
413
|
+
icon: pictureOf(entry) ?? ICON,
|
|
414
|
+
words: `${entry.name.zh} ${entry.name.en} ${entry.id} ${entry.words}`.toLowerCase(),
|
|
415
|
+
sample: true,
|
|
416
|
+
readsTables: entry.needs?.includes("tables") ?? false,
|
|
417
|
+
preview: { src: entry.preview, says: entry.description[language] },
|
|
418
|
+
create({ doc, put: place, paragraph }) {
|
|
419
|
+
bring(entry);
|
|
420
|
+
const instance = newInstance(doc, entry.template);
|
|
421
|
+
slotsMade(doc, instance, (slot) => blocksOfTemplate(doc, slot));
|
|
422
|
+
ownIds(doc, [instance]);
|
|
423
|
+
place(instance);
|
|
424
|
+
return editableParts(instance)[0] ?? firstHost(instance) ?? place(paragraph());
|
|
425
|
+
},
|
|
426
|
+
}]));
|
|
427
|
+
},
|
|
417
428
|
/**
|
|
418
429
|
* Whether a copy of an instance's unit stands for it: not where it has slots, whose blocks that copy
|
|
419
430
|
* would write whole, with no ids the page knows; such an instance is copied by what it carries alone
|
|
@@ -17,13 +17,14 @@ let any = false; // the server could not say which: the page connected a moment
|
|
|
17
17
|
export const isBehind = (id) => any || behind.has(id);
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* `components`, the list a page holds, as the reader's settings now say: the state each package says
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* `components`, the list a page holds, as the reader's settings now say: the state each package says
|
|
21
|
+
* by its `places` and gallery.json's hidden, shown, disabled, unlisted and packs off (settingState, inDocumentMenus: the
|
|
22
|
+
* server's own rule), which a menu reads, at once and with nothing shown again (`doc-settings-changed`).
|
|
23
|
+
* A package that comes on is in none of that yet: it comes with the list the page reads as the catalog
|
|
24
|
+
* changes, as one added does (`doc-catalog-changed`, ./page.mjs).
|
|
24
25
|
*/
|
|
25
26
|
export function followSettings(components, settings) {
|
|
26
|
-
for (const entry of components) entry.state = settingState(entry.id, settings);
|
|
27
|
+
for (const entry of components) entry.state = settingState(entry.id, { hidden: [], shown: [], disabled: [], unlisted: [], packsOff: [], ...settings }, entry.places);
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
/** Hears what changed of the catalog while the page held no instance of it. */
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ATTRIBUTE, INSTANCE } from "../../shared/components/installed.mjs";
|
|
2
|
+
|
|
3
|
+
// A custom page's card read for the instance it holds, by the host's own mark of an instance
|
|
4
|
+
// (shared/components/installed.mjs INSTANCE, ATTRIBUTE: a div or section naming its package): the one
|
|
5
|
+
// the server reads (shared/page-cards.mjs readPage, which refuses an article or a span carrying the
|
|
6
|
+
// attribute, and page check fails it) and the kit's page runtime reads. The board
|
|
7
|
+
// (src/editor/page/board/index.mjs) is a page engine and knows no package's marks, so what it asks of
|
|
8
|
+
// the DOM it asks here: a card with an `<article data-doc-component="…">` is a card with no instance on
|
|
9
|
+
// the page too, offered no settings and sending no part, instead of one the service then refuses.
|
|
10
|
+
|
|
11
|
+
/** The instance card `card` holds (its child that is one), or null. */
|
|
12
|
+
export const instanceOf = (card) => [...card.children].find((child) => child.matches(INSTANCE)) ?? null;
|
|
13
|
+
|
|
14
|
+
/** The package id an instance names (<scope>/<name>), or null for no instance. */
|
|
15
|
+
export const packageOf = (instance) => instance?.getAttribute(ATTRIBUTE) ?? null;
|
|
16
|
+
|
|
17
|
+
/** The nearest instance around `node` (itself counted), or null. */
|
|
18
|
+
export const instanceAround = (node) => node.closest(INSTANCE);
|
|
@@ -6,7 +6,7 @@ import { begin, done, made } from "../../page/made.mjs";
|
|
|
6
6
|
import { createMenu } from "../../page/menu.mjs";
|
|
7
7
|
import { keptByComponent } from "../../page/page-objects.mjs";
|
|
8
8
|
import { hideTooltip, tooltipAt } from "../../page/tooltip.mjs";
|
|
9
|
-
import { addStyle, element } from "../../page/ui.mjs";
|
|
9
|
+
import { addStyle, element, textButton } from "../../page/ui.mjs";
|
|
10
10
|
import { CHECKED, CONTINUE, FLOW, START, TODO, heldListType, holdsSays, listType, mergeSays } from "./index.mjs";
|
|
11
11
|
import { BLOCK_TYPES, accepts } from "../registry.mjs";
|
|
12
12
|
import { FLOW_KEY, isFlowLabel } from "../../../shared/components/list.mjs";
|
|
@@ -186,8 +186,7 @@ const STYLE = `
|
|
|
186
186
|
.ge-list-value-title { padding: 10px 12px 0; color: var(--ge-tx2); font-size: 12px; font-weight: 500; line-height: 14px; }
|
|
187
187
|
.ge-list-value input { box-sizing: border-box; flex: 1; min-width: 0; height: 28px; margin: 0; padding: 0 8px; border: 0; border-radius: 6px; outline: none; background: var(--ge-hover); color: var(--ge-tx); font: inherit; box-shadow: inset 0 0 0 1px var(--ge-line); }
|
|
188
188
|
.ge-list-value input:focus { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ge-tx3) 60%, transparent); }
|
|
189
|
-
.ge-list-value
|
|
190
|
-
.ge-list-value button:hover { background: var(--ge-accent-hover); }
|
|
189
|
+
.ge-list-value .ge-btn { flex: none; }
|
|
191
190
|
`;
|
|
192
191
|
|
|
193
192
|
// ---------- keys, numbers ----------
|
|
@@ -494,9 +493,7 @@ export function create({ struct, say, convertHost, targetsOf, look, isEditing, b
|
|
|
494
493
|
} else return;
|
|
495
494
|
event.preventDefault();
|
|
496
495
|
});
|
|
497
|
-
const confirm =
|
|
498
|
-
confirm.addEventListener("mousedown", (event) => event.preventDefault());
|
|
499
|
-
confirm.addEventListener("click", apply);
|
|
496
|
+
const confirm = textButton(t("确定"), apply, { primary: true });
|
|
500
497
|
const view = element("div", {}, element("div", { class: "ge-list-value-title", text: t("新编号为") }), element("div", { class: "ge-list-value" }, field, confirm));
|
|
501
498
|
item.setAttribute("data-ge-number", "open");
|
|
502
499
|
menu.open([{ node: view, cells: [] }], rect, { label: t("修改编号值"), icons: false, width: 148, highlight: false, onClose: () => item.removeAttribute("data-ge-number") });
|
|
@@ -136,7 +136,7 @@ import { t } from "../../shared/i18n/index.mjs";
|
|
|
136
136
|
// own. Every component's rules are tried in `rank` order, with the page's (PAGE below),
|
|
137
137
|
// and the first match wins: a rule ranked below the page's 80 goes before any control's,
|
|
138
138
|
// and is the one that can claim a button as its own.
|
|
139
|
-
// hosts the kinds of text block it defines (data-ge-kind): { [kind]: { name, caps, tex?, wrapped?, parts?, opensBefore?, textFilters?, formula?, closed?, inner?, blankSays?, placeholder? } }, caps
|
|
139
|
+
// hosts the kinds of text block it defines (data-ge-kind): { [kind]: { name, caps, tex?, wrapped?, parts?, opensBefore?, textFilters?, formula?, closed?, inner?, pictures?, blankSays?, placeholder?, untitled?, opensBody? } }, caps
|
|
140
140
|
// ({ bound, blockLevel }) giving what such a text block can do (source/); opensBefore:
|
|
141
141
|
// Enter at its very start, with words in it, puts an empty paragraph before its block
|
|
142
142
|
// where it does not split, as one that splits does (typing/); textFilters: false, what
|
|
@@ -145,14 +145,19 @@ import { t } from "../../shared/i18n/index.mjs";
|
|
|
145
145
|
// none there (takesFormula);
|
|
146
146
|
// closed: the page holds no text block for it until the reader opens it (a code block);
|
|
147
147
|
// inner(element): the text a save takes of one, as markup, where that is not what its
|
|
148
|
-
// nodes say (a code block's code);
|
|
148
|
+
// nodes say (a code block's code); pictures: it holds pictures amid its words (a table
|
|
149
|
+
// cell's), { show(root) (the file's made the page's: where the server serves them),
|
|
150
|
+
// write(element) (one's markup, "" for one of no file, null for no picture) } (core.mjs);
|
|
149
151
|
// parts: the parts of components ([component id, part name]: a part of its shared
|
|
150
152
|
// description edited as text, src/shared/components/) whose elements are text blocks
|
|
151
153
|
// of this kind, found so by the server's scan; tex: its text is a formula's TeX alone; wrapped: the page makes the text block a
|
|
152
154
|
// span inside the element, which keeps its own behaviour (a Sheet tab's button);
|
|
153
155
|
// blankSays: what the status line says of one left blank that must hold words, as a
|
|
154
156
|
// type's says of a block of it (blankSaysOf); placeholder: what one says while it
|
|
155
|
-
// is empty under the caret, whatever part it is (placeholderOf)
|
|
157
|
+
// is empty under the caret, whatever part it is (placeholderOf); untitled: it says its
|
|
158
|
+
// placeholder whenever it is empty, the caret in it or not (the page's title, notion-lite's
|
|
159
|
+
// data-ph 新页面: typing/ updatePlaceholder); opensBody: Enter in it goes to the body, what
|
|
160
|
+
// follows the caret a new paragraph right below it (the page's title: typing/ enterBody)
|
|
156
161
|
// placeholders what an empty text block says while the caret is in it: { [part]: text }, part
|
|
157
162
|
// being a part of its shared description (src/shared/components/) whose element it is
|
|
158
163
|
// (placeholderOf); a heading's own is its type's `placeholder`, and a type's `placeholder:
|
|
@@ -380,7 +385,11 @@ const PAGE = {
|
|
|
380
385
|
hosts: {
|
|
381
386
|
// A free text block may be left empty (Notion's): written as an empty element, one line high.
|
|
382
387
|
flow: { opensBefore: true, caps: ({ bound }) => bound ? ["split", "merge", "links"] : ["split", "merge", "remove", "empty", "links"] },
|
|
383
|
-
title
|
|
388
|
+
// The page's title may be left empty (notion-lite's page title): an untitled document, its title
|
|
389
|
+
// saying 未命名文档 in gray (`untitled`), never written into the file; whatever names the document
|
|
390
|
+
// names it so (the workbench's reportTitle, links/pages.mjs, an export's <title>). Enter in it goes to the
|
|
391
|
+
// body (`opensBody`: typing/ enterBody, notion-lite's page title).
|
|
392
|
+
title: { name: t("文档主标题"), caps: () => ["plain", "empty"], placeholder: t("未命名文档"), untitled: true, opensBody: true },
|
|
384
393
|
...MEDIA_HOSTS,
|
|
385
394
|
},
|
|
386
395
|
readOnly: [
|
|
@@ -6,6 +6,8 @@ import { columnWidths, slotsOf, tileSlots, tileSpans } from "../../../shared/tab
|
|
|
6
6
|
import { CELL_ALIGN_CLASSES, CELL_BOLD_CLASS, CELL_VALIGN_CLASSES } from "../../../shared/components/table.mjs";
|
|
7
7
|
import { CHART_KEY, CHART_SOURCE } from "../../../shared/table-chart.mjs";
|
|
8
8
|
import { t } from "../../../shared/i18n/index.mjs";
|
|
9
|
+
import { escapeAttribute } from "../../../shared/escape.mjs";
|
|
10
|
+
import { servedFile } from "../../page/served.mjs";
|
|
9
11
|
|
|
10
12
|
const ICON = svg('<rect x="3.25" y="3.75" width="13.5" height="12.5" rx="2"/><path d="M3.25 8h13.5M3.25 12.1h13.5M8.25 3.75v12.5"/>');
|
|
11
13
|
|
|
@@ -53,7 +55,9 @@ export default {
|
|
|
53
55
|
boxed: true,
|
|
54
56
|
resizable: ".doc-table-wrap[data-ge-unit]", // its right and bottom edges, once it is in the file
|
|
55
57
|
copy: "itself", // within the report a copy keeps all of its markup (its scope line, its frame's size); another report's gets the table's data (tableData) made anew
|
|
56
|
-
|
|
58
|
+
// 识别数字列 off, and the key a chart or a view reads it by (src/shared/table-chart.mjs), which 视图 ›
|
|
59
|
+
// of its menu puts on a table that has none (page/table/views.mjs) in the step that puts the view in.
|
|
60
|
+
attributes: { [NUMBERS]: (value) => value === "off", [CHART_SOURCE]: (value) => CHART_KEY.test(value) },
|
|
57
61
|
sizes: {
|
|
58
62
|
[SPAN]: { min: 0.15, max: 3 }, // past 1 the table is wider than the text and scrolls in its frame
|
|
59
63
|
[TABLE_HEIGHT]: { min: 80, max: 4000, px: true, none: true, height: true },
|
|
@@ -62,7 +66,7 @@ export default {
|
|
|
62
66
|
},
|
|
63
67
|
components: ["doc-table-wrap", "doc-table-meta"],
|
|
64
68
|
hosts: {
|
|
65
|
-
cell: { name: t("表格单元格"), caps: () => ["empty", "links"] },
|
|
69
|
+
cell: { name: t("表格单元格"), caps: () => ["empty", "links"], pictures: { show: showPictures, write: writtenPicture } },
|
|
66
70
|
},
|
|
67
71
|
types: {
|
|
68
72
|
// Made by a paste or the "/" menu (三列三行, a header row: page.mjs newTable): no class here, so
|
|
@@ -306,3 +310,56 @@ export function tableData(element, serializeInner) {
|
|
|
306
310
|
...(chart && CHART_KEY.test(chart) ? { chart } : {}),
|
|
307
311
|
};
|
|
308
312
|
}
|
|
313
|
+
|
|
314
|
+
// ---------- a cell's pictures ----------
|
|
315
|
+
// 单元格里的图片 (page/table/pictures.mjs; source/blocks.mjs cellPictureProblem says what the file
|
|
316
|
+
// takes): an <img> amid a cell's words, a picture of the report's folder. On the page it shows where
|
|
317
|
+
// the server serves the folder (`src`, page/served.mjs), the file it is in data-ge-src, as an
|
|
318
|
+
// image block's; the cell's text writes it back from its element (the host's `pictures`, which
|
|
319
|
+
// core.mjs reads): <img src="assets/<file>" alt="…" width="N">, its attributes in the order the
|
|
320
|
+
// element has them, the file's own; one the browser put in from elsewhere, its file no picture of
|
|
321
|
+
// the folder, is no part of the text.
|
|
322
|
+
|
|
323
|
+
const PICTURE_FILE = /^assets\/[A-Za-z0-9][A-Za-z0-9._-]{0,80}$/;
|
|
324
|
+
const PICTURE_WIDTH = /^[1-9]\d{0,3}$/;
|
|
325
|
+
const isPicture = (node) => node?.nodeType === 1 && node.localName === "img";
|
|
326
|
+
|
|
327
|
+
/** The file of a picture in a cell (assets/<file>), or null: none the page writes. */
|
|
328
|
+
export const pictureFile = (img) => {
|
|
329
|
+
const file = img.getAttribute("data-ge-src") || img.getAttribute("src") || "";
|
|
330
|
+
return PICTURE_FILE.test(file) ? file : null;
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* A picture for a cell: the file `path` (assets/<file>) shown where the server serves it, its `alt`
|
|
335
|
+
* words, its `width` in pixels (none: the kit's own size).
|
|
336
|
+
*/
|
|
337
|
+
export function cellPicture(doc, path, { alt = "", width = null } = {}) {
|
|
338
|
+
const img = doc.createElement("img");
|
|
339
|
+
img.setAttribute("src", servedFile(path));
|
|
340
|
+
img.setAttribute("alt", alt);
|
|
341
|
+
if (width) img.setAttribute("width", String(Math.round(width)));
|
|
342
|
+
img.setAttribute("data-ge-src", path);
|
|
343
|
+
img.draggable = false;
|
|
344
|
+
return img;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// A cell's pictures as the file has them made the page's (core.mjs prepareBlock): shown where the server serves them.
|
|
348
|
+
function showPictures(root) {
|
|
349
|
+
for (const img of root.querySelectorAll("img")) {
|
|
350
|
+
const file = img.getAttribute("src") ?? "";
|
|
351
|
+
if (!PICTURE_FILE.test(file)) continue;
|
|
352
|
+
img.setAttribute("data-ge-src", file);
|
|
353
|
+
img.setAttribute("src", servedFile(file));
|
|
354
|
+
img.draggable = false;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// A picture as the cell's text writes it: its markup, "" (no file of the folder), null (no picture).
|
|
359
|
+
function writtenPicture(node) {
|
|
360
|
+
if (!isPicture(node)) return null;
|
|
361
|
+
const file = pictureFile(node);
|
|
362
|
+
if (!file) return "";
|
|
363
|
+
const said = [...node.attributes].filter(({ name, value }) => name === "src" || name === "alt" || (name === "width" && PICTURE_WIDTH.test(value)));
|
|
364
|
+
return `<img${said.map(({ name, value }) => ` ${name}="${escapeAttribute(name === "src" ? file : value)}"`).join("")}>`;
|
|
365
|
+
}
|
|
@@ -120,7 +120,7 @@ function cellNodes(doc, html, inline) {
|
|
|
120
120
|
* row, its names' column a header column, its numeric columns read (the page's own copy as it was).
|
|
121
121
|
*/
|
|
122
122
|
export function build({ doc, block, inline }) {
|
|
123
|
-
const rows = block.rows.map((row) => row.map((html) => cellNodes(doc, html, inline)));
|
|
123
|
+
const rows = block.rows.map((row) => row.map((html) => cellNodes(doc, html, (text) => inline(text, { pictures: true })))); // a cell's pictures its own
|
|
124
124
|
const table = newTable(doc, { rows, header: Boolean(block.header), column: Boolean(block.column), numbers: block.numbers !== false, looks: block.looks, widths: block.widths, spans: block.spans, chart: block.chart });
|
|
125
125
|
if (block.outside) optimizeTable(table);
|
|
126
126
|
return table;
|
|
@@ -32,8 +32,7 @@ export const STYLE = `
|
|
|
32
32
|
.ge-note-marker { width: ${RAIL.marker}px; height: ${RAIL.marker}px; box-sizing: border-box; margin: 0; padding: 0; border: 0; border-radius: 6px; background: transparent; display: grid; place-items: center; color: var(--ge-ico2); cursor: pointer; pointer-events: auto; }
|
|
33
33
|
.ge-note-marker svg { width: 18px; height: 18px; fill: currentColor; stroke: none; }
|
|
34
34
|
.ge-note-marker[hidden], .ge-note-card[hidden] { display: none; }
|
|
35
|
-
.ge-note-marker
|
|
36
|
-
.ge-note-marker:active { background: var(--ge-press); }
|
|
35
|
+
.ge-note-marker[data-hot] { background: var(--ge-hover); color: var(--ge-ico); }
|
|
37
36
|
.ge-note-marker:focus-visible { outline: 2px solid var(--ge-focus); outline-offset: -2px; }
|
|
38
37
|
/* The card, where the format bar would stand: a popover as the bar is, as wide as ${RAIL.card}px or the column. Its face is what shows; the card itself stands still, so a face going left under the pointer keeps it. */
|
|
39
38
|
.ge-note-card { z-index: 1; width: ${RAIL.card}px; box-sizing: border-box; color: var(--ge-tx); pointer-events: auto; cursor: text; }
|
|
@@ -60,8 +59,6 @@ export const STYLE = `
|
|
|
60
59
|
.ge-note-card[data-long][data-top] textarea { --top: 28px; }
|
|
61
60
|
/* Its delete button, on the field's first line, in the room the field leaves it. */
|
|
62
61
|
.ge-note-delete { position: absolute; top: 7px; right: 7px; width: 24px; height: 24px; box-sizing: border-box; margin: 0; padding: 0; border: 0; border-radius: 6px; background: transparent; display: grid; place-items: center; color: var(--ge-ico3); cursor: pointer; }
|
|
63
|
-
.ge-note-delete:hover { background: var(--ge-hover); }
|
|
64
|
-
.ge-note-delete:active { background: var(--ge-press); }
|
|
65
62
|
.ge-note-delete svg { width: 18px; height: 18px; pointer-events: none; }
|
|
66
63
|
.ge-note-bar { width: 2px; border-radius: 1px; background: var(--ge-note-line); }
|
|
67
64
|
.ge-note-bar[data-hot] { background: var(--ge-note-hot-line); }
|
|
@@ -74,13 +71,13 @@ export const STYLE = `
|
|
|
74
71
|
export const layerNode = () => element("div", { class: "ge-note-layer", "data-doc-dev": "" });
|
|
75
72
|
|
|
76
73
|
export function markerNode(id) {
|
|
77
|
-
return element("button", { type: "button", class: "ge-note-marker", "data-note": id, "aria-label": t("批注"), tabindex: "-1", html: MARKER_ICON });
|
|
74
|
+
return element("button", { type: "button", class: "ge-note-marker ge-icon-btn", "data-note": id, "aria-label": t("批注"), tabindex: "-1", html: MARKER_ICON });
|
|
78
75
|
}
|
|
79
76
|
|
|
80
77
|
/** A card: a plain-text field, and the button that deletes what it holds, on its face. */
|
|
81
78
|
export function cardNode() {
|
|
82
79
|
const field = element("textarea", { rows: "1", spellcheck: "false", maxlength: TEXT_MOST, placeholder: t("写下建议…"), "aria-label": t("批注") });
|
|
83
|
-
const erase = element("button", { type: "button", class: "ge-note-delete", "aria-label": t("删除批注"), tabindex: "-1", html: ICONS.trash });
|
|
80
|
+
const erase = element("button", { type: "button", class: "ge-note-delete ge-icon-btn", "aria-label": t("删除批注"), tabindex: "-1", html: ICONS.trash });
|
|
84
81
|
tooltip(erase, t("删除批注"));
|
|
85
82
|
return { node: element("div", { class: "ge-note-card", role: "group" }, element("div", { class: "ge-note-face" }, field, erase)), field, erase };
|
|
86
83
|
}
|