@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
package/src/workspace/session.ts
CHANGED
|
@@ -25,9 +25,17 @@
|
|
|
25
25
|
* across versions. Every field is validated on the way in and a bad record restores nothing.
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
import { PRIMARY_PANE, SECONDARY_PANE, focusPane, workspace } from "./workspace";
|
|
28
|
+
import { PRIMARY_PANE, SECONDARY_PANE, activateTab, focusPane, workspace } from "./workspace";
|
|
29
|
+
import {
|
|
30
|
+
isBoolean,
|
|
31
|
+
isJsonObject,
|
|
32
|
+
isNonNullObject,
|
|
33
|
+
isNumber,
|
|
34
|
+
isString,
|
|
35
|
+
} from "@jxsuite/schema/guards";
|
|
29
36
|
import { isWellFormedLocale } from "@jxsuite/schema/locale";
|
|
30
|
-
import type {
|
|
37
|
+
import type { JsonValue } from "@jxsuite/schema/types";
|
|
38
|
+
import type { Tab, TabUi } from "../tabs/tab";
|
|
31
39
|
|
|
32
40
|
/** One pane's share of a session. */
|
|
33
41
|
export interface PersistedPane {
|
|
@@ -46,7 +54,7 @@ export interface PersistedTabUi {
|
|
|
46
54
|
zoom?: number;
|
|
47
55
|
editZoom?: number;
|
|
48
56
|
activeMedia?: string | null;
|
|
49
|
-
previewColorScheme?:
|
|
57
|
+
previewColorScheme?: TabUi["previewColorScheme"];
|
|
50
58
|
/** BCP 47 tag, or `null` for "the document's own language". */
|
|
51
59
|
previewLocale?: string | null;
|
|
52
60
|
showLayout?: boolean;
|
|
@@ -62,7 +70,12 @@ export interface PersistedSession {
|
|
|
62
70
|
}
|
|
63
71
|
|
|
64
72
|
const PANE_IDS = new Set([PRIMARY_PANE, SECONDARY_PANE]);
|
|
65
|
-
const SCHEMES = new Set(["auto", "light", "dark"]);
|
|
73
|
+
const SCHEMES: ReadonlySet<string> = new Set(["auto", "light", "dark"]);
|
|
74
|
+
|
|
75
|
+
/** Whether a stored value is one of the three schemes a tab's preview may be forced into. */
|
|
76
|
+
function isColorScheme(value: JsonValue | undefined): value is TabUi["previewColorScheme"] {
|
|
77
|
+
return isString(value) && SCHEMES.has(value);
|
|
78
|
+
}
|
|
66
79
|
|
|
67
80
|
/** The view settings this tab was left in — the ones a person chose, not the ones derived. */
|
|
68
81
|
function uiOf(tab: Tab): PersistedTabUi {
|
|
@@ -118,40 +131,42 @@ export function captureSession(): PersistedSession {
|
|
|
118
131
|
}
|
|
119
132
|
|
|
120
133
|
/** Whether a parsed value is a usable {@link PersistedTabUi}. Hand-edited storage is input. */
|
|
121
|
-
function readTabUi(value:
|
|
122
|
-
if (
|
|
134
|
+
function readTabUi(value: JsonValue | undefined): PersistedTabUi {
|
|
135
|
+
if (!isJsonObject(value)) {
|
|
123
136
|
return {};
|
|
124
137
|
}
|
|
125
|
-
const raw = value as Record<string, unknown>;
|
|
126
138
|
const out: PersistedTabUi = {};
|
|
127
|
-
if (
|
|
128
|
-
out.canvasMode =
|
|
139
|
+
if (isString(value.canvasMode)) {
|
|
140
|
+
out.canvasMode = value.canvasMode;
|
|
129
141
|
}
|
|
130
|
-
if (
|
|
131
|
-
out.preview =
|
|
142
|
+
if (isBoolean(value.preview)) {
|
|
143
|
+
out.preview = value.preview;
|
|
132
144
|
}
|
|
133
|
-
if (
|
|
134
|
-
out.zoom =
|
|
145
|
+
if (isNumber(value.zoom) && Number.isFinite(value.zoom)) {
|
|
146
|
+
out.zoom = value.zoom;
|
|
135
147
|
}
|
|
136
|
-
if (
|
|
137
|
-
out.editZoom =
|
|
148
|
+
if (isNumber(value.editZoom) && Number.isFinite(value.editZoom)) {
|
|
149
|
+
out.editZoom = value.editZoom;
|
|
138
150
|
}
|
|
139
|
-
if (
|
|
140
|
-
out.activeMedia =
|
|
151
|
+
if (value.activeMedia === null || isString(value.activeMedia)) {
|
|
152
|
+
out.activeMedia = value.activeMedia;
|
|
141
153
|
}
|
|
142
|
-
if (
|
|
143
|
-
out.previewColorScheme =
|
|
154
|
+
if (isColorScheme(value.previewColorScheme)) {
|
|
155
|
+
out.previewColorScheme = value.previewColorScheme;
|
|
144
156
|
}
|
|
145
157
|
/* `null` is a value here, not an absence: it is "the document's own language", so a pane put
|
|
146
158
|
deliberately back onto its own file's language would otherwise restore the tag it left.
|
|
147
159
|
A tag is checked for WELL-FORMEDNESS only — whether the project still declares it is a
|
|
148
160
|
question about `project.json`, which the reader cannot see and which changes between sessions;
|
|
149
161
|
the control refuses an undeclared tag on the way in and the render falls back on the way out. */
|
|
150
|
-
if (
|
|
151
|
-
|
|
162
|
+
if (
|
|
163
|
+
value.previewLocale === null ||
|
|
164
|
+
(isString(value.previewLocale) && isWellFormedLocale(value.previewLocale))
|
|
165
|
+
) {
|
|
166
|
+
out.previewLocale = value.previewLocale;
|
|
152
167
|
}
|
|
153
|
-
if (
|
|
154
|
-
out.showLayout =
|
|
168
|
+
if (isBoolean(value.showLayout)) {
|
|
169
|
+
out.showLayout = value.showLayout;
|
|
155
170
|
}
|
|
156
171
|
return out;
|
|
157
172
|
}
|
|
@@ -159,35 +174,28 @@ function readTabUi(value: unknown): PersistedTabUi {
|
|
|
159
174
|
/**
|
|
160
175
|
* Validate a stored session. Returns `null` for anything that is not one — a corrupt record
|
|
161
176
|
* restores nothing rather than restoring half a workspace.
|
|
177
|
+
*
|
|
178
|
+
* The input is whatever `JSON.parse` gave back for the stored record (or `undefined` when the
|
|
179
|
+
* project record has no session), so every field is decoded here rather than trusted.
|
|
162
180
|
*/
|
|
163
|
-
export function readSession(value:
|
|
164
|
-
if (
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
const raw = value as Partial<PersistedSession>;
|
|
168
|
-
if (!Array.isArray(raw.panes)) {
|
|
181
|
+
export function readSession(value: JsonValue | undefined): PersistedSession | null {
|
|
182
|
+
if (!isJsonObject(value) || !Array.isArray(value.panes)) {
|
|
169
183
|
return null;
|
|
170
184
|
}
|
|
171
185
|
const panes: PersistedPane[] = [];
|
|
172
|
-
for (const
|
|
173
|
-
if (
|
|
174
|
-
continue;
|
|
175
|
-
}
|
|
176
|
-
const pane = entry as Partial<PersistedPane>;
|
|
177
|
-
if (typeof pane.id !== "string" || !PANE_IDS.has(pane.id)) {
|
|
186
|
+
for (const pane of value.panes) {
|
|
187
|
+
if (!isJsonObject(pane) || !isString(pane.id) || !PANE_IDS.has(pane.id)) {
|
|
178
188
|
continue;
|
|
179
189
|
}
|
|
180
190
|
const files = Array.isArray(pane.files)
|
|
181
|
-
? pane.files.filter((file): file is string =>
|
|
191
|
+
? pane.files.filter((file): file is string => isString(file) && file !== "")
|
|
182
192
|
: [];
|
|
183
193
|
if (files.length === 0) {
|
|
184
194
|
continue;
|
|
185
195
|
}
|
|
186
196
|
panes.push({
|
|
187
197
|
activeFile:
|
|
188
|
-
|
|
189
|
-
? pane.activeFile
|
|
190
|
-
: null,
|
|
198
|
+
isString(pane.activeFile) && files.includes(pane.activeFile) ? pane.activeFile : null,
|
|
191
199
|
files,
|
|
192
200
|
id: pane.id,
|
|
193
201
|
});
|
|
@@ -196,15 +204,17 @@ export function readSession(value: unknown): PersistedSession | null {
|
|
|
196
204
|
return null;
|
|
197
205
|
}
|
|
198
206
|
const ui: Record<string, PersistedTabUi> = {};
|
|
199
|
-
|
|
200
|
-
|
|
207
|
+
/* `isNonNullObject`, not `isJsonObject`: a hand-edited array here has always been read entry by
|
|
208
|
+
entry under its index keys, and this decoder keeps that rather than silently dropping it. */
|
|
209
|
+
if (isNonNullObject(value.ui)) {
|
|
210
|
+
for (const [path, entry] of Object.entries(value.ui)) {
|
|
201
211
|
ui[path] = readTabUi(entry);
|
|
202
212
|
}
|
|
203
213
|
}
|
|
204
214
|
return {
|
|
205
215
|
focusedPane:
|
|
206
|
-
|
|
207
|
-
?
|
|
216
|
+
isString(value.focusedPane) && PANE_IDS.has(value.focusedPane)
|
|
217
|
+
? value.focusedPane
|
|
208
218
|
: PRIMARY_PANE,
|
|
209
219
|
panes,
|
|
210
220
|
ui,
|
|
@@ -288,7 +298,7 @@ export async function restoreSession(
|
|
|
288
298
|
ui.activeMedia = stored.activeMedia;
|
|
289
299
|
}
|
|
290
300
|
if (stored.previewColorScheme !== undefined) {
|
|
291
|
-
ui.previewColorScheme = stored.previewColorScheme
|
|
301
|
+
ui.previewColorScheme = stored.previewColorScheme;
|
|
292
302
|
}
|
|
293
303
|
if (stored.previewLocale !== undefined) {
|
|
294
304
|
ui.previewLocale = stored.previewLocale;
|
|
@@ -297,8 +307,22 @@ export async function restoreSession(
|
|
|
297
307
|
ui.showLayout = stored.showLayout;
|
|
298
308
|
}
|
|
299
309
|
}
|
|
300
|
-
|
|
301
|
-
|
|
310
|
+
/*
|
|
311
|
+
* Each pane's active tab, then the pane that had the keyboard, in that order, because activating
|
|
312
|
+
* a tab in a pane is what makes that pane's strip meaningful and focusing comes last.
|
|
313
|
+
*
|
|
314
|
+
* The focused pane's tab is ACTIVATED, not merely assigned, because the restored tab is the most
|
|
315
|
+
* recently used one and the workspace switch that follows a restore asks exactly that question.
|
|
316
|
+
* Every document was reopened without moving the keyboard, so the MRU list was empty, and
|
|
317
|
+
* `focusPane` adds nothing for the pane that already has the keyboard. Entering the stored
|
|
318
|
+
* workspace then fell back to that workspace's FIRST tab in the strip: two exhibition entries
|
|
319
|
+
* restored with the English one active came back on whichever was opened first, and a Design
|
|
320
|
+
* session left on `/exhibitions` came back on `/`.
|
|
321
|
+
*/
|
|
322
|
+
const focused = workspace.panes.some((pane) => pane.id === session.focusedPane)
|
|
323
|
+
? session.focusedPane
|
|
324
|
+
: null;
|
|
325
|
+
let focusedTab: string | null = null;
|
|
302
326
|
for (const stored of session.panes) {
|
|
303
327
|
const pane = workspace.panes.find((p) => p.id === stored.id);
|
|
304
328
|
if (!pane || !stored.activeFile) {
|
|
@@ -307,12 +331,19 @@ export async function restoreSession(
|
|
|
307
331
|
const match = pane.tabOrder.find(
|
|
308
332
|
(tabId) => workspace.tabs.get(tabId)?.documentPath === stored.activeFile,
|
|
309
333
|
);
|
|
310
|
-
if (match) {
|
|
311
|
-
|
|
334
|
+
if (!match) {
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (pane.id === focused) {
|
|
338
|
+
focusedTab = match;
|
|
339
|
+
} else {
|
|
340
|
+
activateTab(match, { focus: false });
|
|
312
341
|
}
|
|
313
342
|
}
|
|
314
|
-
if (
|
|
315
|
-
|
|
343
|
+
if (focusedTab) {
|
|
344
|
+
activateTab(focusedTab);
|
|
345
|
+
} else if (focused) {
|
|
346
|
+
focusPane(focused);
|
|
316
347
|
}
|
|
317
348
|
return opened;
|
|
318
349
|
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which workspace a tab belongs to, and which of a pane's tabs its strip draws.
|
|
3
|
+
*
|
|
4
|
+
* Every tab belongs to exactly one workspace, and the answer is DERIVED from the tab rather than
|
|
5
|
+
* stored on it: what a tab is (a home, a media file, a comparison) and how it is being edited (the
|
|
6
|
+
* configuration document's stylebook editor) are already on the tab, so a stored field would be a
|
|
7
|
+
* second record of the same fact, free to disagree with it.
|
|
8
|
+
*
|
|
9
|
+
* - **Content**: the Content home and the collection and page grids; an entry's form editor; and any
|
|
10
|
+
* file a content collection owns (collection-match.ts is the one matcher), because an entry is
|
|
11
|
+
* written in Content even when it is opened from somewhere else.
|
|
12
|
+
* - **Media**: the media home and every media file's viewer.
|
|
13
|
+
* - **Styles**: `project.json`, in any of its three views: Elements (`stylebook`), Variables
|
|
14
|
+
* (`tokens`) and Code (`source`). Project Settings is a dialog over every workspace (§17.1), not
|
|
15
|
+
* a tab, so it belongs to none.
|
|
16
|
+
* - **Publish**: the publish home and every comparison (`git-diff`).
|
|
17
|
+
* - **Design**: everything else: pages, templates, components and every other file.
|
|
18
|
+
*
|
|
19
|
+
* The rules read the tab's CURRENT editor, so switching an entry from its form to the canvas keeps
|
|
20
|
+
* it in Content while a grid's kind decides between Content and Design, and
|
|
21
|
+
* `workspace/workspace-switch.ts` follows the tab wherever that puts it.
|
|
22
|
+
*
|
|
23
|
+
* @docs studio/interface
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { shell } from "../shell";
|
|
27
|
+
import { workspace } from "./workspace";
|
|
28
|
+
import { homeWorkspaceOfTabId } from "./workspace-ids";
|
|
29
|
+
import { parseGridTabId } from "../grid/grid-source";
|
|
30
|
+
import { collectionForFile } from "../content/collection-match";
|
|
31
|
+
import { PROJECT_CONFIG_PATH } from "../tabs/tab";
|
|
32
|
+
import type { Pane } from "./workspace";
|
|
33
|
+
import type { WorkspaceId } from "./workspace-ids";
|
|
34
|
+
import type { Tab } from "../tabs/tab";
|
|
35
|
+
|
|
36
|
+
/** The editors that are Content's whatever document they are over. */
|
|
37
|
+
const CONTENT_MODES: ReadonlySet<string> = new Set(["entry"]);
|
|
38
|
+
|
|
39
|
+
/** The workspace `tab` belongs to. Pure over the tab and the open project's configuration. */
|
|
40
|
+
export function workspaceOfTab(tab: Tab): WorkspaceId {
|
|
41
|
+
const home = homeWorkspaceOfTabId(tab.id);
|
|
42
|
+
if (home) {
|
|
43
|
+
return home;
|
|
44
|
+
}
|
|
45
|
+
const mode = tab.session.ui.canvasMode;
|
|
46
|
+
if (mode === "git-diff") {
|
|
47
|
+
return "publish";
|
|
48
|
+
}
|
|
49
|
+
if (mode === "media") {
|
|
50
|
+
return "media";
|
|
51
|
+
}
|
|
52
|
+
if (CONTENT_MODES.has(mode)) {
|
|
53
|
+
return "content";
|
|
54
|
+
}
|
|
55
|
+
const grid = parseGridTabId(tab.id);
|
|
56
|
+
if (grid) {
|
|
57
|
+
// A data-table grid is the Data panel's, which is Design's; every other grid is content.
|
|
58
|
+
return grid.kind === "data" ? "design" : "content";
|
|
59
|
+
}
|
|
60
|
+
if (tab.documentPath === PROJECT_CONFIG_PATH) {
|
|
61
|
+
return "styles";
|
|
62
|
+
}
|
|
63
|
+
/* A file-backed collection's file too: its grid is where its records are written, and the
|
|
64
|
+
Content home opens it for any of them, so it must not carry the author off to Design. */
|
|
65
|
+
return collectionForFile(tab.documentPath) ? "content" : "design";
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The editors in which a document is written on the canvas, where the Inspector applies: a page's
|
|
70
|
+
* canvas, and the Elements view (`stylebook`), whose canvas selects the element default the
|
|
71
|
+
* Inspector's Style tab edits.
|
|
72
|
+
*/
|
|
73
|
+
const CANVAS_WRITING_MODES: ReadonlySet<string> = new Set(["edit", "design", "stylebook"]);
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Whether a tab is a document being written on the canvas: a file-backed tab in an editing canvas
|
|
77
|
+
* mode. A grid, an entry's form, a home, the Variables view and a code view are not. Content's and
|
|
78
|
+
* Styles' presets read it to draw the Inspector while the canvas is being written (`shell.ts`'s
|
|
79
|
+
* `WORKSPACE_PRESETS`).
|
|
80
|
+
*/
|
|
81
|
+
export function writesOnCanvas(tab: Tab): boolean {
|
|
82
|
+
return (
|
|
83
|
+
tab.documentPath !== null &&
|
|
84
|
+
parseGridTabId(tab.id) === null &&
|
|
85
|
+
CANVAS_WRITING_MODES.has(tab.session.ui.canvasMode)
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Whether a tab id names an open tab of the workspace on screen. */
|
|
90
|
+
export function isTabInWorkspace(tabId: string, id: WorkspaceId = shell.workspace): boolean {
|
|
91
|
+
const tab = workspace.tabs.get(tabId);
|
|
92
|
+
return tab !== undefined && workspaceOfTab(tab) === id;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* The tabs a pane's strip draws: its own, in strip order, less every tab of another workspace.
|
|
97
|
+
*
|
|
98
|
+
* The order is the pane's, so a drop index computed against {@link Pane.tabOrder} still lands
|
|
99
|
+
* between the two chips it was dropped between: the hidden tabs keep their slots, they are only not
|
|
100
|
+
* drawn.
|
|
101
|
+
*/
|
|
102
|
+
export function workspaceTabOrder(pane: Pane, id: WorkspaceId = shell.workspace): string[] {
|
|
103
|
+
return pane.tabOrder.filter((tabId) => isTabInWorkspace(tabId, id));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* The tab a workspace was last in: the most recently used of its open tabs, in any pane, or the
|
|
108
|
+
* first of them in strip order when none has been used yet (a restored session's tabs are opened
|
|
109
|
+
* without being focused). `null` when the workspace has no tab open.
|
|
110
|
+
*/
|
|
111
|
+
export function lastTabOfWorkspace(id: WorkspaceId): string | null {
|
|
112
|
+
const recent = workspace.mruOrder.find((tabId) => isTabInWorkspace(tabId, id));
|
|
113
|
+
if (recent) {
|
|
114
|
+
return recent;
|
|
115
|
+
}
|
|
116
|
+
for (const pane of workspace.panes) {
|
|
117
|
+
const first = pane.tabOrder.find((tabId) => isTabInWorkspace(tabId, id));
|
|
118
|
+
if (first) {
|
|
119
|
+
return first;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** The tab `pane` should show for a workspace: its most recent one there, or `null`. */
|
|
126
|
+
export function paneTabOfWorkspace(pane: Pane, id: WorkspaceId): string | null {
|
|
127
|
+
if (pane.activeTabId && isTabInWorkspace(pane.activeTabId, id)) {
|
|
128
|
+
return pane.activeTabId;
|
|
129
|
+
}
|
|
130
|
+
return (
|
|
131
|
+
workspace.mruOrder.find(
|
|
132
|
+
(tabId) => pane.tabOrder.includes(tabId) && isTabInWorkspace(tabId, id),
|
|
133
|
+
) ??
|
|
134
|
+
pane.tabOrder.find((tabId) => isTabInWorkspace(tabId, id)) ??
|
|
135
|
+
null
|
|
136
|
+
);
|
|
137
|
+
}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Back to the workspace home — the way out of a view in a workspace that draws no tab strip.
|
|
3
|
+
*
|
|
4
|
+
* Media, Styles and Publish draw their home surface without a strip (`shell.ts`'s
|
|
5
|
+
* `WorkspacePreset.tabStrip`, `specs/studio.md` §22.3). What they open beside their home has to be
|
|
6
|
+
* leave-able anyway, and without a strip there is no chip to click and no × to press:
|
|
7
|
+
*
|
|
8
|
+
* - **Media**: a media file opened in its viewer leads back to the media library.
|
|
9
|
+
* - **Publish**: a comparison (`git-diff`) leads back to the Publish home.
|
|
10
|
+
* - **Styles**: `project.json` in its Code view leads back to the view the Styles home was left in,
|
|
11
|
+
* Variables or Elements. Code is a view of the same tab, so going back switches the view and
|
|
12
|
+
* closes nothing.
|
|
13
|
+
*
|
|
14
|
+
* {@link backTargetOf} is the one rule, read by the pane context bar (which draws the Back control,
|
|
15
|
+
* naming the destination) and by `pane.backToHome` (the control's command, and Escape's). A media
|
|
16
|
+
* viewer or a comparison is CLOSED on the way back, so the home is what is left: a strip-less pane
|
|
17
|
+
* holds its home and one view beside it rather than a pile of views nobody can see, and the close
|
|
18
|
+
* lands on the home (`workspace/workspace-switch.ts`'s close landing). Closing such a view any
|
|
19
|
+
* other way (⌘W) lands there too.
|
|
20
|
+
*
|
|
21
|
+
* @docs studio/interface/tabs
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { shell, workspaceDrawsTabStrip } from "../shell";
|
|
25
|
+
import { PROJECT_CONFIG_PATH } from "../tabs/tab";
|
|
26
|
+
import { tabOfPane } from "../canvas/canvas-surface";
|
|
27
|
+
import { workspace } from "./workspace";
|
|
28
|
+
import { workspaceOfTab } from "./tab-workspace";
|
|
29
|
+
import { homeWorkspaceOfTabId, isHomeWorkspace, workspaceInfo } from "./workspace-ids";
|
|
30
|
+
import { argsSchema, optionalStringArg, stringProperty } from "../commands/command-args";
|
|
31
|
+
import { EDITOR_KIND_LABELS, editorKindForMode } from "../commands/context";
|
|
32
|
+
import { isPopoverOpen } from "../ui/layers";
|
|
33
|
+
import type { WorkspaceId } from "./workspace-ids";
|
|
34
|
+
import type { Tab } from "../tabs/tab";
|
|
35
|
+
import type { AnyCommand } from "../commands/registry";
|
|
36
|
+
|
|
37
|
+
/** Where the Back control leads, and how it gets there. */
|
|
38
|
+
export type BackTarget =
|
|
39
|
+
| {
|
|
40
|
+
/** Close the view: the home beside it is what the pane shows next. */
|
|
41
|
+
kind: "close";
|
|
42
|
+
/** The control's text, naming the destination: "Back to Media". */
|
|
43
|
+
label: string;
|
|
44
|
+
/** Its tooltip: what happens to the view. */
|
|
45
|
+
hint: string;
|
|
46
|
+
}
|
|
47
|
+
| {
|
|
48
|
+
/** Switch the tab to another of its views (Styles' Code view back to the home view). */
|
|
49
|
+
kind: "view";
|
|
50
|
+
label: string;
|
|
51
|
+
hint: string;
|
|
52
|
+
/** The canvas mode to switch to: `tokens` or `stylebook`. */
|
|
53
|
+
mode: string;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** The Code view's mode over `project.json`. */
|
|
57
|
+
const SOURCE_MODE = "source";
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Where a tab's Back control leads in workspace `id`, or `null` when there is nowhere to go back
|
|
61
|
+
* to: a workspace that draws a strip (its strip is the way between documents), a tab of another
|
|
62
|
+
* workspace, and a workspace's home itself.
|
|
63
|
+
*
|
|
64
|
+
* @param tab The tab a pane is showing
|
|
65
|
+
* @param id The workspace on screen
|
|
66
|
+
*/
|
|
67
|
+
export function backTargetOf(
|
|
68
|
+
tab: Tab | null,
|
|
69
|
+
id: WorkspaceId = shell.workspace,
|
|
70
|
+
): BackTarget | null {
|
|
71
|
+
if (!tab || workspaceDrawsTabStrip(id) || workspaceOfTab(tab) !== id) {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
if (id === "styles") {
|
|
75
|
+
if (tab.documentPath !== PROJECT_CONFIG_PATH || tab.session.ui.canvasMode !== SOURCE_MODE) {
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
const mode = shell.stylebook.view;
|
|
79
|
+
const name = EDITOR_KIND_LABELS[editorKindForMode(mode)];
|
|
80
|
+
return {
|
|
81
|
+
hint: `Leave the Code view for the ${name} view of your styles`,
|
|
82
|
+
kind: "view",
|
|
83
|
+
label: `Back to ${name}`,
|
|
84
|
+
mode,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (!isHomeWorkspace(id) || homeWorkspaceOfTabId(tab.id) === id) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const home = workspaceInfo(id).title;
|
|
91
|
+
return {
|
|
92
|
+
hint: `Close this view and return to ${home}`,
|
|
93
|
+
kind: "close",
|
|
94
|
+
label: `Back to ${home}`,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** {@link backTargetOf} for the tab a pane is showing. */
|
|
99
|
+
export function backTargetOfPane(paneId: string): BackTarget | null {
|
|
100
|
+
return backTargetOf(tabOfPane(paneId));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** What going back needs that this module may not import. */
|
|
104
|
+
export interface WorkspaceBackDeps {
|
|
105
|
+
/** Close a tab through the strip's guarded close (`panels/tab-strip.ts` `requestClose`). */
|
|
106
|
+
closeTab: (tabId: string) => void | Promise<void>;
|
|
107
|
+
/** Switch a tab's editor (`studio.ts` `setCanvasMode`). */
|
|
108
|
+
setCanvasMode: (tab: Tab, mode: string) => void;
|
|
109
|
+
/**
|
|
110
|
+
* Give the keyboard to the home a close landed on: the Media home's tile, the Publish change the
|
|
111
|
+
* comparison was opened from. Without it the focus falls to the page body with the view.
|
|
112
|
+
*/
|
|
113
|
+
focusHome?: (paneId: string, id: WorkspaceId) => void;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Go back from what `paneId` shows to its workspace's home. `false` when there is nowhere to go.
|
|
118
|
+
*
|
|
119
|
+
* @param paneId The pane whose Back control was pressed
|
|
120
|
+
* @param deps The close and the view switch
|
|
121
|
+
*/
|
|
122
|
+
export async function goBack(paneId: string, deps: WorkspaceBackDeps): Promise<boolean> {
|
|
123
|
+
const tab = tabOfPane(paneId);
|
|
124
|
+
const target = backTargetOf(tab);
|
|
125
|
+
if (!tab || !target) {
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
if (target.kind === "view") {
|
|
129
|
+
tab.session.ui.preview = false;
|
|
130
|
+
deps.setCanvasMode(tab, target.mode);
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
const id = shell.workspace;
|
|
134
|
+
await deps.closeTab(tab.id);
|
|
135
|
+
// Only when the close went through: a refused close (unsaved work kept) leaves the view standing.
|
|
136
|
+
if (!workspace.tabs.has(tab.id)) {
|
|
137
|
+
deps.focusHome?.(paneId, id);
|
|
138
|
+
}
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* `pane.backToHome`: the Back control's command, and Escape's.
|
|
144
|
+
*
|
|
145
|
+
* Gated with `when`, not `enablement`, because Escape is the chord: a disabled record still claims
|
|
146
|
+
* its chord, and every other Escape in the global scope would be swallowed by a Back that is not
|
|
147
|
+
* there. Three places keep their own Escape: a text field (the caret is a field's, and Escape there
|
|
148
|
+
* is the field's own); the Code view, where Escape belongs to the code editor's widgets, so the
|
|
149
|
+
* Back control is how Code is left; and an open popover (the pane context bar's Context menu, for
|
|
150
|
+
* one), which the platform closes on Escape, and which a cancelled Escape would leave standing over
|
|
151
|
+
* a view that had gone.
|
|
152
|
+
*
|
|
153
|
+
* @param deps The close and the view switch
|
|
154
|
+
*/
|
|
155
|
+
export function workspaceBackCommands(deps: WorkspaceBackDeps): AnyCommand[] {
|
|
156
|
+
return [
|
|
157
|
+
{
|
|
158
|
+
args: argsSchema(
|
|
159
|
+
{
|
|
160
|
+
pane: stringProperty("Which pane to go back in. Defaults to the focused one."),
|
|
161
|
+
},
|
|
162
|
+
[],
|
|
163
|
+
),
|
|
164
|
+
id: "pane.backToHome",
|
|
165
|
+
title: "Back to Workspace Home",
|
|
166
|
+
category: "View",
|
|
167
|
+
level: "document",
|
|
168
|
+
keybinding: "escape",
|
|
169
|
+
menus: ["palette"],
|
|
170
|
+
group: "5_pane",
|
|
171
|
+
when: (ctx) =>
|
|
172
|
+
!ctx.caret.active &&
|
|
173
|
+
ctx.editor.kind !== "code" &&
|
|
174
|
+
!isPopoverOpen() &&
|
|
175
|
+
backTargetOfPane(workspace.activePaneId) !== null,
|
|
176
|
+
requires: "a view opened beside a workspace home",
|
|
177
|
+
undo: "none",
|
|
178
|
+
run: async (_ctx, args) => {
|
|
179
|
+
const paneId = optionalStringArg("pane.backToHome", args, "pane") ?? workspace.activePaneId;
|
|
180
|
+
if (!(await goBack(paneId, deps))) {
|
|
181
|
+
throw new RangeError(
|
|
182
|
+
`command "pane.backToHome": pane "${paneId}" shows no view opened beside a ` +
|
|
183
|
+
"workspace home, so there is nothing to go back from",
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
];
|
|
189
|
+
}
|