@jxsuite/studio 6.1.0 → 6.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunks/2020-f2gkpy8d.js +4 -0
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-4912g339.js +4 -0
- package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
- package/dist/chunks/cf-settings-br6105tr.js +4 -0
- package/dist/chunks/color-28ksk2qm.js +4 -0
- package/dist/chunks/color-area-0fj8a4ga.js +4 -0
- package/dist/chunks/color-field-xch8kx2g.js +4 -0
- package/dist/chunks/color-slider-jxd8v350.js +4 -0
- package/dist/chunks/combobox-p0efwjke.js +4 -0
- package/dist/chunks/components-db68vsn7.js +4 -0
- package/dist/chunks/content-source-1449qesq.js +4 -0
- package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-x9jn86a7.js +4 -0
- package/dist/chunks/entry-commands-may24cpt.js +4 -0
- package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
- package/dist/chunks/file-ops-x9v54pcj.js +4 -0
- package/dist/chunks/files-j3knqf0s.js +4 -0
- package/dist/chunks/format-host-tyre2trb.js +4 -0
- package/dist/chunks/fs-events-64ma9htc.js +4 -0
- package/dist/chunks/git-panel-84ps5dex.js +4 -0
- package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
- package/dist/chunks/icons-pnfz478q.js +4 -0
- package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
- package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
- package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
- package/dist/chunks/iframe-entry-zap785cw.js +5 -0
- package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
- package/dist/chunks/index-b8xw3vy9.js +4 -0
- package/dist/chunks/{index-gybvv7a6.js → index-zpjmzqfk.js} +3 -3
- package/dist/chunks/{javascript-rnvdp3k4.js → javascript-m54mnwp6.js} +3 -3
- package/dist/chunks/jsonMode-w15cmrcm.js +13 -0
- package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
- package/dist/chunks/layers-h4xp1pss.js +4 -0
- package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
- package/dist/chunks/listbox-e74qjyq6.js +4 -0
- package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
- package/dist/chunks/media-picker-2cweexc5.js +4 -0
- package/dist/chunks/menu-n6yzswmy.js +4 -0
- package/dist/chunks/menu-ynw13y0s.js +4 -0
- package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
- package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
- package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
- package/dist/chunks/notify-cj5zbrs2.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-b7ddhr8m.js +4 -0
- package/dist/chunks/platform-3dfws9js.js +4 -0
- package/dist/chunks/popover-jt2gxmzs.js +4 -0
- package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
- package/dist/chunks/quick-search-0dajrwqg.js +4 -0
- package/dist/chunks/references-49qgt404.js +4 -0
- package/dist/chunks/right-panel-jm1bwe53.js +4 -0
- package/dist/chunks/section-registry-6kwc4fky.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/split-n2gfpm5m.js +4 -0
- package/dist/chunks/{studio-5g0ag7c0.js → studio-0q988f9w.js} +3 -3
- package/dist/chunks/studio-0rt52vpq.js +5 -0
- package/dist/chunks/studio-18vgbhs5.js +5 -0
- package/dist/chunks/{studio-pxg4ap1e.js → studio-1fxkaaea.js} +4 -4
- package/dist/chunks/studio-24mccdrj.js +5 -0
- package/dist/chunks/studio-2eh507zk.js +9 -0
- package/dist/chunks/studio-2hcbccfv.js +5 -0
- package/dist/chunks/studio-2j1cb95x.js +5 -0
- package/dist/chunks/studio-2jbs3rxv.js +5 -0
- package/dist/chunks/{studio-qbj760tx.js → studio-485046te.js} +7 -7
- package/dist/chunks/studio-4h8k4dw9.js +5 -0
- package/dist/chunks/studio-5f6n18kx.js +5 -0
- package/dist/chunks/studio-5gthpky6.js +5 -0
- package/dist/chunks/studio-5ve6bbep.js +5 -0
- package/dist/chunks/studio-6ep3js6b.js +9 -0
- package/dist/chunks/studio-6wkmf3wz.js +9 -0
- package/dist/chunks/studio-841rf3cg.js +5 -0
- package/dist/chunks/studio-8gmwgheg.js +5 -0
- package/dist/chunks/studio-8qm0ep50.js +5 -0
- package/dist/chunks/{studio-anyrgzvb.js → studio-90pq9km1.js} +4 -4
- package/dist/chunks/studio-924p1tm1.js +6 -0
- package/dist/chunks/{studio-v2bvmbjj.js → studio-a3g98wjr.js} +4 -4
- package/dist/chunks/studio-a3shpz9y.js +5 -0
- package/dist/chunks/studio-amsbaaar.js +6 -0
- package/dist/chunks/studio-at5spjbc.js +7 -0
- package/dist/chunks/studio-b2xv945e.js +5 -0
- package/dist/chunks/studio-bn5nkafw.js +5 -0
- package/dist/chunks/studio-bw6q5xjf.js +9 -0
- package/dist/chunks/studio-c7q0t9x1.js +5 -0
- package/dist/chunks/studio-camnhc96.js +6 -0
- package/dist/chunks/studio-cffqvnzd.js +5 -0
- package/dist/chunks/studio-d81xfh1g.js +5 -0
- package/dist/chunks/studio-dgz8d0c1.js +5 -0
- package/dist/chunks/studio-efvfrsf8.js +5 -0
- package/dist/chunks/studio-er30bpcx.js +5 -0
- package/dist/chunks/studio-ezscgr64.js +5 -0
- package/dist/chunks/studio-ffrrncvz.js +5 -0
- package/dist/chunks/studio-fpphgn8y.js +10 -0
- package/dist/chunks/studio-j1kvhdjk.js +4 -0
- package/dist/chunks/{studio-txjjzrsm.js → studio-j430n16g.js} +5 -5
- package/dist/chunks/studio-jjkg84nj.js +5 -0
- package/dist/chunks/studio-m0q32ars.js +4 -0
- package/dist/chunks/studio-m6bdst11.js +5 -0
- package/dist/chunks/studio-nv2cptd4.js +64 -0
- package/dist/chunks/studio-nwfrc98n.js +5 -0
- package/dist/chunks/studio-p1wgvp7r.js +5 -0
- package/dist/chunks/studio-pag2wncm.js +5 -0
- package/dist/chunks/studio-qvanvzfd.js +5 -0
- package/dist/chunks/studio-qwa64kt7.js +5 -0
- package/dist/chunks/studio-rk1zc4x3.js +928 -0
- package/dist/chunks/studio-se2r3ptc.js +5 -0
- package/dist/chunks/studio-sg2a0dh0.js +5 -0
- package/dist/chunks/studio-tjzjhe68.js +5 -0
- package/dist/chunks/{studio-0x3jyb8r.js → studio-tq0rtfwj.js} +4 -4
- package/dist/chunks/{studio-cpxkgjrj.js → studio-v0jzqdjm.js} +4 -4
- package/dist/chunks/studio-v2w7q8r1.js +7 -0
- package/dist/chunks/studio-v5vjq1h0.js +4 -0
- package/dist/chunks/studio-v8aga3vp.js +14 -0
- package/dist/chunks/studio-vfcdrfmv.js +5 -0
- package/dist/chunks/studio-vmfkgdjf.js +5 -0
- package/dist/chunks/studio-wt1816jj.js +5 -0
- package/dist/chunks/studio-wz73q5kq.js +4 -0
- package/dist/chunks/studio-y04qtxvp.js +7 -0
- package/dist/chunks/studio-y21g8zzg.js +5 -0
- package/dist/chunks/studio-y64hrt8p.js +12 -0
- package/dist/chunks/studio-ynn90f58.js +16 -0
- package/dist/chunks/studio-yxz682sx.js +5 -0
- package/dist/chunks/studio-zp7snvkq.js +5 -0
- package/dist/chunks/studio-zq4z6tm6.js +5 -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-c9fn075p.js +4 -0
- package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
- package/dist/chunks/tree-mdq3v5cw.js +4 -0
- package/dist/chunks/tsMode-sf49ee9x.js +14 -0
- package/dist/chunks/workspace-jtfahpee.js +4 -0
- package/dist/chunks/ws-client-nze0k6mv.js +4 -0
- package/dist/iframe-entry.js +16 -16
- package/dist/manifest.json +63 -63
- package/dist/studio.js +98 -98
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +11 -11
- 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/library-layouts.ts +8 -5
- package/src/browse/library-model.ts +18 -6
- package/src/browse/library-pane.ts +37 -21
- package/src/browse/library-preview.ts +14 -9
- package/src/browse/library-source.ts +1 -1
- package/src/canvas/asset-refs.ts +24 -9
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +44 -53
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +66 -42
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +163 -64
- 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 +13 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +80 -63
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +203 -118
- package/src/canvas/iframe-inline-edit.ts +69 -32
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +37 -26
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +18 -15
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +15 -16
- package/src/canvas/iframe-render.ts +41 -36
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +6 -2
- 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/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +2 -1
- package/src/canvas/surface-registry.ts +21 -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/budget.ts +3 -3
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +22 -20
- package/src/commands/defaults.ts +4 -1
- package/src/commands/keymap.ts +47 -43
- package/src/commands/levels.ts +3 -3
- package/src/commands/live-context.ts +10 -8
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +12 -10
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +5 -4
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +3 -2
- package/src/content/entry-editor.ts +29 -17
- package/src/content/entry-fields.ts +12 -7
- package/src/content/entry-model.ts +21 -12
- 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 +11 -5
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +21 -22
- package/src/editor/inline-edit-apply.ts +35 -17
- package/src/editor/inline-edit.ts +66 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-zone-action.ts +1 -1
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +87 -47
- package/src/editor/slash-menu.ts +1 -6
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +15 -10
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +77 -36
- package/src/files/files.ts +90 -95
- package/src/files/media-meta.ts +2 -1
- package/src/files/media-paths.ts +6 -1
- package/src/files/serialize-document.ts +2 -2
- 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 +76 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +19 -9
- package/src/github/github-publish.ts +24 -20
- 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 +20 -22
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -6
- package/src/grid/grid-panel.ts +11 -4
- package/src/grid/grid-source.ts +8 -8
- package/src/grid/grid-view.ts +14 -17
- 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 +25 -24
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +55 -34
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +1 -2
- package/src/media/media-pane.ts +4 -1
- 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 +17 -9
- package/src/panels/ai-chat/attached-context.ts +13 -7
- 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 +46 -35
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +31 -24
- package/src/panels/data-explorer.ts +62 -25
- package/src/panels/data-grid.ts +14 -11
- package/src/panels/dnd.ts +108 -118
- package/src/panels/editors.ts +55 -22
- package/src/panels/elements-panel.ts +10 -3
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +76 -51
- package/src/panels/frontmatter-fields.ts +24 -19
- package/src/panels/frontmatter-panel.ts +44 -34
- package/src/panels/git-diff-open.ts +4 -4
- package/src/panels/git-panel.ts +49 -61
- package/src/panels/head-panel.ts +131 -111
- package/src/panels/i18n-panel.ts +10 -3
- package/src/panels/imports-panel.ts +23 -47
- package/src/panels/jump-bar.ts +48 -29
- package/src/panels/layers-panel.ts +97 -74
- package/src/panels/left-panel.ts +3 -3
- package/src/panels/pane-context.ts +31 -22
- package/src/panels/pane-grid.ts +49 -20
- package/src/panels/panel-registry.ts +22 -37
- package/src/panels/properties-panel.ts +175 -121
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +3 -3
- package/src/panels/seo-modal.ts +13 -17
- package/src/panels/settings-menu.ts +15 -15
- package/src/panels/signals-panel.ts +153 -131
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +254 -216
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +57 -54
- package/src/panels/stylebook-layers-panel.ts +9 -9
- package/src/panels/stylebook-panel.ts +13 -17
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +36 -26
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +58 -30
- package/src/platforms/cloud.ts +345 -175
- package/src/platforms/default-platform.ts +10 -4
- package/src/platforms/devserver.ts +174 -127
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +8 -2
- package/src/publish/pages-service.ts +28 -13
- package/src/publish/publish-commands.ts +5 -4
- package/src/publish/publish-panel.ts +10 -6
- 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 +58 -31
- package/src/services/cem-export.ts +149 -58
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- 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 +18 -12
- 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 +8 -7
- 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 +79 -60
- package/src/settings/css-vars-editor.ts +37 -16
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +23 -13
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +11 -8
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +9 -6
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +1 -1
- package/src/settings/schema-field-ui.ts +9 -0
- package/src/settings/settings-document.ts +5 -5
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +104 -81
- package/src/site-context.ts +37 -22
- package/src/state.ts +41 -49
- package/src/store.ts +54 -34
- package/src/studio.ts +39 -77
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +6 -7
- package/src/style/token-ref.ts +5 -4
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +31 -36
- 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.ts +4 -5
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.ts +12 -11
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/commandbar.ts +14 -9
- 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/doc-header.ts +10 -19
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.ts +14 -11
- 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/git-panel.ts +7 -15
- 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.ts +13 -12
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.ts +25 -20
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.ts +11 -10
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/menu.ts +29 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.ts +20 -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.ts +5 -6
- 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.ts +11 -18
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.ts +20 -34
- package/src/surfaces/panel-stylebook-layers.ts +5 -8
- package/src/surfaces/preferences.ts +21 -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.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.json +126 -73
- package/src/surfaces/rail.ts +38 -12
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.ts +15 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.ts +14 -10
- package/src/surfaces/settings-css-vars.ts +5 -12
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.ts +8 -15
- 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.ts +5 -6
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.ts +9 -18
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/slash-menu.ts +19 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +17 -14
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +5 -7
- 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 +52 -41
- package/src/tabs/transact.ts +98 -53
- package/src/tabs/typing.ts +31 -0
- package/src/types.ts +32 -17
- 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 +57 -48
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +44 -31
- package/src/ui/media-picker.ts +18 -9
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +7 -6
- package/src/ui/schema-form.ts +113 -70
- 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 +3 -2
- package/src/utils/base64.ts +3 -1
- package/src/utils/edit-display.ts +103 -74
- 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/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 +10 -12
- package/src/workspace/session.ts +53 -43
- package/src/workspace/workspace.ts +47 -36
- package/dist/chunks/2020-nkxms0ay.js +0 -4
- package/dist/chunks/adapter-m948ab5f.js +0 -4
- package/dist/chunks/cf-account-picker-n8hr38v7.js +0 -4
- package/dist/chunks/cf-settings-356xdtne.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-yk3t844e.js +0 -4
- package/dist/chunks/content-source-bawmyc09.js +0 -4
- package/dist/chunks/convert-to-repeater-7wns8kf1.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-6sc8nacq.js +0 -4
- package/dist/chunks/entry-commands-8ay9fh81.js +0 -4
- package/dist/chunks/extension-sections-na7rj3nr.js +0 -4
- package/dist/chunks/file-ops-gye0qw56.js +0 -4
- package/dist/chunks/files-dmc2xvcq.js +0 -4
- package/dist/chunks/format-host-t76b53f8.js +0 -4
- package/dist/chunks/fs-events-cg4tpz06.js +0 -4
- package/dist/chunks/git-panel-yef7bshy.js +0 -4
- package/dist/chunks/grid-view-7tt4bxw1.js +0 -51
- package/dist/chunks/icons-qbh8akb1.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-tmz30gfp.js +0 -4
- package/dist/chunks/index-nag78a9h.js +0 -4
- package/dist/chunks/jsonMode-zhwsprqk.js +0 -13
- package/dist/chunks/jx-validate-3gbp5nkn.js +0 -4
- package/dist/chunks/layers-fvz99859.js +0 -4
- package/dist/chunks/layers-panel-gchmbf9p.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-9agdspkt.js +0 -4
- package/dist/chunks/media-picker-rhjvyy00.js +0 -4
- package/dist/chunks/menu-2e4y9j7b.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/monaco-binding-2jnhjjvr.js +0 -4
- package/dist/chunks/monaco-buffer-rp21359g.js +0 -4
- package/dist/chunks/monaco-setup-vhh7gayr.js +0 -4
- package/dist/chunks/notify-h3www560.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-hz34wcd7.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-exsmjzyj.js +0 -4
- package/dist/chunks/quick-search-pgaqeh0m.js +0 -4
- package/dist/chunks/references-2cgdxnb8.js +0 -4
- package/dist/chunks/right-panel-jf856w5w.js +0 -4
- package/dist/chunks/section-registry-jnf8r5gy.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0f55h9ye.js +0 -5
- package/dist/chunks/studio-0sqdhnew.js +0 -12
- package/dist/chunks/studio-19x1c75w.js +0 -5
- package/dist/chunks/studio-2sqcndak.js +0 -5
- package/dist/chunks/studio-3aey7dd3.js +0 -5
- package/dist/chunks/studio-3bpdkq2s.js +0 -5
- package/dist/chunks/studio-47y6fbpf.js +0 -5
- package/dist/chunks/studio-4m3826v2.js +0 -5
- package/dist/chunks/studio-4nx2dj1g.js +0 -4
- package/dist/chunks/studio-4xv5s47r.js +0 -9
- package/dist/chunks/studio-5g4t8v6w.js +0 -5
- package/dist/chunks/studio-5py436sf.js +0 -5
- package/dist/chunks/studio-77kt594t.js +0 -5
- package/dist/chunks/studio-8f87n763.js +0 -10
- package/dist/chunks/studio-8mb00b84.js +0 -5
- package/dist/chunks/studio-8p51gq2h.js +0 -6
- package/dist/chunks/studio-954ds834.js +0 -5
- package/dist/chunks/studio-9ft45c83.js +0 -9
- package/dist/chunks/studio-a2138x5k.js +0 -7
- package/dist/chunks/studio-a9yzstqj.js +0 -5
- package/dist/chunks/studio-acdksxx6.js +0 -5
- package/dist/chunks/studio-ar8jcf2y.js +0 -5
- package/dist/chunks/studio-bmn4mn9j.js +0 -7
- package/dist/chunks/studio-e7xxa0sj.js +0 -5
- package/dist/chunks/studio-ecaz25vk.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-fzdywr6p.js +0 -9
- package/dist/chunks/studio-g5fmf0c1.js +0 -5
- package/dist/chunks/studio-g7nse7zb.js +0 -5
- package/dist/chunks/studio-geq1ea6k.js +0 -14
- package/dist/chunks/studio-ghkb32r8.js +0 -5
- package/dist/chunks/studio-ghrhy2y7.js +0 -5
- package/dist/chunks/studio-grawhey1.js +0 -5
- package/dist/chunks/studio-h0xgswew.js +0 -5
- package/dist/chunks/studio-h9c4p2tx.js +0 -5
- package/dist/chunks/studio-jyzj5cxs.js +0 -5
- package/dist/chunks/studio-mgx8yhnz.js +0 -64
- package/dist/chunks/studio-mpb04y1d.js +0 -6
- package/dist/chunks/studio-n17mty64.js +0 -5
- package/dist/chunks/studio-nwh2eqsk.js +0 -6
- package/dist/chunks/studio-q1h883bt.js +0 -16
- package/dist/chunks/studio-q4tv82h7.js +0 -9
- package/dist/chunks/studio-qpqa7vk3.js +0 -5
- package/dist/chunks/studio-qqz8e5gk.js +0 -5
- package/dist/chunks/studio-qvasen3f.js +0 -5
- package/dist/chunks/studio-rggdb3hm.js +0 -5
- package/dist/chunks/studio-sghy936h.js +0 -4
- package/dist/chunks/studio-skprc6ef.js +0 -5
- package/dist/chunks/studio-tt2nactf.js +0 -5
- package/dist/chunks/studio-tyasmc39.js +0 -5
- package/dist/chunks/studio-vk9ezads.js +0 -5
- package/dist/chunks/studio-vzacdfsc.js +0 -4
- package/dist/chunks/studio-w4c0xmrw.js +0 -5
- package/dist/chunks/studio-wfjqhhbk.js +0 -5
- package/dist/chunks/studio-wgh5kxpj.js +0 -5
- package/dist/chunks/studio-xasj0796.js +0 -5
- package/dist/chunks/studio-y78s8r2n.js +0 -5
- package/dist/chunks/studio-z8w183sh.js +0 -5
- package/dist/chunks/studio-zscd9ty4.js +0 -928
- package/dist/chunks/studio-zxp13sss.js +0 -7
- package/dist/chunks/studio-zygnmm01.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-gr0m4dzr.js +0 -14
- package/dist/chunks/workspace-m15qtcqp.js +0 -4
- package/dist/chunks/ws-client-nf61frr1.js +0 -4
|
@@ -42,10 +42,11 @@
|
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
44
|
import { nothing } from "lit-html";
|
|
45
|
-
import {
|
|
45
|
+
import { getNodeAtPath } from "@jxsuite/schema/doc-ops";
|
|
46
|
+
import { getEventBinding, isExpressionDef, isJsonObject, isString } from "@jxsuite/schema/guards";
|
|
46
47
|
|
|
47
48
|
import { effect, effectScope, shallowRef } from "../reactivity";
|
|
48
|
-
import {
|
|
49
|
+
import { updateUi } from "../store";
|
|
49
50
|
import { activeTab } from "../workspace/workspace";
|
|
50
51
|
import { mutateAddDef, mutateUpdateDef, mutateUpdateProperty, transactDoc } from "../tabs/transact";
|
|
51
52
|
import { setBottomTab } from "../shell";
|
|
@@ -69,14 +70,19 @@ import {
|
|
|
69
70
|
stringProperty,
|
|
70
71
|
} from "../commands/command-args";
|
|
71
72
|
|
|
72
|
-
import type { JxNodeValue } from "../tabs/transact";
|
|
73
73
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
74
74
|
import type { PanelBody } from "./panel-registry";
|
|
75
75
|
import type { ExpressionPreview } from "../services/preview-eval";
|
|
76
|
-
import type { FormulaEditDef, FunctionEditDef
|
|
76
|
+
import type { FormulaEditDef, FunctionEditDef } from "../types";
|
|
77
77
|
import type { Tab } from "../tabs/tab";
|
|
78
|
-
import type {
|
|
78
|
+
import type {
|
|
79
|
+
JsonObject,
|
|
80
|
+
JsonValue,
|
|
81
|
+
JxEventBinding,
|
|
82
|
+
JxStateDefinition,
|
|
83
|
+
} from "@jxsuite/schema/types";
|
|
79
84
|
import type { EffectScope } from "@vue/reactivity";
|
|
85
|
+
import type { ScopeValue } from "../editor/merge-tags";
|
|
80
86
|
import type {
|
|
81
87
|
LogicChipView,
|
|
82
88
|
LogicScopeEntryView,
|
|
@@ -125,10 +131,10 @@ export function logicTarget(tab: Tab | null = activeTab.value): LogicTarget | nu
|
|
|
125
131
|
return null;
|
|
126
132
|
}
|
|
127
133
|
if (ui.editingFunction) {
|
|
128
|
-
return { editing: ui.editingFunction
|
|
134
|
+
return { editing: ui.editingFunction, surface: "function" };
|
|
129
135
|
}
|
|
130
136
|
if (ui.editingFormula) {
|
|
131
|
-
return { editing: ui.editingFormula
|
|
137
|
+
return { editing: ui.editingFormula, surface: "formula" };
|
|
132
138
|
}
|
|
133
139
|
return null;
|
|
134
140
|
}
|
|
@@ -176,25 +182,35 @@ export function openLogicTarget(target: LogicTarget): void {
|
|
|
176
182
|
revealLogicPanel();
|
|
177
183
|
}
|
|
178
184
|
|
|
179
|
-
|
|
180
|
-
|
|
185
|
+
/** An expression node: a plain object naming its `operator`. */
|
|
186
|
+
function isExprNode(value: JsonValue | undefined): value is JsonObject {
|
|
187
|
+
return isJsonObject(value) && isString(value.operator);
|
|
181
188
|
}
|
|
182
189
|
|
|
183
190
|
// ─── Document access ─────────────────────────────────────────────────────────
|
|
184
191
|
|
|
192
|
+
/**
|
|
193
|
+
* The `$expression` of an expression entry or binding, as the JSON object it is; null for anything
|
|
194
|
+
* else. `isExpressionDef` has already checked it is a plain object, and the guard carries that to
|
|
195
|
+
* the type.
|
|
196
|
+
*/
|
|
197
|
+
function expressionOf(value: JxStateDefinition | JxEventBinding | undefined): JsonObject | null {
|
|
198
|
+
if (!isExpressionDef(value)) {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
const { $expression } = value;
|
|
202
|
+
return isJsonObject($expression) ? $expression : null;
|
|
203
|
+
}
|
|
204
|
+
|
|
185
205
|
/** Read the workspace target's current root expression node from the document. */
|
|
186
|
-
export function formulaRoot(tab: Tab, editing: FormulaEditDef):
|
|
206
|
+
export function formulaRoot(tab: Tab, editing: FormulaEditDef): JsonObject | null {
|
|
187
207
|
const { document } = tab.doc;
|
|
188
208
|
if (editing.type === "def" && editing.defName) {
|
|
189
|
-
|
|
190
|
-
return isExpressionDef(def) ? (def.$expression as unknown as Record<string, unknown>) : null;
|
|
209
|
+
return expressionOf(document.state?.[editing.defName]);
|
|
191
210
|
}
|
|
192
211
|
if (editing.type === "event" && editing.path && editing.eventKey) {
|
|
193
212
|
const node = getNodeAtPath(document, editing.path);
|
|
194
|
-
|
|
195
|
-
return isExpressionDef(binding)
|
|
196
|
-
? (binding.$expression as unknown as Record<string, unknown>)
|
|
197
|
-
: null;
|
|
213
|
+
return expressionOf(node ? getEventBinding(node, editing.eventKey) : undefined);
|
|
198
214
|
}
|
|
199
215
|
return null;
|
|
200
216
|
}
|
|
@@ -203,18 +219,18 @@ export function formulaRoot(tab: Tab, editing: FormulaEditDef): Record<string, u
|
|
|
203
219
|
* Resolve a chip selection to its editable node: the deepest expression-node prefix of `path` (head
|
|
204
220
|
* chips target ref/literal operands; stale paths fall back toward the root).
|
|
205
221
|
*/
|
|
206
|
-
function resolveSelection(
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
): { node: Record<string, unknown>; path: NodePath } {
|
|
210
|
-
let current: unknown = root;
|
|
211
|
-
let node: Record<string, unknown> = root;
|
|
222
|
+
function resolveSelection(root: JsonObject, path: NodePath) {
|
|
223
|
+
let current: JsonValue | undefined = root;
|
|
224
|
+
let node = root;
|
|
212
225
|
let nodePath: NodePath = [];
|
|
213
226
|
for (const [i, seg] of path.entries()) {
|
|
214
|
-
if (
|
|
227
|
+
if (Array.isArray(current)) {
|
|
228
|
+
current = current[Number(seg)];
|
|
229
|
+
} else if (isJsonObject(current)) {
|
|
230
|
+
current = current[String(seg)];
|
|
231
|
+
} else {
|
|
215
232
|
break;
|
|
216
233
|
}
|
|
217
|
-
current = (current as Record<string, unknown>)[seg as keyof typeof current];
|
|
218
234
|
if (isExprNode(current)) {
|
|
219
235
|
node = current;
|
|
220
236
|
nodePath = path.slice(0, i + 1);
|
|
@@ -224,30 +240,28 @@ function resolveSelection(
|
|
|
224
240
|
}
|
|
225
241
|
|
|
226
242
|
/** Immutably replace the value at `path` within `node` (object keys / array indexes). */
|
|
227
|
-
function replaceAtPath(node:
|
|
228
|
-
|
|
243
|
+
function replaceAtPath(node: JsonValue | undefined, path: NodePath, value: JsonValue): JsonValue {
|
|
244
|
+
const [head, ...rest] = path;
|
|
245
|
+
if (head === undefined) {
|
|
229
246
|
return value;
|
|
230
247
|
}
|
|
231
|
-
const [head, ...rest] = path as [string | number, ...NodePath];
|
|
232
248
|
if (Array.isArray(node)) {
|
|
233
|
-
const copy = [...
|
|
249
|
+
const copy = [...node];
|
|
234
250
|
copy[Number(head)] = replaceAtPath(copy[Number(head)], rest, value);
|
|
235
251
|
return copy;
|
|
236
252
|
}
|
|
237
|
-
const base:
|
|
238
|
-
return { ...base, [head]: replaceAtPath(base[head
|
|
253
|
+
const base: JsonObject = isJsonObject(node) ? node : {};
|
|
254
|
+
return { ...base, [head]: replaceAtPath(base[head], rest, value) };
|
|
239
255
|
}
|
|
240
256
|
|
|
241
257
|
/** Write the whole updated root node back to the document position (one undo step). */
|
|
242
|
-
function writeRoot(tab: Tab, editing: FormulaEditDef, newRoot:
|
|
258
|
+
function writeRoot(tab: Tab, editing: FormulaEditDef, newRoot: JsonValue) {
|
|
243
259
|
if (editing.type === "def" && editing.defName) {
|
|
244
260
|
const { defName } = editing;
|
|
245
|
-
transactDoc(tab, (t) => mutateUpdateDef(t, defName, { $expression: newRoot
|
|
261
|
+
transactDoc(tab, (t) => mutateUpdateDef(t, defName, { $expression: newRoot }));
|
|
246
262
|
} else if (editing.type === "event" && editing.path && editing.eventKey) {
|
|
247
263
|
const { eventKey, path } = editing;
|
|
248
|
-
transactDoc(tab, (t) =>
|
|
249
|
-
mutateUpdateProperty(t, path, eventKey, { $expression: newRoot } as JxNodeValue),
|
|
250
|
-
);
|
|
264
|
+
transactDoc(tab, (t) => mutateUpdateProperty(t, path, eventKey, { $expression: newRoot }));
|
|
251
265
|
}
|
|
252
266
|
}
|
|
253
267
|
|
|
@@ -295,8 +309,8 @@ function selectionKey(editing: FormulaEditDef): string {
|
|
|
295
309
|
interface Resolved {
|
|
296
310
|
tab: Tab;
|
|
297
311
|
editing: FormulaEditDef;
|
|
298
|
-
root:
|
|
299
|
-
selected:
|
|
312
|
+
root: JsonObject;
|
|
313
|
+
selected: JsonObject;
|
|
300
314
|
selectedPath: NodePath;
|
|
301
315
|
stateEntries: Record<string, JxStateDefinition>;
|
|
302
316
|
preview: ExpressionPreview | null;
|
|
@@ -304,19 +318,27 @@ interface Resolved {
|
|
|
304
318
|
/** Chip key → node path, so a chip click needs no path parsing (a `switch` case may hold "/"). */
|
|
305
319
|
chipPaths: Map<string, NodePath>;
|
|
306
320
|
/** Rail entry name → the value its tree draws. */
|
|
307
|
-
scopeValues: Map<string,
|
|
321
|
+
scopeValues: Map<string, ScopeValue>;
|
|
308
322
|
}
|
|
309
323
|
|
|
310
324
|
let _resolved: Resolved | null = null;
|
|
311
325
|
|
|
312
|
-
/**
|
|
313
|
-
|
|
326
|
+
/**
|
|
327
|
+
* Replace the selected sub-node inside the root and write the whole root back.
|
|
328
|
+
*
|
|
329
|
+
* Typed as the expression editor's own change callback, which is one of its two callers; the other
|
|
330
|
+
* is a catalog pick's `onChange`.
|
|
331
|
+
*/
|
|
332
|
+
const writeSelected: Parameters<typeof mountExpressionEditor>[2] = (next) => {
|
|
314
333
|
const held = _resolved;
|
|
315
334
|
if (!held) {
|
|
316
335
|
return;
|
|
317
336
|
}
|
|
318
|
-
|
|
319
|
-
|
|
337
|
+
/* SAFETY: both callers hand back an expression node built of JSON operator/operand values: the
|
|
338
|
+
expression editor's edited tree, and the node a catalog pick inserts (a JxExpressionNode). */
|
|
339
|
+
const node = next as JsonValue;
|
|
340
|
+
writeRoot(held.tab, held.editing, replaceAtPath(held.root, held.selectedPath, node));
|
|
341
|
+
};
|
|
320
342
|
|
|
321
343
|
// ─── The projection ──────────────────────────────────────────────────────────
|
|
322
344
|
|
|
@@ -354,13 +376,13 @@ function resultOf(
|
|
|
354
376
|
}
|
|
355
377
|
|
|
356
378
|
/** The live data context — a SECOND opinion now that the page itself is on screen, not the only one. */
|
|
357
|
-
function railOf(scope:
|
|
358
|
-
entries: LogicScopeEntryView[];
|
|
359
|
-
values: Map<string, unknown>;
|
|
360
|
-
} {
|
|
379
|
+
function railOf(scope: Tab["session"]["canvas"]["scope"] | undefined) {
|
|
361
380
|
const entries: LogicScopeEntryView[] = [];
|
|
362
|
-
const values = new Map<string,
|
|
363
|
-
|
|
381
|
+
const values = new Map<string, ScopeValue>();
|
|
382
|
+
/* SAFETY: the canvas scope's one writer (iframe-host.ts, on a `dataScope` message) stores that
|
|
383
|
+
message's `scope`, a JsonObject of deep-cloned values (serialize-scope.ts). */
|
|
384
|
+
const snapshot = (scope ?? {}) as JsonObject;
|
|
385
|
+
for (const [name, value] of Object.entries(snapshot)) {
|
|
364
386
|
entries.push({ key: name, name, type: dataTypeLabel(value) });
|
|
365
387
|
values.set(name, unwrapSignal(value));
|
|
366
388
|
}
|
|
@@ -422,7 +444,7 @@ export function workspaceView(): LogicWorkspaceView {
|
|
|
422
444
|
};
|
|
423
445
|
}
|
|
424
446
|
|
|
425
|
-
const stateEntries =
|
|
447
|
+
const stateEntries = tab.doc.document.state ?? {};
|
|
426
448
|
/* Live-context evaluation in the canvas iframe with snapshot fallback (M6). The canvas is no
|
|
427
449
|
longer unmounted while this surface is open — that is the entire point of the move — so the
|
|
428
450
|
live path is the ORDINARY case now rather than the one that never happened. An event target's
|
|
@@ -595,7 +617,10 @@ const ACTIONS: LogicWorkspaceActions = {
|
|
|
595
617
|
};
|
|
596
618
|
|
|
597
619
|
/** Vendor a packaged formula's state entry into the document, as one undo step. */
|
|
598
|
-
function insertDef(defName: string, def:
|
|
620
|
+
function insertDef(defName: string, def: JxStateDefinition): void {
|
|
621
|
+
/* SAFETY: the only def the editor and the catalog insert is a packaged formula's vendored entry
|
|
622
|
+
(formula-catalog.ts `ensure`): `$description`, `$expression` and `parameters`, all JSON from
|
|
623
|
+
@jxsuite/formulas. */
|
|
599
624
|
transactDoc(activeTab.value, (t) => mutateAddDef(t, defName, def as Record<string, JsonValue>));
|
|
600
625
|
}
|
|
601
626
|
|
|
@@ -750,7 +775,7 @@ export function formulaEditorCommands(): AnyCommand[] {
|
|
|
750
775
|
if (!tab) {
|
|
751
776
|
throw new RangeError(`command "formula.editDef" needs an open document`);
|
|
752
777
|
}
|
|
753
|
-
const defs = tab.doc.document
|
|
778
|
+
const defs = tab.doc.document.state ?? {};
|
|
754
779
|
if (!(defName in defs)) {
|
|
755
780
|
const defined = Object.keys(defs);
|
|
756
781
|
throw new RangeError(
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* the two hosts. The Page panel was the last one, and the renderer went with it.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
+
import { isBoolean, isString } from "@jxsuite/schema/guards";
|
|
23
24
|
import { previewAssetSrc } from "../canvas/asset-refs";
|
|
24
25
|
import { IMAGE_EXTENSIONS, extensionOf } from "../files/media-upload";
|
|
25
26
|
import { referenceEntryState } from "../ui/form-controls";
|
|
@@ -29,12 +30,14 @@ import { referenceTarget } from "../ui/schema-form";
|
|
|
29
30
|
import type { JsonValue } from "../types";
|
|
30
31
|
import type { Tab } from "../tabs/tab";
|
|
31
32
|
import type { ProjectConfig } from "@jxsuite/schema/types";
|
|
33
|
+
import type { SurfaceOption } from "../ui/surface";
|
|
32
34
|
|
|
33
35
|
export interface FmSchemaEntry {
|
|
34
36
|
type?: string;
|
|
35
37
|
enum?: string[];
|
|
36
38
|
format?: string;
|
|
37
|
-
|
|
39
|
+
/** A nested object field's own field schemas. */
|
|
40
|
+
properties?: Record<string, FmSchemaEntry>;
|
|
38
41
|
/** `#/content/<type>` — a relationship to another collection (site-architecture.md §6.1). */
|
|
39
42
|
$ref?: string;
|
|
40
43
|
}
|
|
@@ -42,7 +45,8 @@ export interface FmSchemaEntry {
|
|
|
42
45
|
export interface FmField {
|
|
43
46
|
field: string;
|
|
44
47
|
entry: FmSchemaEntry;
|
|
45
|
-
|
|
48
|
+
/** What the document holds under the key; `undefined` for a schema field it does not set. */
|
|
49
|
+
value: JsonValue | undefined;
|
|
46
50
|
}
|
|
47
51
|
|
|
48
52
|
export interface FmFieldSet {
|
|
@@ -70,8 +74,15 @@ export function collectFmFields(
|
|
|
70
74
|
projectConfig: ProjectConfig | null | undefined,
|
|
71
75
|
reserved: Set<string>,
|
|
72
76
|
): FmFieldSet {
|
|
73
|
-
|
|
77
|
+
/* SAFETY: `FormatFrontmatter` holds `JxDocumentValue`, which is the JSON value space seen through
|
|
78
|
+
the typed interfaces a document's declared keys use (JxRef, JxStatement, CemEvent, ...). Every
|
|
79
|
+
frontmatter value is parsed from the file by a format class's split or JSON-cloned from one, so
|
|
80
|
+
each is plain JSON data, and viewing it as JsonValue reads the same data without those views. */
|
|
81
|
+
const fm = tab.doc.content.frontmatter as Record<string, JsonValue | undefined>;
|
|
74
82
|
const collection = findContentTypeSchema(tab.documentPath, projectConfig);
|
|
83
|
+
/* SAFETY: a collection schema is JSON Schema, and the only keywords an FmSchemaEntry reads —
|
|
84
|
+
`type`, `format`, `$ref` (strings) and `enum` (a list of choices) — carry those shapes there;
|
|
85
|
+
`required` is already typed `string[]` on ContentTypeSchema. */
|
|
75
86
|
const schema = collection?.schema as
|
|
76
87
|
| { properties?: Record<string, FmSchemaEntry>; required?: string[] }
|
|
77
88
|
| undefined;
|
|
@@ -84,16 +95,16 @@ export function collectFmFields(
|
|
|
84
95
|
if (reserved.has(field)) {
|
|
85
96
|
continue;
|
|
86
97
|
}
|
|
87
|
-
fields.push({ entry: fieldSchema, field, value: fm[field]
|
|
98
|
+
fields.push({ entry: fieldSchema, field, value: fm[field] });
|
|
88
99
|
}
|
|
89
100
|
for (const [field, value] of Object.entries(fm)) {
|
|
90
101
|
if (schemaProps[field] || field.startsWith("$") || reserved.has(field)) {
|
|
91
102
|
continue;
|
|
92
103
|
}
|
|
93
104
|
fields.push({
|
|
94
|
-
entry: { type:
|
|
105
|
+
entry: { type: isBoolean(value) ? "boolean" : "string" },
|
|
95
106
|
field,
|
|
96
|
-
value
|
|
107
|
+
value,
|
|
97
108
|
});
|
|
98
109
|
}
|
|
99
110
|
} else {
|
|
@@ -102,9 +113,9 @@ export function collectFmFields(
|
|
|
102
113
|
continue;
|
|
103
114
|
}
|
|
104
115
|
fields.push({
|
|
105
|
-
entry: { type:
|
|
116
|
+
entry: { type: isBoolean(value) ? "boolean" : "string" },
|
|
106
117
|
field,
|
|
107
|
-
value
|
|
118
|
+
value,
|
|
108
119
|
});
|
|
109
120
|
}
|
|
110
121
|
}
|
|
@@ -112,12 +123,6 @@ export function collectFmFields(
|
|
|
112
123
|
return { collection, fields, hasSchema: Boolean(schemaProps), requiredFields };
|
|
113
124
|
}
|
|
114
125
|
|
|
115
|
-
/** One choice in a row's picker — the shape `jx-select` reads. */
|
|
116
|
-
export interface FmChoice {
|
|
117
|
-
value: string;
|
|
118
|
-
label: string;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
126
|
/**
|
|
122
127
|
* One frontmatter field as a surface draws it. Every field is present whatever the `kind`, because
|
|
123
128
|
* a document's binding renders a value and its `$switch` chooses on one: a row that omitted
|
|
@@ -140,7 +145,7 @@ export interface FmRowView {
|
|
|
140
145
|
/** A text row's placeholder. Empty draws none. */
|
|
141
146
|
placeholder: string;
|
|
142
147
|
/** A picker's rows, in the order they are offered. Empty on every other kind. */
|
|
143
|
-
options:
|
|
148
|
+
options: SurfaceOption[];
|
|
144
149
|
/** A sentence under the control — an empty collection, or a listing that failed. */
|
|
145
150
|
note: string;
|
|
146
151
|
/** Whether {@link FmRowView.note} has anything in it; `$switch` is a document's conditional. */
|
|
@@ -162,8 +167,8 @@ export interface FmRowProjection {
|
|
|
162
167
|
}
|
|
163
168
|
|
|
164
169
|
/** A frontmatter value as the text a field shows. An object is not a string and never pretends. */
|
|
165
|
-
function text(value:
|
|
166
|
-
return
|
|
170
|
+
function text(value: JsonValue | undefined): string {
|
|
171
|
+
return isString(value) ? value : "";
|
|
167
172
|
}
|
|
168
173
|
|
|
169
174
|
/** A blank row, so every kind carries every field a surface's bindings read. */
|
|
@@ -188,7 +193,7 @@ function blankRow(label: string): FmRowView {
|
|
|
188
193
|
*
|
|
189
194
|
* @param {string} field The frontmatter key.
|
|
190
195
|
* @param {FmSchemaEntry} entry Its schema, or the type inferred from the value it already holds.
|
|
191
|
-
* @param {
|
|
196
|
+
* @param {JsonValue | undefined} value What the document says today.
|
|
192
197
|
* @param {Set<string>} requiredFields The collection's required keys, for the label's marker.
|
|
193
198
|
* @param {{ rerender: () => void }} opts How a surface is repainted when a referenced collection's
|
|
194
199
|
* entry ids land — the one asynchronous read a row can start.
|
|
@@ -197,7 +202,7 @@ function blankRow(label: string): FmRowView {
|
|
|
197
202
|
export function projectFmField(
|
|
198
203
|
field: string,
|
|
199
204
|
entry: FmSchemaEntry,
|
|
200
|
-
value:
|
|
205
|
+
value: JsonValue | undefined,
|
|
201
206
|
requiredFields: Set<string>,
|
|
202
207
|
opts: { rerender: () => void },
|
|
203
208
|
): FmRowProjection {
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
* @docs studio/editing/frontmatter
|
|
67
67
|
*/
|
|
68
68
|
|
|
69
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
69
70
|
import { projectState } from "../store";
|
|
70
71
|
import { workspace } from "../workspace/workspace";
|
|
71
72
|
import { tabOfPane } from "../canvas/canvas-surface";
|
|
@@ -90,18 +91,18 @@ import { activeRegistry } from "../commands/active-registry";
|
|
|
90
91
|
import { invalidateLayoutCache } from "../site-context";
|
|
91
92
|
import { mountDocHeaderSurface } from "../surfaces/doc-header";
|
|
92
93
|
|
|
93
|
-
import type { JxHeadEntry, JxMutableNode } from "@jxsuite/schema/types";
|
|
94
|
+
import type { JsonValue, JxHeadEntry, JxMutableNode } from "@jxsuite/schema/types";
|
|
94
95
|
import type { Tab } from "../tabs/tab";
|
|
95
96
|
import type { FmSchemaEntry } from "./frontmatter-fields";
|
|
96
97
|
import type * as MediaPickerModule from "../ui/media-picker";
|
|
97
98
|
import type {
|
|
98
99
|
DocHeaderActions,
|
|
99
|
-
DocHeaderChoice,
|
|
100
100
|
DocHeaderRawEntry,
|
|
101
101
|
DocHeaderRow,
|
|
102
102
|
DocHeaderSurface,
|
|
103
103
|
DocHeaderView,
|
|
104
104
|
} from "../surfaces/doc-header";
|
|
105
|
+
import type { SurfaceOption } from "../ui/surface";
|
|
105
106
|
|
|
106
107
|
/** What one row of the card writes. The document knows the control; this knows the document. */
|
|
107
108
|
interface RowCommit {
|
|
@@ -120,7 +121,13 @@ interface RowCommit {
|
|
|
120
121
|
* drawing a header the second `ref` to fire silently took the card away from the first, leaving one
|
|
121
122
|
* pane's Document Header frozen on the frontmatter of the moment it lost the handle.
|
|
122
123
|
*/
|
|
123
|
-
interface HeaderCard {
|
|
124
|
+
interface HeaderCard extends HeaderCardState {
|
|
125
|
+
/** Handed to the surface once, when it is mounted; every one of them reads `commits`. */
|
|
126
|
+
actions: DocHeaderActions;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** Everything a card holds except its actions, which are built over this and read it lazily. */
|
|
130
|
+
interface HeaderCardState {
|
|
124
131
|
/** The pane this card is drawn for. Held rather than looked up: an action has to answer it. */
|
|
125
132
|
paneId: string;
|
|
126
133
|
el: HTMLElement;
|
|
@@ -128,8 +135,6 @@ interface HeaderCard {
|
|
|
128
135
|
surface: DocHeaderSurface | null;
|
|
129
136
|
/** This pane's rows, by key. Rebuilt with each projection. */
|
|
130
137
|
commits: Map<string, RowCommit>;
|
|
131
|
-
/** Handed to the surface once, when it is mounted; every one of them reads `commits`. */
|
|
132
|
-
actions: DocHeaderActions;
|
|
133
138
|
/** Text edits waiting out {@link LIVE_PREVIEW}, one per row key. */
|
|
134
139
|
pending: Map<string, { commit: () => void; timer: ReturnType<typeof setTimeout> }>;
|
|
135
140
|
}
|
|
@@ -194,15 +199,20 @@ export function attachDocumentHeaderHost(paneId: string, el: HTMLElement | null)
|
|
|
194
199
|
if (!el) {
|
|
195
200
|
return;
|
|
196
201
|
}
|
|
197
|
-
const
|
|
198
|
-
actions: {} as DocHeaderActions,
|
|
202
|
+
const state: HeaderCardState = {
|
|
199
203
|
commits: new Map(),
|
|
200
204
|
el,
|
|
201
205
|
paneId,
|
|
202
206
|
pending: new Map(),
|
|
203
207
|
surface: null,
|
|
204
208
|
};
|
|
205
|
-
|
|
209
|
+
/* The same object, not a copy: the actions read `state.commits`, which a projection reassigns.
|
|
210
|
+
`settle` runs only on a reader's toggle, long after `card` is bound. */
|
|
211
|
+
const card: HeaderCard = Object.assign(state, {
|
|
212
|
+
actions: makeActions(state, () => {
|
|
213
|
+
settle(card);
|
|
214
|
+
}),
|
|
215
|
+
});
|
|
206
216
|
_hosts.set(paneId, card);
|
|
207
217
|
paint(paneId, card);
|
|
208
218
|
}
|
|
@@ -236,14 +246,12 @@ export function mount() {
|
|
|
236
246
|
void tab.doc.mode;
|
|
237
247
|
void tab.documentPath;
|
|
238
248
|
void tab.doc.document;
|
|
239
|
-
void tab.doc.document
|
|
240
|
-
void tab.doc.document
|
|
241
|
-
void tab.doc.document
|
|
242
|
-
const fm = tab.doc.content
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
void fm[key];
|
|
246
|
-
}
|
|
249
|
+
void tab.doc.document.title;
|
|
250
|
+
void tab.doc.document.$head;
|
|
251
|
+
void tab.doc.document.$layout;
|
|
252
|
+
const fm = tab.doc.content.frontmatter;
|
|
253
|
+
for (const key of Object.keys(fm)) {
|
|
254
|
+
void fm[key];
|
|
247
255
|
}
|
|
248
256
|
}
|
|
249
257
|
render();
|
|
@@ -309,12 +317,13 @@ export function render() {
|
|
|
309
317
|
* @returns {boolean}
|
|
310
318
|
*/
|
|
311
319
|
export function hasDocumentHeader(tab: Tab): boolean {
|
|
312
|
-
const fm = tab.doc.content
|
|
320
|
+
const fm = tab.doc.content.frontmatter;
|
|
313
321
|
const doc = tab.doc.document;
|
|
314
322
|
if (Object.keys(fm).length > 0) {
|
|
315
323
|
return true;
|
|
316
324
|
}
|
|
317
|
-
|
|
325
|
+
// `title` is typed a string, but a document read off disk may carry any JSON there.
|
|
326
|
+
if (isString(doc.title) || (doc.$head?.length ?? 0) > 0) {
|
|
318
327
|
return true;
|
|
319
328
|
}
|
|
320
329
|
// A page always has one, even an empty one: Title and Route are the two facts it must state.
|
|
@@ -368,7 +377,7 @@ function paint(paneId: string, card: HeaderCard): void {
|
|
|
368
377
|
*/
|
|
369
378
|
function viewFor(tab: Tab, paneId: string, card: HeaderCard): DocHeaderView {
|
|
370
379
|
const isContent = tab.doc.mode === "content";
|
|
371
|
-
const fm =
|
|
380
|
+
const fm = tab.doc.content.frontmatter;
|
|
372
381
|
// ONE view of the document's head material, whichever realm it lives in: frontmatter keys for a
|
|
373
382
|
// Markdown page, root properties for a JSON one.
|
|
374
383
|
const headDoc = isContent ? buildHeadDoc(tab.doc.document, fm) : tab.doc.document;
|
|
@@ -437,7 +446,7 @@ function titleRow(
|
|
|
437
446
|
applyMutation: (fn: (doc: JxMutableNode) => void) => void,
|
|
438
447
|
commits: Map<string, RowCommit>,
|
|
439
448
|
): DocHeaderRow {
|
|
440
|
-
const title =
|
|
449
|
+
const title = isString(headDoc.title) ? headDoc.title : "";
|
|
441
450
|
commits.set("title", {
|
|
442
451
|
clear: () =>
|
|
443
452
|
applyMutation((d) => {
|
|
@@ -485,7 +494,7 @@ function layoutRow(
|
|
|
485
494
|
const current = headDoc.$layout;
|
|
486
495
|
const defaultPath = projectState?.projectConfig?.defaults?.layout;
|
|
487
496
|
const defaultLabel = defaultPath ? layoutName(defaultPath) : "";
|
|
488
|
-
const options:
|
|
497
|
+
const options: SurfaceOption[] = [
|
|
489
498
|
{ label: defaultLabel ? `Default (${defaultLabel})` : "Default", value: "__default__" },
|
|
490
499
|
{ label: "None", value: "__none__" },
|
|
491
500
|
...entries.map((l) => ({ label: l.name, value: l.path })),
|
|
@@ -544,7 +553,7 @@ function fieldRow(
|
|
|
544
553
|
tab: Tab,
|
|
545
554
|
field: string,
|
|
546
555
|
entry: FmSchemaEntry,
|
|
547
|
-
value:
|
|
556
|
+
value: JsonValue | undefined,
|
|
548
557
|
requiredFields: Set<string>,
|
|
549
558
|
commits: Map<string, RowCommit>,
|
|
550
559
|
): DocHeaderRow {
|
|
@@ -564,15 +573,15 @@ function fieldRow(
|
|
|
564
573
|
* they cannot see, and the Page panel remains the surface that adds and removes them.
|
|
565
574
|
*/
|
|
566
575
|
function rawEntries(head: JxHeadEntry[]): DocHeaderRawEntry[] {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
+
const rows: DocHeaderRawEntry[] = [];
|
|
577
|
+
for (const entry of head) {
|
|
578
|
+
if (isManagedEntry(entry) || isGoogleFontEntry(entry) || isGoogleFontPreconnect(entry)) {
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
// The key counts the LISTED entries, as the index of the filtered list it replaces did.
|
|
582
|
+
rows.push({ key: `raw:${rows.length}`, label: entryLabel(entry), value: entryValue(entry) });
|
|
583
|
+
}
|
|
584
|
+
return rows;
|
|
576
585
|
}
|
|
577
586
|
|
|
578
587
|
// ─── The actions ─────────────────────────────────────────────────────────────
|
|
@@ -582,8 +591,9 @@ function rawEntries(head: JxHeadEntry[]): DocHeaderRawEntry[] {
|
|
|
582
591
|
*
|
|
583
592
|
* Made once per host and handed to the surface at mount, so every one of them reads the CURRENT
|
|
584
593
|
* commit table rather than closing over the projection that was standing when the card was drawn.
|
|
594
|
+
* `settleCard` repaints the whole card, which needs these actions, so it is handed in.
|
|
585
595
|
*/
|
|
586
|
-
function makeActions(card:
|
|
596
|
+
function makeActions(card: HeaderCardState, settleCard: () => void): DocHeaderActions {
|
|
587
597
|
const flush = (key: string): void => {
|
|
588
598
|
const waiting = card.pending.get(key);
|
|
589
599
|
if (waiting) {
|
|
@@ -645,7 +655,7 @@ function makeActions(card: HeaderCard): DocHeaderActions {
|
|
|
645
655
|
} catch {
|
|
646
656
|
// Storage full or unavailable — this card still folds, the next one just opens.
|
|
647
657
|
}
|
|
648
|
-
|
|
658
|
+
settleCard();
|
|
649
659
|
},
|
|
650
660
|
setNumber: (key, value) => now(key, value),
|
|
651
661
|
setRawOpen: (open) => {
|
|
@@ -660,7 +670,7 @@ function makeActions(card: HeaderCard): DocHeaderActions {
|
|
|
660
670
|
} else {
|
|
661
671
|
_rawOpen.delete(tab.id);
|
|
662
672
|
}
|
|
663
|
-
|
|
673
|
+
settleCard();
|
|
664
674
|
},
|
|
665
675
|
upload: (key) => {
|
|
666
676
|
flush(key);
|
|
@@ -132,8 +132,8 @@ export function openDiffTab(path: string): Tab {
|
|
|
132
132
|
*
|
|
133
133
|
* `files/files.ts` is imported dynamically because it imports `cleanupGitPanel` from
|
|
134
134
|
* `panels/git-panel.ts`, which imports this module: a static edge back would close that cycle.
|
|
135
|
-
* `openFileInTab` answers `void`
|
|
136
|
-
* resolved from the workspace
|
|
135
|
+
* `openFileInTab` answers `void` whether it opens a new tab or reveals one that was already open,
|
|
136
|
+
* so the tab is resolved from the workspace by its path.
|
|
137
137
|
*
|
|
138
138
|
* Answers null when the file could not be opened at all, which the caller states rather than
|
|
139
139
|
* silently leaving the stage on someone else's document.
|
|
@@ -143,6 +143,6 @@ export async function openComparisonTab(path: string): Promise<Tab | null> {
|
|
|
143
143
|
return openDiffTab(path);
|
|
144
144
|
}
|
|
145
145
|
const files = await import("../files/files");
|
|
146
|
-
|
|
147
|
-
return
|
|
146
|
+
await files.openFileInTab(path, {});
|
|
147
|
+
return [...workspace.tabs.values()].find((tab) => tab.documentPath === path) ?? null;
|
|
148
148
|
}
|