@jxsuite/studio 6.1.1 → 8.0.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/README.md +5 -5
- package/dist/chunks/2020-5wtzce5g.js +4 -0
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-5tphg7xe.js +4 -0
- package/dist/chunks/add-new-flow-psym14sn.js +4 -0
- package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
- package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
- package/dist/chunks/color-area-6rbra5dy.js +4 -0
- package/dist/chunks/color-field-gy56c94g.js +4 -0
- package/dist/chunks/color-m7r1vk54.js +4 -0
- package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
- package/dist/chunks/combobox-72h32ejk.js +4 -0
- package/dist/chunks/components-r22xca09.js +4 -0
- package/dist/chunks/content-source-mmppmcyg.js +4 -0
- package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-ccd9jwsa.js +4 -0
- package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
- package/dist/chunks/extension-sections-0egb88dm.js +4 -0
- package/dist/chunks/file-ops-qnab36ek.js +4 -0
- package/dist/chunks/files-rcn56qvm.js +4 -0
- package/dist/chunks/format-host-yxz0kjjs.js +4 -0
- package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
- package/dist/chunks/grid-open-4z1g062t.js +4 -0
- package/dist/chunks/grid-view-qg1b5eqx.js +51 -0
- package/dist/chunks/icons-63bjtbs7.js +4 -0
- package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
- package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
- package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
- package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
- package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
- package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
- package/dist/chunks/index-f0jn7nnp.js +4 -0
- package/dist/chunks/{javascript-8nbvs12s.js → javascript-pjp734q4.js} +3 -3
- package/dist/chunks/jsonMode-njkvsa02.js +13 -0
- package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
- package/dist/chunks/layers-bgyr11tr.js +4 -0
- package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
- package/dist/chunks/listbox-c421cf8c.js +4 -0
- package/dist/chunks/lit-html-v9gh687x.js +4 -0
- package/dist/chunks/media-library-sq468wts.js +4 -0
- package/dist/chunks/media-picker-shfe59pt.js +4 -0
- package/dist/chunks/menu-bdpzbfvs.js +4 -0
- package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
- package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
- package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
- package/dist/chunks/notify-kzrjr3fv.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-v77xtwv7.js +4 -0
- package/dist/chunks/platform-7v4rtd7m.js +4 -0
- package/dist/chunks/popover-b89sfej7.js +4 -0
- package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
- package/dist/chunks/publish-quick-qx2455cj.js +4 -0
- package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
- package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
- package/dist/chunks/references-9547rg5s.js +4 -0
- package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/source-control-kwktr9y6.js +4 -0
- package/dist/chunks/split-c9zfdgxf.js +4 -0
- package/dist/chunks/studio-03ct6yfv.js +9 -0
- package/dist/chunks/studio-07rcfje3.js +5 -0
- package/dist/chunks/studio-3e54qh39.js +7 -0
- package/dist/chunks/studio-3exxhz5g.js +5 -0
- package/dist/chunks/studio-3q40e3rj.js +5 -0
- package/dist/chunks/studio-3qeh9t0h.js +6 -0
- package/dist/chunks/studio-3qqjeep5.js +6 -0
- package/dist/chunks/studio-43sd2mam.js +4 -0
- package/dist/chunks/studio-4hp8pkyt.js +5 -0
- package/dist/chunks/studio-58xg6j2q.js +9 -0
- package/dist/chunks/studio-5g0rprdt.js +7 -0
- package/dist/chunks/studio-6m380wp7.js +5 -0
- package/dist/chunks/studio-80jyh1xh.js +4 -0
- package/dist/chunks/studio-83mk4bgg.js +9 -0
- package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
- package/dist/chunks/studio-8m0y2qe7.js +5 -0
- package/dist/chunks/studio-8tr6cfrc.js +5 -0
- package/dist/chunks/studio-8vcvfs7r.js +6 -0
- package/dist/chunks/studio-9tmebf0s.js +5 -0
- package/dist/chunks/studio-a2bvaptz.js +5 -0
- package/dist/chunks/studio-b7y5mr30.js +5 -0
- package/dist/chunks/studio-bavb31r0.js +5 -0
- package/dist/chunks/studio-bbe4c90a.js +5 -0
- package/dist/chunks/studio-c05wdnt3.js +5 -0
- package/dist/chunks/studio-ccv2svc6.js +5 -0
- package/dist/chunks/studio-d5grtb9e.js +16 -0
- package/dist/chunks/studio-df0baea9.js +5 -0
- package/dist/chunks/studio-dgk4dqtx.js +7 -0
- package/dist/chunks/studio-e1g64q43.js +5 -0
- package/dist/chunks/studio-ed1hp6zf.js +6 -0
- package/dist/chunks/studio-ed3xx40h.js +7 -0
- package/dist/chunks/studio-f14e1zdj.js +5 -0
- package/dist/chunks/studio-fbhxxc5f.js +5 -0
- package/dist/chunks/studio-fyh0jc96.js +5 -0
- package/dist/chunks/studio-gcxk20n7.js +5 -0
- package/dist/chunks/studio-jaaz8ce9.js +5 -0
- package/dist/chunks/{studio-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
- package/dist/chunks/studio-jsgf2q5k.js +7 -0
- package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
- package/dist/chunks/studio-k7evxqh4.js +5 -0
- package/dist/chunks/studio-kt3pjkwd.js +5 -0
- package/dist/chunks/studio-m8g16bgz.js +5 -0
- package/dist/chunks/studio-mn0476ag.js +5 -0
- package/dist/chunks/studio-mx1smyq0.js +5 -0
- package/dist/chunks/studio-n0c5h6mf.js +5 -0
- package/dist/chunks/{studio-rv11kfwa.js → studio-nh6d342n.js} +7 -7
- package/dist/chunks/studio-nqxqf8p2.js +4 -0
- package/dist/chunks/studio-p4nrkvqr.js +5 -0
- package/dist/chunks/{studio-h46vtzk8.js → studio-pbxa5fpc.js} +4 -4
- package/dist/chunks/studio-pgmvdv7z.js +7 -0
- package/dist/chunks/studio-ph84avkf.js +5 -0
- package/dist/chunks/{studio-wszjyh0j.js → studio-q0mvbaq6.js} +4 -4
- package/dist/chunks/studio-q0tccd43.js +5 -0
- package/dist/chunks/studio-q7rtx6zq.js +14 -0
- package/dist/chunks/{studio-pre0skq6.js → studio-qgh13jtz.js} +4 -4
- package/dist/chunks/studio-qmn1xc24.js +5 -0
- package/dist/chunks/studio-qwdqwkj0.js +5 -0
- package/dist/chunks/{studio-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
- package/dist/chunks/studio-rj9eamf8.js +5 -0
- package/dist/chunks/studio-rptgsk96.js +5 -0
- package/dist/chunks/studio-rthyg42z.js +928 -0
- package/dist/chunks/studio-s19tp1xr.js +5 -0
- package/dist/chunks/studio-s32578pn.js +5 -0
- package/dist/chunks/studio-svb7yyve.js +5 -0
- package/dist/chunks/studio-syreb644.js +5 -0
- package/dist/chunks/studio-tf9jryb1.js +10 -0
- package/dist/chunks/studio-tfkznv39.js +5 -0
- package/dist/chunks/studio-tft6r105.js +5 -0
- package/dist/chunks/studio-txf2kysx.js +5 -0
- package/dist/chunks/studio-v8867ddv.js +12 -0
- package/dist/chunks/studio-vxq7fcvv.js +5 -0
- package/dist/chunks/studio-w4rz9hdk.js +5 -0
- package/dist/chunks/studio-wbcjbhy1.js +9 -0
- package/dist/chunks/studio-wc649wss.js +5 -0
- package/dist/chunks/studio-wys23mxz.js +5 -0
- package/dist/chunks/studio-x1x167jh.js +5 -0
- package/dist/chunks/studio-x9hsze61.js +5 -0
- package/dist/chunks/studio-y0n7yxea.js +9 -0
- package/dist/chunks/studio-y3ahhdpx.js +5 -0
- package/dist/chunks/studio-z97c48fk.js +5 -0
- package/dist/chunks/studio-zat62m0c.js +5 -0
- package/dist/chunks/studio-zcd2e7yz.js +5 -0
- package/dist/chunks/studio-zz9qe3rw.js +64 -0
- package/dist/chunks/swatch-group-ewh24n1f.js +4 -0
- package/dist/chunks/tabs-f5cw3tgp.js +4 -0
- package/dist/chunks/textfield-wewc8rq2.js +4 -0
- package/dist/chunks/toast-1gv0h53h.js +4 -0
- package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-yypz28gq.js +4 -0
- package/dist/chunks/tree-9xa4hm7n.js +4 -0
- package/dist/chunks/tsMode-epyfz1hv.js +14 -0
- package/dist/chunks/workspace-dz7nxfhv.js +4 -0
- package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
- package/dist/chunks/ws-client-bv552sfx.js +4 -0
- package/dist/iframe-entry.js +20 -16
- package/dist/manifest.json +77 -63
- package/dist/studio.js +106 -107
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +17 -16
- package/src/about/about-modal.ts +4 -3
- package/src/account/action-flow.ts +45 -38
- package/src/account-status.ts +7 -2
- package/src/browse/component-examples.ts +272 -0
- package/src/browse/library-commands.ts +64 -104
- package/src/browse/library-layouts.ts +270 -53
- package/src/browse/library-model.ts +194 -134
- package/src/browse/library-pane.ts +748 -440
- package/src/browse/library-preview.ts +161 -26
- package/src/browse/library-source.ts +308 -41
- package/src/browse/preview-root.ts +78 -0
- package/src/browse/preview-style.ts +155 -0
- package/src/canvas/asset-refs.ts +40 -10
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +260 -77
- package/src/canvas/canvas-origin.ts +37 -12
- package/src/canvas/canvas-page-context.ts +112 -0
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +175 -148
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +147 -61
- package/src/canvas/dialog-path.ts +9 -4
- package/src/canvas/dialog-state.ts +1 -2
- package/src/canvas/diff-marks.ts +9 -16
- package/src/canvas/diff-toolbar.ts +8 -7
- package/src/canvas/edit-width-drag.ts +4 -1
- package/src/canvas/edit-width.ts +1 -3
- package/src/canvas/iframe-channel.ts +27 -13
- package/src/canvas/iframe-drop.ts +120 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +104 -75
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +269 -158
- package/src/canvas/iframe-inline-edit.ts +49 -30
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +30 -25
- package/src/canvas/iframe-keys.ts +11 -0
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +25 -21
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +36 -21
- package/src/canvas/iframe-render.ts +84 -35
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +10 -3
- package/src/canvas/npm-modules.ts +22 -0
- package/src/canvas/path-mapping.ts +19 -12
- package/src/canvas/popover-path.ts +7 -3
- package/src/canvas/popover-state.ts +1 -2
- package/src/canvas/preview-navigate.ts +16 -0
- package/src/canvas/repeater-sources.ts +200 -0
- package/src/canvas/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +7 -2
- package/src/canvas/surface-registry.ts +27 -3
- package/src/collab/collab-commands.ts +7 -2
- package/src/collab/collab-session.ts +84 -45
- package/src/collab/collab-state.ts +4 -3
- package/src/collab/monaco-binding.ts +16 -13
- package/src/collab/monaco-cursors.ts +5 -2
- package/src/commands/app-commands.ts +16 -6
- package/src/commands/budget.ts +13 -11
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +55 -28
- package/src/commands/defaults.ts +69 -45
- package/src/commands/keymap.ts +56 -43
- package/src/commands/levels.ts +14 -8
- package/src/commands/live-context.ts +9 -7
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +22 -11
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +11 -9
- package/src/content/collection-pages.ts +412 -0
- package/src/content/content-collections.ts +270 -0
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +54 -62
- package/src/content/entry-editor.ts +137 -32
- package/src/content/entry-fields.ts +25 -8
- package/src/content/entry-inspector.ts +225 -0
- package/src/content/entry-model.ts +38 -15
- package/src/content/entry-open.ts +80 -0
- package/src/content/entry-summaries.ts +440 -0
- package/src/content/file-record-ids.ts +80 -0
- package/src/content/file-records.ts +125 -0
- package/src/content/page-summaries.ts +129 -0
- package/src/content/record-entry.ts +201 -0
- package/src/content/writing-banner.ts +177 -0
- package/src/create/add-new-commands.ts +185 -0
- package/src/create/add-new-flow.ts +1116 -0
- package/src/create/add-new.ts +1014 -0
- package/src/create/element-name.ts +121 -0
- package/src/editor/canvas-context-menu.ts +1 -2
- package/src/editor/canvas-slash-bridge.ts +3 -6
- package/src/editor/content-slice.ts +16 -14
- package/src/editor/context-menu.ts +35 -22
- package/src/editor/convert-targets.ts +30 -35
- package/src/editor/convert-to-component.ts +78 -48
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +29 -22
- package/src/editor/inline-edit-apply.ts +79 -17
- package/src/editor/inline-edit.ts +76 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-component.ts +91 -0
- package/src/editor/insert-zone-action.ts +14 -5
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +76 -42
- package/src/editor/slash-menu.ts +52 -14
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +89 -20
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +92 -41
- package/src/files/files.ts +248 -239
- package/src/files/fs-events.ts +18 -7
- package/src/files/media-meta.ts +97 -2
- package/src/files/media-paths.ts +3 -0
- package/src/files/media-types.ts +55 -0
- package/src/files/media-upload.ts +209 -52
- package/src/files/new-file-name.ts +156 -0
- package/src/files/serialize-document.ts +15 -5
- package/src/format/constraints.ts +1 -1
- package/src/format/convert-file.ts +27 -13
- package/src/format/format-choices.ts +2 -1
- package/src/format/format-host.ts +91 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +21 -11
- package/src/github/github-publish.ts +28 -23
- package/src/grid/cell-editors.ts +46 -31
- package/src/grid/cell-popovers.ts +5 -3
- package/src/grid/edit-buffer.ts +10 -9
- package/src/grid/grid-controller.ts +25 -23
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -33
- package/src/grid/grid-panel.ts +65 -6
- package/src/grid/grid-reveal.ts +34 -0
- package/src/grid/grid-source.ts +9 -31
- package/src/grid/grid-view.ts +45 -23
- package/src/grid/redirects-grid.ts +14 -5
- package/src/grid/redirects.ts +16 -14
- package/src/grid/schema-columns.ts +25 -19
- package/src/grid/sources/connector-source.ts +47 -20
- package/src/grid/sources/content-source.ts +100 -31
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +61 -34
- package/src/hosting/document.ts +2 -2
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +3 -3
- package/src/media/media-commands.ts +181 -0
- package/src/media/media-library-model.ts +232 -0
- package/src/media/media-library.ts +1283 -0
- package/src/media/media-pane.ts +51 -20
- package/src/new-project/add-repo-modal.ts +20 -19
- package/src/new-project/import-tab.ts +10 -14
- package/src/new-project/location-fields.ts +2 -1
- package/src/new-project/new-project-modal.ts +12 -9
- package/src/packages/jxsuite-update.ts +4 -3
- package/src/packages/pull-package-sync.ts +26 -25
- package/src/page-params.ts +97 -68
- package/src/panels/activity-panel.ts +38 -14
- package/src/panels/ai-chat/attached-context.ts +13 -7
- package/src/panels/ai-chat/chat-markdown.ts +8 -8
- package/src/panels/ai-chat/chat-view.ts +80 -73
- package/src/panels/ai-chat/composer.ts +30 -33
- package/src/panels/ai-chat/sessions-view.ts +1 -2
- package/src/panels/ai-panel.ts +23 -20
- package/src/panels/block-action-bar.ts +57 -46
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +36 -26
- package/src/panels/chat-panel.ts +6 -6
- package/src/panels/collections-panel.ts +306 -0
- package/src/panels/component-preview.ts +35 -13
- package/src/panels/data-explorer.ts +63 -26
- package/src/panels/data-grid.ts +18 -11
- package/src/panels/dnd.ts +115 -138
- package/src/panels/editors.ts +52 -21
- package/src/panels/elements-panel.ts +19 -5
- package/src/panels/empty-state.ts +2 -2
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +78 -54
- package/src/panels/frontmatter-fields.ts +33 -28
- package/src/panels/git-diff-open.ts +10 -6
- package/src/panels/head-panel.ts +488 -202
- package/src/panels/i18n-panel.ts +20 -12
- package/src/panels/imports-panel.ts +25 -47
- package/src/panels/jump-bar.ts +75 -31
- package/src/panels/layers-panel.ts +130 -101
- package/src/panels/left-panel.ts +25 -11
- package/src/panels/navigator-panels.ts +23 -11
- package/src/panels/pane-context.ts +140 -49
- package/src/panels/pane-grid.ts +55 -26
- package/src/panels/panel-registry.ts +36 -46
- package/src/panels/properties-panel.ts +182 -124
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +201 -45
- package/src/panels/seo-modal.ts +54 -125
- package/src/panels/settings-menu.ts +63 -61
- package/src/panels/settings-pane.ts +268 -162
- package/src/panels/signals-panel.ts +156 -135
- package/src/panels/site-model.ts +367 -0
- package/src/panels/site-panel.ts +638 -0
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +253 -206
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +195 -60
- package/src/panels/stylebook-layers-panel.ts +48 -89
- package/src/panels/stylebook-panel.ts +60 -27
- package/src/panels/styles-panel.ts +327 -0
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +143 -49
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +59 -31
- package/src/platforms/cloud.ts +373 -176
- package/src/platforms/default-platform.ts +14 -8
- package/src/platforms/devserver.ts +180 -142
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +20 -9
- package/src/publish/pages-service.ts +66 -27
- package/src/publish/publish-changes.ts +491 -0
- package/src/publish/publish-commands.ts +88 -22
- package/src/publish/publish-ids.ts +49 -0
- package/src/publish/publish-panel.ts +10 -6
- package/src/publish/publish-quick.ts +148 -0
- package/src/publish/publish-workspace.ts +926 -0
- package/src/publish/source-control.ts +907 -0
- package/src/recent-projects.ts +15 -8
- package/src/resize-edges.ts +26 -36
- package/src/services/a11y-report.ts +26 -19
- package/src/services/agent-seed.ts +23 -11
- package/src/services/ai-ask.ts +9 -12
- package/src/services/ai-command-tools.ts +68 -62
- package/src/services/ai-import-tools.ts +80 -67
- package/src/services/ai-models.ts +17 -13
- package/src/services/ai-project-tools.ts +68 -32
- package/src/services/ai-session-store.ts +19 -10
- package/src/services/ai-system-prompt.ts +46 -20
- package/src/services/ai-tools.ts +71 -27
- package/src/services/ai-write-report.ts +20 -12
- package/src/services/ai-writes.ts +4 -4
- package/src/services/automation.ts +74 -51
- package/src/services/cem-export.ts +149 -58
- package/src/services/cf-settings.ts +4 -4
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- package/src/services/connection.ts +2 -2
- package/src/services/context-manager.ts +14 -10
- package/src/services/context-resolver.ts +20 -8
- package/src/services/data-service.ts +19 -15
- package/src/services/directory-picker.ts +20 -14
- package/src/services/document-assistant.ts +39 -19
- package/src/services/gated-registry.ts +10 -6
- package/src/services/harness/chat-reducer.ts +23 -1
- package/src/services/import-client.ts +91 -38
- package/src/services/import-seed.ts +8 -2
- package/src/services/jx-validate.ts +28 -31
- package/src/services/live-preview.ts +0 -0
- package/src/services/live-surfaces.ts +6 -3
- package/src/services/model-uri.ts +10 -2
- package/src/services/module-preloads.ts +12 -8
- package/src/services/monaco-buffer.ts +43 -24
- package/src/services/monaco-lazy.ts +7 -8
- package/src/services/monaco-setup.ts +23 -16
- package/src/services/notify.ts +44 -17
- package/src/services/popover-report.ts +25 -10
- package/src/services/preview-eval.ts +20 -8
- package/src/services/profile.ts +13 -6
- package/src/services/project-path.ts +13 -10
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +29 -9
- package/src/services/settings/definitions.ts +25 -14
- package/src/services/settings/kernel.ts +13 -4
- package/src/services/settings/write-queue.ts +9 -9
- package/src/services/token-lint.ts +12 -10
- package/src/services/tool-executor.ts +17 -5
- package/src/services/tool-outcomes.ts +44 -24
- package/src/services/trusted-types.ts +24 -7
- package/src/settings/contexts-section.ts +11 -8
- package/src/settings/contributed-section.ts +128 -70
- package/src/settings/css-vars-editor.ts +119 -32
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/developer-panels.ts +43 -0
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +42 -14
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +101 -28
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +17 -7
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +28 -11
- package/src/settings/schema-field-ui.ts +12 -1
- package/src/settings/section-registry.ts +116 -11
- package/src/settings/settings-dialog.ts +192 -0
- package/src/settings/settings-document.ts +186 -166
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +536 -477
- package/src/site-context.ts +101 -32
- package/src/state.ts +68 -57
- package/src/store.ts +54 -34
- package/src/studio.ts +219 -116
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +40 -7
- package/src/style/stylebook-specimens.ts +89 -0
- package/src/style/stylebook-target.ts +26 -0
- package/src/style/tag-inheritance.ts +105 -0
- package/src/style/token-ref.ts +5 -4
- package/src/style/variables-focus.ts +61 -0
- package/src/style/variables-view.ts +235 -0
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-new.json +1482 -0
- package/src/surfaces/add-new.ts +325 -0
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +33 -38
- package/src/surfaces/ai-credentials-form.ts +6 -16
- package/src/surfaces/ai-managed-connect.ts +3 -4
- package/src/surfaces/ai-model-picker.ts +3 -5
- package/src/surfaces/block-action-bar.ts +22 -11
- package/src/surfaces/boot-failure.json +4 -3
- package/src/surfaces/boot-failure.ts +4 -5
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.json +30 -19
- package/src/surfaces/canvas-stage.ts +17 -16
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/collections-panel.json +615 -0
- package/src/surfaces/collections-panel.ts +168 -0
- package/src/surfaces/commandbar.json +241 -96
- package/src/surfaces/commandbar.ts +145 -105
- package/src/surfaces/convert-repeater.ts +17 -19
- package/src/surfaces/data-actions.ts +9 -7
- package/src/surfaces/dialog.ts +26 -28
- package/src/surfaces/diff-toolbar.ts +9 -7
- package/src/surfaces/empty-state.json +1 -1
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.json +136 -0
- package/src/surfaces/entry-editor.ts +35 -11
- package/src/surfaces/entry-inspector.json +371 -0
- package/src/surfaces/entry-inspector.ts +143 -0
- package/src/surfaces/expression-editor.ts +11 -25
- package/src/surfaces/files-panel.ts +27 -14
- package/src/surfaces/formula-palette.ts +4 -5
- package/src/surfaces/github-auth.ts +16 -20
- package/src/surfaces/github-publish.ts +17 -22
- package/src/surfaces/grid-cell.ts +30 -31
- package/src/surfaces/grid-open.ts +10 -14
- package/src/surfaces/grid-panel.ts +13 -9
- package/src/surfaces/grid-replace.ts +13 -13
- package/src/surfaces/grid-views.ts +15 -18
- package/src/surfaces/inspector-dock.json +162 -14
- package/src/surfaces/inspector-dock.ts +59 -31
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.json +670 -437
- package/src/surfaces/library-pane.ts +111 -77
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.json +62 -6
- package/src/surfaces/media-browser.ts +26 -11
- package/src/surfaces/media-field.json +1 -1
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-library.json +1586 -0
- package/src/surfaces/media-library.ts +282 -0
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/media-pick-dialog.json +71 -0
- package/src/surfaces/media-pick-dialog.ts +132 -0
- package/src/surfaces/menu.ts +47 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.json +144 -77
- package/src/surfaces/pane-context.ts +44 -25
- package/src/surfaces/pane-grid.ts +15 -10
- package/src/surfaces/panel-activity.ts +5 -6
- package/src/surfaces/panel-data.ts +3 -4
- package/src/surfaces/panel-deploy-checklist.json +12 -6
- package/src/surfaces/panel-deploy-checklist.ts +8 -7
- package/src/surfaces/panel-elements.ts +5 -7
- package/src/surfaces/panel-i18n.ts +5 -7
- package/src/surfaces/panel-imports.ts +6 -13
- package/src/surfaces/panel-outline.ts +25 -19
- package/src/surfaces/panel-page.json +72 -2
- package/src/surfaces/panel-page.ts +49 -25
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.json +1 -1
- package/src/surfaces/panel-signals.ts +25 -39
- package/src/surfaces/panel-stylebook-layers.json +71 -204
- package/src/surfaces/panel-stylebook-layers.ts +5 -29
- package/src/surfaces/preferences.json +120 -48
- package/src/surfaces/preferences.ts +29 -11
- package/src/surfaces/progress-modal.ts +15 -9
- package/src/surfaces/properties-panel.json +1 -1
- package/src/surfaces/properties-panel.ts +20 -42
- package/src/surfaces/publish-quick.json +428 -0
- package/src/surfaces/publish-quick.ts +165 -0
- package/src/surfaces/publish-workspace.json +2892 -0
- package/src/surfaces/publish-workspace.ts +391 -0
- package/src/surfaces/publish.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.json +1 -159
- package/src/surfaces/rail.ts +22 -79
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.json +10 -2
- package/src/surfaces/schema-form.ts +17 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.json +5 -5
- package/src/surfaces/settings-contributed.ts +32 -12
- package/src/surfaces/settings-css-vars.json +44 -36
- package/src/surfaces/settings-css-vars.ts +82 -16
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.json +2 -15
- package/src/surfaces/settings-deploy.ts +9 -16
- package/src/surfaces/settings-dialog.json +51 -0
- package/src/surfaces/settings-dialog.ts +169 -0
- package/src/surfaces/settings-extensions.ts +5 -6
- package/src/surfaces/settings-head.ts +33 -39
- package/src/surfaces/settings-locales.ts +8 -20
- package/src/surfaces/settings-overview.json +3 -3
- package/src/surfaces/settings-overview.ts +14 -8
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.json +269 -46
- package/src/surfaces/settings-pane.ts +88 -36
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.json +2 -1
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/site-panel.json +1029 -0
- package/src/surfaces/site-panel.ts +233 -0
- package/src/surfaces/slash-menu.json +63 -21
- package/src/surfaces/slash-menu.ts +42 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +56 -29
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/styles-panel.json +735 -0
- package/src/surfaces/styles-panel.ts +195 -0
- package/src/surfaces/styles-variables.json +149 -0
- package/src/surfaces/styles-variables.ts +145 -0
- package/src/surfaces/tab-strip.json +4 -4
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +6 -8
- package/src/surfaces/writing-banner.json +94 -0
- package/src/surfaces/writing-banner.ts +80 -0
- package/src/tabs/bare-repeaters.ts +101 -0
- package/src/tabs/patch-ops.ts +4 -3
- package/src/tabs/project-config.ts +32 -21
- package/src/tabs/selection.ts +36 -8
- package/src/tabs/tab.ts +99 -48
- package/src/tabs/transact.ts +98 -53
- package/src/types.ts +53 -43
- package/src/ui/ai-credentials-form.ts +10 -13
- package/src/ui/ai-model-picker.ts +3 -3
- package/src/ui/cf-account-picker.ts +7 -9
- package/src/ui/color-selector.ts +9 -5
- package/src/ui/dynamic-slot.ts +7 -8
- package/src/ui/expression-editor.ts +112 -105
- package/src/ui/form-controls.ts +104 -56
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +57 -31
- package/src/ui/media-picker.ts +300 -47
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +14 -12
- package/src/ui/schema-form.ts +372 -97
- package/src/ui/surface.ts +71 -8
- package/src/ui/timing.ts +9 -0
- package/src/ui/value-source.ts +44 -31
- package/src/ui/virtual-window.ts +29 -3
- package/src/utils/base64.ts +6 -4
- package/src/utils/edit-display.ts +366 -111
- package/src/utils/element-selectors.ts +3 -2
- package/src/utils/google-fonts.ts +15 -14
- package/src/utils/inherited-style.ts +18 -20
- package/src/utils/link-target.ts +1 -1
- package/src/utils/local-day.ts +18 -0
- package/src/utils/preview-format.ts +25 -3
- package/src/utils/strip-events.ts +49 -22
- package/src/utils/studio-utils.ts +29 -14
- package/src/view.ts +2 -3
- package/src/workspace/pane-derive.ts +14 -16
- package/src/workspace/session.ts +81 -50
- package/src/workspace/tab-workspace.ts +137 -0
- package/src/workspace/workspace-back.ts +189 -0
- package/src/workspace/workspace-home.ts +133 -0
- package/src/workspace/workspace-ids.ts +129 -0
- package/src/workspace/workspace-switch.ts +372 -0
- package/src/workspace/workspace.ts +165 -47
- package/styles/shell-frame.css +30 -7
- package/styles/shell-frame.json +15 -3
- package/dist/chunks/2020-va2wwra4.js +0 -4
- package/dist/chunks/adapter-f93pafd7.js +0 -4
- package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
- package/dist/chunks/cf-settings-125tdm0w.js +0 -4
- package/dist/chunks/color-area-jqhna8zy.js +0 -4
- package/dist/chunks/color-field-embq5ctg.js +0 -4
- package/dist/chunks/color-fpezvnkt.js +0 -4
- package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
- package/dist/chunks/combobox-773hdzyj.js +0 -4
- package/dist/chunks/components-ax2f1fnn.js +0 -4
- package/dist/chunks/content-source-108aqtk1.js +0 -4
- package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-pfgdmkb0.js +0 -4
- package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
- package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
- package/dist/chunks/file-ops-meej5mqf.js +0 -4
- package/dist/chunks/files-44vp8a2s.js +0 -4
- package/dist/chunks/format-host-7q1petb9.js +0 -4
- package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
- package/dist/chunks/git-panel-zngbymvd.js +0 -4
- package/dist/chunks/grid-view-sx9vynsp.js +0 -51
- package/dist/chunks/icons-p44xhjf0.js +0 -4
- package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
- package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
- package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
- package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
- package/dist/chunks/index-wkyfjeqz.js +0 -4
- package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
- package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
- package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
- package/dist/chunks/layers-xd92fg8d.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
- package/dist/chunks/media-picker-0svzkdyb.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/menu-5c55ea3d.js +0 -4
- package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
- package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
- package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
- package/dist/chunks/notify-0xgtn8q1.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-v1qctbe6.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
- package/dist/chunks/quick-search-a54e6t5n.js +0 -4
- package/dist/chunks/references-gmqp82fs.js +0 -4
- package/dist/chunks/right-panel-v7t9awbk.js +0 -4
- package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0bhx5hz6.js +0 -5
- package/dist/chunks/studio-0k1ddnyy.js +0 -6
- package/dist/chunks/studio-1b04pd0j.js +0 -64
- package/dist/chunks/studio-4dwbj6gb.js +0 -5
- package/dist/chunks/studio-4tanh828.js +0 -5
- package/dist/chunks/studio-55h4mstj.js +0 -4
- package/dist/chunks/studio-5tnvjkz4.js +0 -5
- package/dist/chunks/studio-60dqgb0c.js +0 -5
- package/dist/chunks/studio-61dp09qg.js +0 -9
- package/dist/chunks/studio-63epcrj2.js +0 -5
- package/dist/chunks/studio-74k29dy9.js +0 -5
- package/dist/chunks/studio-7vg6jcd3.js +0 -5
- package/dist/chunks/studio-7zx31knw.js +0 -9
- package/dist/chunks/studio-8bxk97km.js +0 -5
- package/dist/chunks/studio-933e30n4.js +0 -5
- package/dist/chunks/studio-98wnwhbg.js +0 -5
- package/dist/chunks/studio-9mccjwjh.js +0 -14
- package/dist/chunks/studio-a2ke1e4t.js +0 -5
- package/dist/chunks/studio-e3a2a6v3.js +0 -4
- package/dist/chunks/studio-e81q1vb9.js +0 -5
- package/dist/chunks/studio-epgrmqqm.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-g1shz58g.js +0 -5
- package/dist/chunks/studio-gf0fz03c.js +0 -5
- package/dist/chunks/studio-gjtpe62q.js +0 -6
- package/dist/chunks/studio-gkskhg7m.js +0 -5
- package/dist/chunks/studio-gx4dnjzd.js +0 -5
- package/dist/chunks/studio-j03zga3y.js +0 -9
- package/dist/chunks/studio-jhpxeckz.js +0 -5
- package/dist/chunks/studio-k01r7ykp.js +0 -5
- package/dist/chunks/studio-kk7h30ne.js +0 -7
- package/dist/chunks/studio-kt1zqney.js +0 -5
- package/dist/chunks/studio-m3cwhvye.js +0 -5
- package/dist/chunks/studio-mcayt6hz.js +0 -5
- package/dist/chunks/studio-myjcghv3.js +0 -5
- package/dist/chunks/studio-n8bxwc3y.js +0 -4
- package/dist/chunks/studio-ngm8gvpb.js +0 -5
- package/dist/chunks/studio-nj5a01jy.js +0 -928
- package/dist/chunks/studio-pcgz8heb.js +0 -5
- package/dist/chunks/studio-qcsq0t15.js +0 -5
- package/dist/chunks/studio-qkstvve9.js +0 -5
- package/dist/chunks/studio-qv1pwd3c.js +0 -5
- package/dist/chunks/studio-rc6dvxjb.js +0 -7
- package/dist/chunks/studio-s8dmmz66.js +0 -5
- package/dist/chunks/studio-sp5xzbj4.js +0 -6
- package/dist/chunks/studio-szsjbj0g.js +0 -5
- package/dist/chunks/studio-t1xzawhr.js +0 -16
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- package/dist/chunks/studio-vrmcjf9g.js +0 -7
- package/dist/chunks/studio-vyc0b4he.js +0 -10
- package/dist/chunks/studio-w0cgf6jg.js +0 -5
- package/dist/chunks/studio-w3hskzqk.js +0 -5
- package/dist/chunks/studio-xgrgcdyh.js +0 -9
- package/dist/chunks/studio-xz2yxfcb.js +0 -5
- package/dist/chunks/studio-y6n42tgs.js +0 -5
- package/dist/chunks/studio-yb560vxr.js +0 -5
- package/dist/chunks/studio-yn9f8vtx.js +0 -5
- package/dist/chunks/studio-yw05w8f0.js +0 -7
- package/dist/chunks/studio-z16sgavc.js +0 -5
- package/dist/chunks/studio-zey7zsdw.js +0 -12
- package/dist/chunks/studio-zyqn40w4.js +0 -5
- package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
- package/dist/chunks/tabs-jwthg40w.js +0 -4
- package/dist/chunks/textfield-spy3hc77.js +0 -4
- package/dist/chunks/toast-4d35zd64.js +0 -4
- package/dist/chunks/toast-host-8sjmfed3.js +0 -4
- package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
- package/dist/chunks/tree-h19v1jfz.js +0 -4
- package/dist/chunks/tsMode-2frah6h1.js +0 -14
- package/dist/chunks/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
- package/src/panels/frontmatter-panel.ts +0 -701
- package/src/panels/git-panel.ts +0 -1120
- package/src/surfaces/doc-header.json +0 -776
- package/src/surfaces/doc-header.ts +0 -231
- package/src/surfaces/git-panel.json +0 -1880
- package/src/surfaces/git-panel.ts +0 -272
|
@@ -17,6 +17,7 @@ import { allCanvasSurfaces, stageContaining, surfaceForPane } from "./surface-re
|
|
|
17
17
|
import type { CanvasSurface } from "./surface-registry";
|
|
18
18
|
import type { PaneDerivation } from "../workspace/workspace";
|
|
19
19
|
import type { CanvasPanel } from "../types";
|
|
20
|
+
import type { UnboundCanvasPanel } from "./canvas-utils";
|
|
20
21
|
import type { Tab } from "../tabs/tab";
|
|
21
22
|
|
|
22
23
|
export {
|
|
@@ -149,11 +150,12 @@ export function panelHostingCanvas(
|
|
|
149
150
|
* answers with the FOCUSED pane's tab, which is a different document the moment the click is in a
|
|
150
151
|
* pane the keyboard is not in.
|
|
151
152
|
*
|
|
152
|
-
* @param {
|
|
153
|
+
* @param {UnboundCanvasPanel} panel
|
|
153
154
|
* @returns {Tab | null}
|
|
154
155
|
*/
|
|
155
|
-
export function tabOfMountedPanel(panel:
|
|
156
|
-
|
|
156
|
+
export function tabOfMountedPanel(panel: UnboundCanvasPanel): Tab | null {
|
|
157
|
+
// An unbound board (no canvas node yet) has no pane mounting it.
|
|
158
|
+
const canvasEl = panel.canvas;
|
|
157
159
|
const mounted = canvasEl ? panelHostingCanvas(canvasEl) : null;
|
|
158
160
|
return mounted ? tabOfPane(mounted.surface.paneId) : null;
|
|
159
161
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* template creation, centering, transform application, zoom indicator, and fit-to-screen.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { CanvasPanel
|
|
7
|
+
import type { CanvasPanel } from "../types";
|
|
8
8
|
|
|
9
9
|
import { renderOnly } from "../store";
|
|
10
10
|
import {
|
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
import type { CanvasStageHandle, CanvasStagePanelItem } from "../surfaces/canvas-stage";
|
|
40
40
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
41
41
|
import type { CommandArgValues } from "../commands/command-args";
|
|
42
|
+
import { isNumber, isString } from "@jxsuite/schema/guards";
|
|
42
43
|
import type { Tab } from "../tabs/tab";
|
|
43
44
|
|
|
44
45
|
/*
|
|
@@ -106,6 +107,22 @@ function setZoomOf(surface: CanvasSurface, zoom: number): void {
|
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
110
|
+
/** The {@link CanvasPanel} fields that hold the board's drawn nodes. */
|
|
111
|
+
type CanvasPanelNodeKey = "canvas" | "element" | "scrollContainer" | "viewport";
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* A panel record as it may be before {@link bindCanvasPanels} has run: its DOM fields can still be
|
|
115
|
+
* null, because {@link canvasPanelEntry} builds them that way. A bound {@link CanvasPanel} is
|
|
116
|
+
* assignable to it, so a reader that must tolerate an unbound board takes this type.
|
|
117
|
+
*/
|
|
118
|
+
export type UnboundCanvasPanel = Omit<CanvasPanel, CanvasPanelNodeKey> &
|
|
119
|
+
Record<CanvasPanelNodeKey, HTMLElement | null>;
|
|
120
|
+
|
|
121
|
+
/** Whether the stage has wired a board's canvas and viewport nodes into its record yet. */
|
|
122
|
+
export function isPanelBound(panel: UnboundCanvasPanel): boolean {
|
|
123
|
+
return Boolean(panel.canvas && panel.viewport);
|
|
124
|
+
}
|
|
125
|
+
|
|
109
126
|
/**
|
|
110
127
|
* One artboard: the record the geometry reads, and the item the stage document draws.
|
|
111
128
|
*
|
|
@@ -139,7 +156,7 @@ export function canvasPanelEntry(
|
|
|
139
156
|
fullWidth: boolean,
|
|
140
157
|
width: number | null = null,
|
|
141
158
|
): CanvasPanelEntry {
|
|
142
|
-
const
|
|
159
|
+
const unbound: UnboundCanvasPanel = {
|
|
143
160
|
_width: width || null,
|
|
144
161
|
canvas: null,
|
|
145
162
|
element: null,
|
|
@@ -148,7 +165,11 @@ export function canvasPanelEntry(
|
|
|
148
165
|
renderScope: null,
|
|
149
166
|
scrollContainer: null,
|
|
150
167
|
viewport: null,
|
|
151
|
-
}
|
|
168
|
+
};
|
|
169
|
+
/* SAFETY: the record is handed out unbound and filled in place by `bindCanvasPanels` once the
|
|
170
|
+
stage has drawn it; every reader that can run before that (`tabOfMountedPanel`, `applyEditZoom`,
|
|
171
|
+
`updateActivePanelHeaders`) reads it as an UnboundCanvasPanel and checks the nodes first. */
|
|
172
|
+
const panel = unbound as CanvasPanel;
|
|
152
173
|
/* The viewport takes the declared width, the canvas takes it too — but a FULL-WIDTH board's
|
|
153
174
|
viewport does not, because "full width" means "as wide as the box you are in". Carried as two
|
|
154
175
|
custom properties rather than as `width:` so `applyEditZoom`'s inline write on the canvas still
|
|
@@ -186,9 +207,13 @@ export function canvasPanelEntry(
|
|
|
186
207
|
*/
|
|
187
208
|
export function bindCanvasPanels(entries: CanvasPanelEntry[], stage: CanvasStageHandle): void {
|
|
188
209
|
for (const { item, panel } of entries) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
210
|
+
/* SAFETY: callers bind only after `drawStage` has settled, and the stage document draws the
|
|
211
|
+
`panel`, `panel-viewport` and `panel-canvas` parts for every item it was given, keyed by
|
|
212
|
+
`item.key`, so each lookup finds its node. */
|
|
213
|
+
const node = (part: string) => stage.panelNode(item.key, part) as HTMLElement;
|
|
214
|
+
panel.element = node("panel");
|
|
215
|
+
panel.viewport = node("panel-viewport");
|
|
216
|
+
panel.canvas = node("panel-canvas");
|
|
192
217
|
}
|
|
193
218
|
}
|
|
194
219
|
|
|
@@ -232,8 +257,10 @@ export function centerCanvas(surface: CanvasSurface) {
|
|
|
232
257
|
const wrapWidth = surface.wrap.clientWidth;
|
|
233
258
|
const contentWidth = surface.panzoomWrap.scrollWidth;
|
|
234
259
|
const zoom = zoomOf(surface);
|
|
235
|
-
const
|
|
236
|
-
|
|
260
|
+
const free = wrapWidth - contentWidth * zoom;
|
|
261
|
+
/* Content that fits is centred, however little room is left over: a 16px floor on a fitted page
|
|
262
|
+
pushed its right edge 16px past the pane. Content wider than the pane starts 16px in. */
|
|
263
|
+
surface.panX = free >= 0 ? free / 2 : 16;
|
|
237
264
|
surface.panY = 0;
|
|
238
265
|
}
|
|
239
266
|
|
|
@@ -349,7 +376,7 @@ export function applyEditZoom(
|
|
|
349
376
|
return;
|
|
350
377
|
}
|
|
351
378
|
const [panel] = surface.panels;
|
|
352
|
-
if (!panel
|
|
379
|
+
if (!panel || !isPanelBound(panel)) {
|
|
353
380
|
return;
|
|
354
381
|
}
|
|
355
382
|
const canvasEl = panel.canvas;
|
|
@@ -458,6 +485,14 @@ export function requestEditZoom(
|
|
|
458
485
|
);
|
|
459
486
|
}
|
|
460
487
|
|
|
488
|
+
/** The screen pixels a stage reserves above its boards (`--boards-inset`), or 0 for none. */
|
|
489
|
+
export function boardsInset(panzoomWrap: HTMLElement): number {
|
|
490
|
+
// The inset is declared in px (`--boards-inset:40px`); unset reads as "", which is no inset.
|
|
491
|
+
const declared = getComputedStyle(panzoomWrap).getPropertyValue("--boards-inset").trim();
|
|
492
|
+
const inset = Number(declared.replace(/px$/, ""));
|
|
493
|
+
return Number.isFinite(inset) ? inset : 0;
|
|
494
|
+
}
|
|
495
|
+
|
|
461
496
|
/**
|
|
462
497
|
* Compute and apply a geometric fit. Pure arithmetic — it declares nothing.
|
|
463
498
|
*
|
|
@@ -470,7 +505,9 @@ function applyGeometricFit(surface: CanvasSurface, axis: "width" | "page", maxZo
|
|
|
470
505
|
return;
|
|
471
506
|
}
|
|
472
507
|
const wrapWidth = surface.wrap.clientWidth;
|
|
473
|
-
|
|
508
|
+
// The boards' own top clearance (`--boards-inset`, the Project Styles bar) is screen space the
|
|
509
|
+
// Artboards cannot use, so the page is fitted into what is left below it.
|
|
510
|
+
const wrapHeight = surface.wrap.clientHeight - boardsInset(surface.panzoomWrap);
|
|
474
511
|
const gap = 24;
|
|
475
512
|
const padding = 32;
|
|
476
513
|
let totalPanelWidth = 0;
|
|
@@ -571,12 +608,12 @@ export const FIT_WORDS: readonly string[] = ["width", "page", "none"];
|
|
|
571
608
|
* assistant sees. It stays as the typed read the body needs (`args.fit` is `unknown`) and as the
|
|
572
609
|
* refusal for a caller that reaches the body directly.
|
|
573
610
|
*/
|
|
574
|
-
function fitArg(commandId: string, args:
|
|
611
|
+
function fitArg(commandId: string, args: CommandArgValues, key: string): FitMode {
|
|
575
612
|
const value = args[key];
|
|
576
|
-
if (
|
|
577
|
-
return value
|
|
613
|
+
if (isFitWord(value)) {
|
|
614
|
+
return value;
|
|
578
615
|
}
|
|
579
|
-
if (
|
|
616
|
+
if (isNumber(value) && value >= PAN_ZOOM_MIN && value <= PAN_ZOOM_MAX) {
|
|
580
617
|
return value;
|
|
581
618
|
}
|
|
582
619
|
throw new RangeError(
|
|
@@ -585,6 +622,11 @@ function fitArg(commandId: string, args: Record<string, unknown>, key: string):
|
|
|
585
622
|
);
|
|
586
623
|
}
|
|
587
624
|
|
|
625
|
+
/** Whether a value is one of {@link FIT_WORDS}, the named (non-scale) fits. */
|
|
626
|
+
function isFitWord(value: unknown): value is Exclude<FitMode, number> {
|
|
627
|
+
return isString(value) && FIT_WORDS.includes(value);
|
|
628
|
+
}
|
|
629
|
+
|
|
588
630
|
/** Declared fits, keyed per tab + document. */
|
|
589
631
|
const _fits = new Map<string, FitMode>();
|
|
590
632
|
|
|
@@ -641,7 +683,7 @@ export function applyFit(fit?: FitMode, surface: CanvasSurface = activeCanvasSur
|
|
|
641
683
|
applyTransform(surface);
|
|
642
684
|
return;
|
|
643
685
|
}
|
|
644
|
-
if (
|
|
686
|
+
if (isNumber(chosen)) {
|
|
645
687
|
setZoomOf(surface, clampPanZoom(chosen));
|
|
646
688
|
applyTransform(surface);
|
|
647
689
|
return;
|
|
@@ -733,11 +775,12 @@ export function resetZoom(surface: CanvasSurface = activeCanvasSurface()) {
|
|
|
733
775
|
* hands a rect back), so one arithmetic serves a rect measured from a parent DOM element and a rect
|
|
734
776
|
* measured inside a canvas iframe alike.
|
|
735
777
|
*
|
|
736
|
-
* **The viewport is the box that SCROLLS, not the stage.**
|
|
737
|
-
* above its scroller, inside the same stage cell, so there the stage is the
|
|
738
|
-
* its centre is half a
|
|
739
|
-
* what the author can actually see. {@link revealScroller} is that box wherever
|
|
740
|
-
* where there is none (Design, Stylebook, a comparison) the stage is still the
|
|
778
|
+
* **The viewport is the box that SCROLLS, not the stage.** Over a collection entry Edit stands the
|
|
779
|
+
* writing banner above its scroller, inside the same stage cell, so there the stage is the banner
|
|
780
|
+
* plus the page and its centre is half a banner too high: a reveal would land the node that far
|
|
781
|
+
* above the middle of what the author can actually see. {@link revealScroller} is that box wherever
|
|
782
|
+
* there is one, and where there is none (Design, Stylebook, a comparison) the stage is still the
|
|
783
|
+
* viewport.
|
|
741
784
|
*/
|
|
742
785
|
function centeringOffset(surface: CanvasSurface, rect: { top: number; height: number }): number {
|
|
743
786
|
const viewport = rectOf(revealScroller(surface) ?? surface.wrap);
|
|
@@ -810,6 +853,37 @@ export function panToParentRect(
|
|
|
810
853
|
revealBy(surface, centeringOffset(surface, rect), false);
|
|
811
854
|
}
|
|
812
855
|
|
|
856
|
+
/**
|
|
857
|
+
* Bring a PARENT-VIEWPORT rect into view on a pan/zoom stage, moving as little as it must: not at
|
|
858
|
+
* all when the rect is already wholly in view, and never so far that the boards' top edge comes
|
|
859
|
+
* down past where it stands now.
|
|
860
|
+
*
|
|
861
|
+
* {@link panToParentRect} always centres, which is right for a jump to a diff change or a node the
|
|
862
|
+
* author asked to see. The stylebook's Outline is a list the author clicks DOWN, and centring its
|
|
863
|
+
* first rows meant the h1 at the very top of a fitted catalogue pulled every board half a pane
|
|
864
|
+
* down, leaving an empty band above them and no specimen that had moved into view.
|
|
865
|
+
*/
|
|
866
|
+
export function revealParentRect(
|
|
867
|
+
rect: { top: number; height: number },
|
|
868
|
+
surface: CanvasSurface = activeCanvasSurface(),
|
|
869
|
+
) {
|
|
870
|
+
const viewport = rectOf(surface.wrap);
|
|
871
|
+
if (rect.top >= viewport.top && rect.top + rect.height <= viewport.top + viewport.height) {
|
|
872
|
+
return;
|
|
873
|
+
}
|
|
874
|
+
const offset = centeringOffset(surface, rect);
|
|
875
|
+
const ceiling = Math.max(surface.panY, 0) - surface.panY;
|
|
876
|
+
const step = Math.min(offset, ceiling);
|
|
877
|
+
if (step !== 0) {
|
|
878
|
+
/* A reveal is a pan somebody asked for, so the entry's centring stands down as a user's pan
|
|
879
|
+
makes it: a frame still growing to its height would otherwise re-centre the stage (top
|
|
880
|
+
aligned) under the card just brought on screen, which is what a reveal on a fresh stylebook
|
|
881
|
+
canvas did. */
|
|
882
|
+
surface.needsCenter = false;
|
|
883
|
+
animatePanBy(surface, step);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
|
|
813
887
|
/** Animate a stage's `panY` by `offsetY` with the shared 250ms ease-out. */
|
|
814
888
|
function animatePanBy(surface: CanvasSurface, offsetY: number) {
|
|
815
889
|
const startY = surface.panY;
|
|
@@ -844,6 +918,7 @@ export const CANVAS_MODES = [
|
|
|
844
918
|
"preview",
|
|
845
919
|
"source",
|
|
846
920
|
"stylebook",
|
|
921
|
+
"tokens",
|
|
847
922
|
"grid",
|
|
848
923
|
"git-diff",
|
|
849
924
|
] as const;
|
|
@@ -853,6 +928,11 @@ export type CanvasMode = (typeof CANVAS_MODES)[number];
|
|
|
853
928
|
/** The base modes the preview flag composes with — the two the Canvas view axis shows it beside. */
|
|
854
929
|
const PREVIEWABLE_BASE_MODES = new Set(["edit", "design"]);
|
|
855
930
|
|
|
931
|
+
/** Whether a base mode is one the preview flag composes with: a member of PREVIEWABLE_BASE_MODES. */
|
|
932
|
+
function isPreviewableBase(mode: string): mode is "edit" | "design" {
|
|
933
|
+
return PREVIEWABLE_BASE_MODES.has(mode);
|
|
934
|
+
}
|
|
935
|
+
|
|
856
936
|
// ─── The Canvas view (§4.2) ──────────────────────────────────────────────────
|
|
857
937
|
// `Edit │ Design` is a radio and `Preview` is a TOGGLE beside it, because that is what the storage
|
|
858
938
|
// Has always been: `preview` is not a base mode, it is a flag that composes with one.
|
|
@@ -913,7 +993,13 @@ export function canvasBaseViewsFor(tab: ViewableTab): CanvasView[] {
|
|
|
913
993
|
/** The base view the tab returns to — what the radio marks while preview is on. */
|
|
914
994
|
export function canvasBaseViewOf(tab: ViewableTab): CanvasView | null {
|
|
915
995
|
const base = tab.session.ui.canvasMode;
|
|
916
|
-
return
|
|
996
|
+
return isPreviewableBase(base) ? base : null;
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
/** A tab's Preview toggle: whether it is offered, and whether it is pressed. */
|
|
1000
|
+
export interface PreviewState {
|
|
1001
|
+
available: boolean;
|
|
1002
|
+
on: boolean;
|
|
917
1003
|
}
|
|
918
1004
|
|
|
919
1005
|
/**
|
|
@@ -922,7 +1008,7 @@ export function canvasBaseViewOf(tab: ViewableTab): CanvasView | null {
|
|
|
922
1008
|
* `available` is a fact about the DOCUMENT (its declared modes) and about the base it is currently
|
|
923
1009
|
* in — `source` composes with no preview, so the toggle is not offered there.
|
|
924
1010
|
*/
|
|
925
|
-
export function previewStateOf(tab: ViewableTab):
|
|
1011
|
+
export function previewStateOf(tab: ViewableTab): PreviewState {
|
|
926
1012
|
return {
|
|
927
1013
|
available:
|
|
928
1014
|
tab.capabilities.modes.includes("preview") &&
|
|
@@ -1041,7 +1127,7 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1041
1127
|
* than the control it replaced, which is the opposite of the point.
|
|
1042
1128
|
*/
|
|
1043
1129
|
function contextTab(commandId: string, args: CommandArgValues) {
|
|
1044
|
-
const { pane } = args
|
|
1130
|
+
const { pane } = args;
|
|
1045
1131
|
if (pane === undefined) {
|
|
1046
1132
|
return requireTab(commandId);
|
|
1047
1133
|
}
|
|
@@ -1073,8 +1159,8 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1073
1159
|
|
|
1074
1160
|
/** The pane a rendering-context verb addresses, named or focused. {@link repaint}'s own rule. */
|
|
1075
1161
|
function paneOfArgs(args: CommandArgValues): string {
|
|
1076
|
-
const { pane } = args
|
|
1077
|
-
return
|
|
1162
|
+
const { pane } = args;
|
|
1163
|
+
return isString(pane) ? pane : workspace.activePaneId;
|
|
1078
1164
|
}
|
|
1079
1165
|
|
|
1080
1166
|
return [
|
|
@@ -1103,7 +1189,7 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1103
1189
|
description:
|
|
1104
1190
|
"Switch the active document's editor mode. edit and design put its element tree on " +
|
|
1105
1191
|
"the canvas, where the document tools work; preview renders it as a visitor sees it; " +
|
|
1106
|
-
"source shows the JSON; stylebook, grid and git-diff open other editors. Use it to " +
|
|
1192
|
+
"source shows the JSON; stylebook, tokens, grid and git-diff open other editors. Use it to " +
|
|
1107
1193
|
"return a document to edit or design when the tree tools are refused.",
|
|
1108
1194
|
name: "set_canvas_mode",
|
|
1109
1195
|
/* `after.editor.kind` rather than the tab's own field: it is the gate's read (`treeEditable`
|
|
@@ -1258,9 +1344,9 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1258
1344
|
* so it simply renders at the pane's width — which is the same clamp the drag applies, arrived
|
|
1259
1345
|
* at by CSS instead of by arithmetic. Refusing would make the verb depend on the window size.
|
|
1260
1346
|
*/
|
|
1261
|
-
run: (_commandCtx, args) => {
|
|
1347
|
+
run: (_commandCtx, args: CommandArgValues) => {
|
|
1262
1348
|
const tab = contextTab("canvas.setEditWidth", args);
|
|
1263
|
-
const { width } = args
|
|
1349
|
+
const { width } = args;
|
|
1264
1350
|
if (width === null) {
|
|
1265
1351
|
clearEditWidth(paneOfArgs(args));
|
|
1266
1352
|
repaint(args);
|
|
@@ -1311,10 +1397,10 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1311
1397
|
group: "3_canvas",
|
|
1312
1398
|
requires: "an open document",
|
|
1313
1399
|
when: documentOpen,
|
|
1314
|
-
run: (_commandCtx, args) => {
|
|
1400
|
+
run: (_commandCtx, args: CommandArgValues) => {
|
|
1315
1401
|
const tab = contextTab("canvas.setBreakpoint", args);
|
|
1316
|
-
const { media } = args
|
|
1317
|
-
if (media !== null &&
|
|
1402
|
+
const { media } = args;
|
|
1403
|
+
if (media !== null && !isString(media)) {
|
|
1318
1404
|
throw new RangeError(
|
|
1319
1405
|
`command "canvas.setBreakpoint" argument "media": expected a breakpoint key or null`,
|
|
1320
1406
|
);
|
|
@@ -1323,9 +1409,7 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1323
1409
|
that does not exist — the rule `data.expandRow` applies to a state entry's name.
|
|
1324
1410
|
`getEffectiveMedia` and not `document.$media`: the popover offers the SITE's breakpoints
|
|
1325
1411
|
too, and a command that refused what the control offers would be worse than no command. */
|
|
1326
|
-
const declared = Object.keys(
|
|
1327
|
-
getEffectiveMedia(tab.doc.document?.$media as Record<string, string> | undefined),
|
|
1328
|
-
);
|
|
1412
|
+
const declared = Object.keys(getEffectiveMedia(tab.doc.document.$media));
|
|
1329
1413
|
if (media !== null && !declared.includes(media)) {
|
|
1330
1414
|
throw new RangeError(
|
|
1331
1415
|
`command "canvas.setBreakpoint" argument "media": "${media}" is not a breakpoint this ` +
|
|
@@ -1359,7 +1443,7 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1359
1443
|
args,
|
|
1360
1444
|
"scheme",
|
|
1361
1445
|
COLOR_SCHEMES,
|
|
1362
|
-
)
|
|
1446
|
+
);
|
|
1363
1447
|
repaint(args);
|
|
1364
1448
|
},
|
|
1365
1449
|
title: "Set Color Scheme",
|
|
@@ -1372,9 +1456,9 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1372
1456
|
* preset owns it. What is left over is genuinely a rendering context, and it is the half of
|
|
1373
1457
|
* site-architecture.md §13.4 the canvas can show today: the artboard root's `lang` and `dir`.
|
|
1374
1458
|
* That is why this is a verb and not a label — an RTL locale mirrors the layout on screen.
|
|
1375
|
-
* (That section's other half, `$page.locale
|
|
1376
|
-
*
|
|
1377
|
-
*
|
|
1459
|
+
* (That section's other half, `$page.locale`, is injected into the canvas render from the
|
|
1460
|
+
* page's route, as the build injects it (studio.md §4.1). This verb leaves it alone: the
|
|
1461
|
+
* pane's language is a rendering context, not the page's (§20.2).)
|
|
1378
1462
|
*
|
|
1379
1463
|
* It lives in this file rather than in `i18n/i18n-commands.ts` because `contextTab`, `paneArg`
|
|
1380
1464
|
* and `repaint` are local closures here, and every rendering-context verb needs all three: the
|
|
@@ -1475,16 +1559,18 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1475
1559
|
level: "document",
|
|
1476
1560
|
menus: ["palette"],
|
|
1477
1561
|
requires: "a popover in the open document",
|
|
1478
|
-
run: (_commandCtx, args) => {
|
|
1562
|
+
run: (_commandCtx, args: CommandArgValues) => {
|
|
1479
1563
|
const tab = contextTab("canvas.setPopoverOpen", args);
|
|
1480
|
-
|
|
1564
|
+
/* SAFETY: `registry.run` coerces args against this record's schema before `run`, and the
|
|
1565
|
+
schema declares `path` an array of strings and numbers, which is what a JxPath is. */
|
|
1566
|
+
const explicitPath = args["path"] as JxPath | undefined;
|
|
1481
1567
|
const open =
|
|
1482
|
-
|
|
1483
|
-
if (!open &&
|
|
1568
|
+
args["open"] === undefined ? true : booleanArg("canvas.setPopoverOpen", args, "open");
|
|
1569
|
+
if (!open && explicitPath === undefined) {
|
|
1484
1570
|
deps.setOpenPopover(tab, null);
|
|
1485
1571
|
return;
|
|
1486
1572
|
}
|
|
1487
|
-
const path = popoverPathFor(tab,
|
|
1573
|
+
const path = popoverPathFor(tab, explicitPath);
|
|
1488
1574
|
/* REFUSES a path that is not a popover rather than opening nothing — the rule
|
|
1489
1575
|
`canvas.setBreakpoint` applies to a breakpoint key. A <dialog> is refused with it: its UA
|
|
1490
1576
|
rules key off `open`, not `popover`, so de-popovering one falls back to a different rule
|
|
@@ -1535,16 +1621,18 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1535
1621
|
level: "document",
|
|
1536
1622
|
menus: ["palette"],
|
|
1537
1623
|
requires: "a dialog in the open document",
|
|
1538
|
-
run: (_commandCtx, args) => {
|
|
1624
|
+
run: (_commandCtx, args: CommandArgValues) => {
|
|
1539
1625
|
const tab = contextTab("canvas.setDialogOpen", args);
|
|
1540
|
-
|
|
1626
|
+
/* SAFETY: `registry.run` coerces args against this record's schema before `run`, and the
|
|
1627
|
+
schema declares `path` an array of strings and numbers, which is what a JxPath is. */
|
|
1628
|
+
const explicitPath = args["path"] as JxPath | undefined;
|
|
1541
1629
|
const open =
|
|
1542
|
-
|
|
1543
|
-
if (!open &&
|
|
1630
|
+
args["open"] === undefined ? true : booleanArg("canvas.setDialogOpen", args, "open");
|
|
1631
|
+
if (!open && explicitPath === undefined) {
|
|
1544
1632
|
deps.setOpenDialog(tab, null);
|
|
1545
1633
|
return;
|
|
1546
1634
|
}
|
|
1547
|
-
const path = dialogPathFor(tab,
|
|
1635
|
+
const path = dialogPathFor(tab, explicitPath);
|
|
1548
1636
|
/* REFUSES a path that is not a dialog, for the same reason its twin refuses a non-popover:
|
|
1549
1637
|
the canvas would draw it under the wrong rule and with the wrong name. */
|
|
1550
1638
|
if (path === null) {
|
|
@@ -1586,14 +1674,14 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1586
1674
|
* (`scripts/screenshots/README.md`) forbids outright. The pointer and the camera use the same
|
|
1587
1675
|
* door.
|
|
1588
1676
|
*/
|
|
1589
|
-
run: (_commandCtx, args) => {
|
|
1677
|
+
run: (_commandCtx, args: CommandArgValues) => {
|
|
1590
1678
|
// Resolve the tab first, so a pane with no document refuses before anything opens.
|
|
1591
1679
|
contextTab("canvas.setResolvingOpen", args);
|
|
1592
|
-
const { open, pane } = args
|
|
1680
|
+
const { open, pane } = args;
|
|
1593
1681
|
// `open` defaults to true and is never COERCED: `{ open: "no" }` would otherwise read as a
|
|
1594
1682
|
// Close, the class of silent wrong answer this setter family exists to stop.
|
|
1595
1683
|
deps.setResolvingOpen(
|
|
1596
|
-
|
|
1684
|
+
isString(pane) ? pane : workspace.activePaneId,
|
|
1597
1685
|
open === undefined || booleanArg("canvas.setResolvingOpen", args, "open"),
|
|
1598
1686
|
);
|
|
1599
1687
|
},
|
|
@@ -1636,26 +1724,24 @@ export function canvasViewCommands(deps: CanvasCommandDeps): AnyCommand[] {
|
|
|
1636
1724
|
group: "3_canvas",
|
|
1637
1725
|
requires: "an open component document",
|
|
1638
1726
|
when: documentOpen,
|
|
1639
|
-
run: (_commandCtx, args) => {
|
|
1727
|
+
run: (_commandCtx, args: CommandArgValues) => {
|
|
1640
1728
|
const tab = contextTab("canvas.setTestProp", args);
|
|
1641
1729
|
const name = stringArg("canvas.setTestProp", args, "name");
|
|
1642
1730
|
// REFUSES a prop the component does not declare, rather than seeding a value nothing reads
|
|
1643
1731
|
// — the rule `data.expandRow` and `canvas.setBreakpoint` both apply to their own names.
|
|
1644
|
-
const declared = Object.keys(
|
|
1645
|
-
(tab.doc.document?.state as Record<string, unknown> | undefined) ?? {},
|
|
1646
|
-
);
|
|
1732
|
+
const declared = Object.keys(tab.doc.document.state ?? {});
|
|
1647
1733
|
if (!declared.includes(name)) {
|
|
1648
1734
|
throw new RangeError(
|
|
1649
1735
|
`command "canvas.setTestProp" argument "name": "${name}" is not a prop this component ` +
|
|
1650
1736
|
`declares — it declares: ${declared.length > 0 ? declared.join(", ") : "nothing"}`,
|
|
1651
1737
|
);
|
|
1652
1738
|
}
|
|
1653
|
-
const { value } = args
|
|
1739
|
+
const { value } = args;
|
|
1654
1740
|
const next = { ...tab.session.ui.previewProps };
|
|
1655
1741
|
if (value === null || value === undefined) {
|
|
1656
1742
|
delete next[name];
|
|
1657
1743
|
} else {
|
|
1658
|
-
next[name] = value
|
|
1744
|
+
next[name] = value;
|
|
1659
1745
|
}
|
|
1660
1746
|
tab.session.ui.previewProps = Object.keys(next).length > 0 ? next : null;
|
|
1661
1747
|
repaint(args);
|
|
@@ -1723,13 +1809,13 @@ export function registerCanvasViewCommands(
|
|
|
1723
1809
|
*/
|
|
1724
1810
|
export function updateActivePanelHeaders(surface: CanvasSurface = activeCanvasSurface()) {
|
|
1725
1811
|
const activeMedia = activeMediaOfPane(surface.paneId);
|
|
1726
|
-
|
|
1812
|
+
// A board the stage has not bound yet has no header to mark.
|
|
1813
|
+
const panels: readonly UnboundCanvasPanel[] = surface.panels;
|
|
1814
|
+
for (const p of panels) {
|
|
1727
1815
|
const header = p.element?.querySelector('[part="panel-header"]');
|
|
1728
1816
|
if (header) {
|
|
1729
1817
|
const isActive =
|
|
1730
|
-
(activeMedia === null && p.mediaName === "base") ||
|
|
1731
|
-
(activeMedia === null && p.mediaName === null) ||
|
|
1732
|
-
activeMedia === p.mediaName;
|
|
1818
|
+
(activeMedia === null && p.mediaName === "base") || activeMedia === p.mediaName;
|
|
1733
1819
|
/* An ATTRIBUTE the document does not bind, written from outside it. Which board is current is
|
|
1734
1820
|
a fact about the pane's session that changes without the stage being rebuilt — the same
|
|
1735
1821
|
reason the pan transform is written rather than bound — so a reconcile can never disagree
|
|
@@ -12,8 +12,9 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { activeTab } from "../workspace/workspace";
|
|
15
|
-
import { getNodeAtPath } from "
|
|
15
|
+
import { getNodeAtPath } from "@jxsuite/schema/doc-ops";
|
|
16
16
|
import { documentHasDialog, isDialog } from "@jxsuite/schema/dialogs";
|
|
17
|
+
import { isNonNullObject } from "@jxsuite/schema/guards";
|
|
17
18
|
import { primarySelection } from "../tabs/selection";
|
|
18
19
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
19
20
|
import type { JxPath } from "../state";
|
|
@@ -39,7 +40,8 @@ export function ancestorDialogPath(
|
|
|
39
40
|
for (let end = path.length; end >= 0; end -= 1) {
|
|
40
41
|
const prefix = path.slice(0, end);
|
|
41
42
|
const node = getNodeAtPath(doc, prefix);
|
|
42
|
-
|
|
43
|
+
// A path can end on a text child or a value, so only an element is asked about its tag.
|
|
44
|
+
if (isNonNullObject(node) && isDialog(node)) {
|
|
43
45
|
return prefix;
|
|
44
46
|
}
|
|
45
47
|
}
|
|
@@ -58,19 +60,22 @@ export function ancestorDialogPath(
|
|
|
58
60
|
* @returns The dialog's path, or null.
|
|
59
61
|
*/
|
|
60
62
|
export function dialogPathFor(tab: Tab, explicit?: JxPath): JxPath | null {
|
|
63
|
+
/* SAFETY: a widening, so it cannot hide a mismatch: `Tab` declares the document always present,
|
|
64
|
+
but a tab record without one must answer null rather than throw (tests/dialog-path.test.ts,
|
|
65
|
+
"a tab with no document"), and the widened type keeps that guard checked. */
|
|
61
66
|
const doc = tab.doc.document as JxMutableNode | undefined;
|
|
62
67
|
if (!doc) {
|
|
63
68
|
return null;
|
|
64
69
|
}
|
|
65
70
|
if (explicit) {
|
|
66
71
|
const node = getNodeAtPath(doc, explicit);
|
|
67
|
-
return node &&
|
|
72
|
+
return isNonNullObject(node) && isDialog(node) ? explicit : null;
|
|
68
73
|
}
|
|
69
74
|
return ancestorDialogPath(doc, primarySelection(tab.session.selection));
|
|
70
75
|
}
|
|
71
76
|
|
|
72
77
|
/** Whether the active document holds a `<dialog>` at all — the command's `enablement`. */
|
|
73
78
|
export function activeDocumentHasDialog(): boolean {
|
|
74
|
-
const doc = activeTab.value?.doc.document
|
|
79
|
+
const doc = activeTab.value?.doc.document;
|
|
75
80
|
return doc ? documentHasDialog(doc) : false;
|
|
76
81
|
}
|
|
@@ -19,7 +19,6 @@ import { ancestorDialogPath } from "./dialog-path";
|
|
|
19
19
|
import { postDialogOpen } from "./iframe-host";
|
|
20
20
|
import { primarySelection } from "../tabs/selection";
|
|
21
21
|
import { updateSession } from "../store";
|
|
22
|
-
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
23
22
|
import type { JxPath } from "../state";
|
|
24
23
|
import type { Tab } from "../tabs/tab";
|
|
25
24
|
|
|
@@ -51,7 +50,7 @@ export function setOpenDialog(tab: Tab, path: JxPath | null): void {
|
|
|
51
50
|
* @returns Whether anything changed.
|
|
52
51
|
*/
|
|
53
52
|
export function openDialogFor(tab: Tab, path: JxPath | null): boolean {
|
|
54
|
-
const target = ancestorDialogPath(tab.doc.document
|
|
53
|
+
const target = ancestorDialogPath(tab.doc.document, path);
|
|
55
54
|
if (target === null || samePath(tab.session.ui.openDialog, target)) {
|
|
56
55
|
return false;
|
|
57
56
|
}
|
package/src/canvas/diff-marks.ts
CHANGED
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
37
|
import { deepEqual, matchChildren } from "@jxsuite/collab/diff-core";
|
|
38
|
+
import { isJsonObject } from "@jxsuite/schema/guards";
|
|
38
39
|
import type { JxMutableNode, JxPath } from "@jxsuite/schema/types";
|
|
39
40
|
|
|
40
41
|
/** What happened to a node. `modified` means the node survived and its own content changed. */
|
|
@@ -84,10 +85,6 @@ export interface ChangeMapOptions {
|
|
|
84
85
|
|
|
85
86
|
const DEFAULT_MAX_CELLS = 250_000;
|
|
86
87
|
|
|
87
|
-
function isPlainObject(value: unknown): value is Record<string, unknown> {
|
|
88
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
88
|
class ChangeWalker {
|
|
92
89
|
readonly original: ChangeMark[] = [];
|
|
93
90
|
readonly current: ChangeMark[] = [];
|
|
@@ -121,12 +118,7 @@ class ChangeWalker {
|
|
|
121
118
|
this.steps.push({ currentPath: bPath, kind, originalPath: aPath });
|
|
122
119
|
}
|
|
123
120
|
|
|
124
|
-
diffNode(
|
|
125
|
-
aPath: JxPath,
|
|
126
|
-
bPath: JxPath,
|
|
127
|
-
a: Record<string, unknown>,
|
|
128
|
-
b: Record<string, unknown>,
|
|
129
|
-
): void {
|
|
121
|
+
diffNode(aPath: JxPath, bPath: JxPath, a: JxMutableNode, b: JxMutableNode): void {
|
|
130
122
|
const isRoot = aPath.length === 0 && bPath.length === 0;
|
|
131
123
|
let ownChanged = false;
|
|
132
124
|
for (const key of new Set([...Object.keys(a), ...Object.keys(b)])) {
|
|
@@ -161,8 +153,8 @@ class ChangeWalker {
|
|
|
161
153
|
private diffChildren(
|
|
162
154
|
aPath: JxPath,
|
|
163
155
|
bPath: JxPath,
|
|
164
|
-
ca: readonly
|
|
165
|
-
cb: readonly
|
|
156
|
+
ca: readonly (JxMutableNode | string)[],
|
|
157
|
+
cb: readonly (JxMutableNode | string)[],
|
|
166
158
|
): void {
|
|
167
159
|
if (ca.length * cb.length > this.maxCells) {
|
|
168
160
|
this.degraded = true;
|
|
@@ -183,7 +175,7 @@ class ChangeWalker {
|
|
|
183
175
|
if (!match.identical) {
|
|
184
176
|
const aItem = ca[match.aIndex];
|
|
185
177
|
const bItem = cb[match.bIndex];
|
|
186
|
-
if (
|
|
178
|
+
if (isJsonObject(aItem) && isJsonObject(bItem)) {
|
|
187
179
|
this.diffNode(
|
|
188
180
|
[...aPath, "children", match.aIndex],
|
|
189
181
|
[...bPath, "children", match.bIndex],
|
|
@@ -211,11 +203,12 @@ class ChangeWalker {
|
|
|
211
203
|
kind: "added" | "removed",
|
|
212
204
|
aPath: JxPath,
|
|
213
205
|
bPath: JxPath,
|
|
214
|
-
|
|
206
|
+
// Every caller reads in bounds, but an indexed read is typed possibly undefined; it is no element.
|
|
207
|
+
item: JxMutableNode | string | undefined,
|
|
215
208
|
aIndex: number | null,
|
|
216
209
|
bIndex: number | null,
|
|
217
210
|
): void {
|
|
218
|
-
if (!
|
|
211
|
+
if (!isJsonObject(item)) {
|
|
219
212
|
this.emit("modified", aPath, bPath);
|
|
220
213
|
return;
|
|
221
214
|
}
|
|
@@ -241,7 +234,7 @@ export function buildChangeMap(
|
|
|
241
234
|
opts: ChangeMapOptions = {},
|
|
242
235
|
): ChangeMap {
|
|
243
236
|
const walker = new ChangeWalker(opts.maxCells ?? DEFAULT_MAX_CELLS);
|
|
244
|
-
walker.diffNode([], [], a
|
|
237
|
+
walker.diffNode([], [], a, b);
|
|
245
238
|
return {
|
|
246
239
|
current: walker.current,
|
|
247
240
|
degraded: walker.degraded,
|