@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
package/src/state.ts
CHANGED
|
@@ -12,7 +12,15 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { ProjectState } from "./types";
|
|
15
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
displayTagName,
|
|
17
|
+
isBoolean,
|
|
18
|
+
isMappedArray,
|
|
19
|
+
isNonNullObject,
|
|
20
|
+
isNumber,
|
|
21
|
+
isRef,
|
|
22
|
+
isString,
|
|
23
|
+
} from "@jxsuite/schema/guards";
|
|
16
24
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
17
25
|
|
|
18
26
|
export type JxPath = (string | number)[];
|
|
@@ -20,23 +28,10 @@ export type JxPath = (string | number)[];
|
|
|
20
28
|
// ─── Path utilities ───────────────────────────────────────────────────────────
|
|
21
29
|
|
|
22
30
|
/**
|
|
23
|
-
* Walk the document tree and return the node at the given path
|
|
24
|
-
*
|
|
25
|
-
* @param {JxMutableNode} doc
|
|
26
|
-
* @param {JxPath} path
|
|
27
|
-
* @returns {JxMutableNode}
|
|
31
|
+
* Walk the document tree and return the node at the given path, or `undefined` when a step falls
|
|
32
|
+
* off the tree (a path gone stale since it was taken). One walk, shared with the document ops.
|
|
28
33
|
*/
|
|
29
|
-
export
|
|
30
|
-
let node = doc;
|
|
31
|
-
for (const key of path) {
|
|
32
|
-
if (node == null) {
|
|
33
|
-
return undefined as unknown as JxMutableNode;
|
|
34
|
-
}
|
|
35
|
-
// Paths address nodes by construction; non-node leaves surface as undefined above.
|
|
36
|
-
node = node[key] as JxMutableNode;
|
|
37
|
-
}
|
|
38
|
-
return node;
|
|
39
|
-
}
|
|
34
|
+
export { getNodeAtPath } from "@jxsuite/schema/doc-ops";
|
|
40
35
|
|
|
41
36
|
/**
|
|
42
37
|
* The node's children when they are a static array (the edit-mode invariant); an empty array for
|
|
@@ -56,11 +51,11 @@ export function childList(node: JxMutableNode | null | undefined): (JxMutableNod
|
|
|
56
51
|
* `$switch` cases. Runs once when a document is loaded into a tab so every in-studio doc — and its
|
|
57
52
|
* history checkpoints — uses the member form before any mutation.
|
|
58
53
|
*
|
|
59
|
-
* @param {
|
|
60
|
-
* @returns {
|
|
54
|
+
* @param {T} node
|
|
55
|
+
* @returns {T} The same node (mutated)
|
|
61
56
|
*/
|
|
62
|
-
export function normalizeArrayChildren(node:
|
|
63
|
-
if (!node
|
|
57
|
+
export function normalizeArrayChildren<T>(node: T): T {
|
|
58
|
+
if (!isNonNullObject(node)) {
|
|
64
59
|
return node;
|
|
65
60
|
}
|
|
66
61
|
if (Array.isArray(node)) {
|
|
@@ -69,14 +64,12 @@ export function normalizeArrayChildren(node: unknown): unknown {
|
|
|
69
64
|
}
|
|
70
65
|
return node;
|
|
71
66
|
}
|
|
67
|
+
/* SAFETY: A non-array object reached from a document root, a children array, a repeater `map` or
|
|
68
|
+
a `$switch` case is a node definition, and JxMutableNode is the editor's open node shape. */
|
|
72
69
|
const n = node as JxMutableNode;
|
|
73
70
|
const { children } = n;
|
|
74
|
-
if (
|
|
75
|
-
children
|
|
76
|
-
typeof children === "object" &&
|
|
77
|
-
!Array.isArray(children) &&
|
|
78
|
-
(children as JxMutableNode).$prototype === "Array"
|
|
79
|
-
) {
|
|
71
|
+
if (isMappedArray(children)) {
|
|
72
|
+
// SAFETY: A legacy whole-children repeater is the same repeater node that becomes the member.
|
|
80
73
|
n.children = [children as JxMutableNode];
|
|
81
74
|
}
|
|
82
75
|
if (Array.isArray(n.children)) {
|
|
@@ -84,10 +77,10 @@ export function normalizeArrayChildren(node: unknown): unknown {
|
|
|
84
77
|
normalizeArrayChildren(child);
|
|
85
78
|
}
|
|
86
79
|
}
|
|
87
|
-
if (n.$prototype === "Array" && n.map
|
|
80
|
+
if (n.$prototype === "Array" && isNonNullObject(n.map)) {
|
|
88
81
|
normalizeArrayChildren(n.map);
|
|
89
82
|
}
|
|
90
|
-
if (n.cases
|
|
83
|
+
if (isNonNullObject(n.cases)) {
|
|
91
84
|
for (const caseDef of Object.values(n.cases)) {
|
|
92
85
|
normalizeArrayChildren(caseDef);
|
|
93
86
|
}
|
|
@@ -209,7 +202,7 @@ function collectRows(
|
|
|
209
202
|
skipSelf: boolean,
|
|
210
203
|
): void {
|
|
211
204
|
// Text node children: bare primitives get a "text" row
|
|
212
|
-
if (
|
|
205
|
+
if (isString(doc) || isNumber(doc) || isBoolean(doc)) {
|
|
213
206
|
if (!skipSelf) {
|
|
214
207
|
out.push({ depth, node: doc, nodeType: "text", path });
|
|
215
208
|
}
|
|
@@ -220,13 +213,13 @@ function collectRows(
|
|
|
220
213
|
// Recurse into its single template at `[...path, "map"]`. This is reached both when the array is
|
|
221
214
|
// A member of a children array (path `[…, "children", i]`) and the legacy whole-children form
|
|
222
215
|
// (path `[…, "children"]`).
|
|
223
|
-
if (
|
|
216
|
+
if (doc.$prototype === "Array") {
|
|
224
217
|
if (!skipSelf) {
|
|
225
218
|
out.push({ depth, node: doc, nodeType: "map", path });
|
|
226
219
|
}
|
|
227
|
-
const mapDef =
|
|
228
|
-
if (mapDef
|
|
229
|
-
collectRows(mapDef
|
|
220
|
+
const mapDef = doc.map;
|
|
221
|
+
if (isNonNullObject(mapDef)) {
|
|
222
|
+
collectRows(mapDef, [...path, "map"], depth + 1, out, false);
|
|
230
223
|
}
|
|
231
224
|
return;
|
|
232
225
|
}
|
|
@@ -247,36 +240,33 @@ function collectRows(
|
|
|
247
240
|
const childPath = [...path, "children", i];
|
|
248
241
|
collectRows(children[i]!, childPath, depth + 1, out, false);
|
|
249
242
|
}
|
|
250
|
-
} else if (
|
|
251
|
-
children &&
|
|
252
|
-
typeof children === "object" &&
|
|
253
|
-
(children as JxMutableNode).$prototype === "Array"
|
|
254
|
-
) {
|
|
243
|
+
} else if (isMappedArray(children)) {
|
|
255
244
|
// Legacy whole-children repeater: the array occupies the children slot itself.
|
|
245
|
+
// SAFETY: The repeater in the children slot is the same repeater node a children member is.
|
|
256
246
|
collectRows(children as JxMutableNode, [...path, "children"], depth + 1, out, false);
|
|
257
247
|
}
|
|
258
248
|
|
|
259
249
|
// $switch — emit each case as a virtual child
|
|
260
|
-
if (doc.$switch && doc.cases
|
|
250
|
+
if (doc.$switch && isNonNullObject(doc.cases)) {
|
|
261
251
|
for (const [caseName, caseDef] of Object.entries(doc.cases)) {
|
|
262
252
|
const casePath = [...path, "cases", caseName];
|
|
263
|
-
if (caseDef &&
|
|
253
|
+
if (isNonNullObject(caseDef) && caseDef.$ref) {
|
|
264
254
|
out.push({
|
|
265
255
|
depth: depth + 1,
|
|
266
|
-
node: caseDef
|
|
256
|
+
node: caseDef,
|
|
267
257
|
nodeType: "case-ref",
|
|
268
258
|
path: casePath,
|
|
269
259
|
});
|
|
270
|
-
} else if (caseDef
|
|
260
|
+
} else if (isNonNullObject(caseDef)) {
|
|
271
261
|
out.push({
|
|
272
262
|
depth: depth + 1,
|
|
273
|
-
node: caseDef
|
|
263
|
+
node: caseDef,
|
|
274
264
|
nodeType: "case",
|
|
275
265
|
path: casePath,
|
|
276
266
|
});
|
|
277
267
|
// Recurse into case children — skipSelf, because the "case" row above already stands in for
|
|
278
268
|
// The case node itself (with its own nodeType).
|
|
279
|
-
collectRows(caseDef
|
|
269
|
+
collectRows(caseDef, casePath, depth + 2, out, true);
|
|
280
270
|
}
|
|
281
271
|
}
|
|
282
272
|
}
|
|
@@ -285,10 +275,10 @@ function collectRows(
|
|
|
285
275
|
/**
|
|
286
276
|
* Get a display label for a node (for layers + overlays).
|
|
287
277
|
*
|
|
288
|
-
* @param {JxMutableNode | null} node
|
|
278
|
+
* @param {JxMutableNode | null | undefined} node
|
|
289
279
|
* @returns {string}
|
|
290
280
|
*/
|
|
291
|
-
export function nodeLabel(node: JxMutableNode | null) {
|
|
281
|
+
export function nodeLabel(node: JxMutableNode | null | undefined) {
|
|
292
282
|
if (!node) {
|
|
293
283
|
return "?";
|
|
294
284
|
}
|
|
@@ -306,14 +296,14 @@ export function nodeLabel(node: JxMutableNode | null) {
|
|
|
306
296
|
}
|
|
307
297
|
if (node.tagName === "slot") {
|
|
308
298
|
const name = node.attributes?.name;
|
|
309
|
-
return
|
|
299
|
+
return isString(name) && name.trim() ? `slot: ${name.trim()}` : "slot";
|
|
310
300
|
}
|
|
311
301
|
/* `displayTagName`, because a tag may be CHOSEN rather than written: this label reached the
|
|
312
302
|
Outline row, the Inspector's header and the jump bar, and a raw read rendered `[object Object]`
|
|
313
303
|
in all three. `a|div` is the honest answer — one element, tag decided at creation. */
|
|
314
304
|
const tag = displayTagName(node.tagName) || "div";
|
|
315
305
|
const suffix = node.$switch ? " ⇆" : "";
|
|
316
|
-
if (
|
|
306
|
+
if (isString(node.textContent) && node.textContent.length > 0) {
|
|
317
307
|
return `${tag} — ${node.textContent.slice(0, 24)}${suffix}`;
|
|
318
308
|
}
|
|
319
309
|
return tag + suffix;
|
|
@@ -340,5 +330,7 @@ export function setProjectState(ps: ProjectState | null) {
|
|
|
340
330
|
* @returns {ProjectState}
|
|
341
331
|
*/
|
|
342
332
|
export function requireProjectState() {
|
|
333
|
+
/* SAFETY: The contract above restricts callers to paths reached after `setProjectState` installed
|
|
334
|
+
a project (a project command, a panel that only mounts with one open); nothing here checks it. */
|
|
343
335
|
return projectState as ProjectState;
|
|
344
336
|
}
|
package/src/store.ts
CHANGED
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
// ─── Re-exports from state.js ────────────────────────────────────────────────
|
|
11
11
|
|
|
12
|
+
import { isFunction, isNonNullObject } from "@jxsuite/schema/guards";
|
|
12
13
|
import { INPUT_DEBOUNCE } from "./ui/timing";
|
|
13
14
|
import type { JxPath } from "./state";
|
|
14
|
-
import type { Tab } from "./tabs/tab";
|
|
15
|
+
import type { Tab, TabUi } from "./tabs/tab";
|
|
15
16
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
16
17
|
|
|
17
18
|
export {
|
|
@@ -36,18 +37,38 @@ export {
|
|
|
36
37
|
each of which meant "the pane I am acting on" and got "the pane that happens to be focused". A
|
|
37
38
|
stage belongs to a pane (`canvas/canvas-surface.ts`), a pane's cell is built by
|
|
38
39
|
`panels/pane-grid.ts`, and every one of those readers now takes its surface. */
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export let
|
|
43
|
-
export let
|
|
40
|
+
|
|
41
|
+
/* Null until `initShellRefs()`, which `studio.ts` calls at boot right after mounting the shell
|
|
42
|
+
document; a render asked for before that (a test, or a command run ahead of the shell) reads null. */
|
|
43
|
+
export let activityBar: HTMLElement | null = null;
|
|
44
|
+
export let leftPanel: HTMLElement | null = null;
|
|
45
|
+
export let rightPanel: HTMLElement | null = null;
|
|
46
|
+
export let toolbarEl: HTMLElement | null = null;
|
|
47
|
+
export let statusbarEl: HTMLElement | null = null;
|
|
48
|
+
|
|
49
|
+
/** The shell region whose `id` is given, or null when the mounted shell has none. */
|
|
50
|
+
function shellRef(id: string): HTMLElement | null {
|
|
51
|
+
const element = document.querySelector(`#${id}`);
|
|
52
|
+
return element instanceof HTMLElement ? element : null;
|
|
53
|
+
}
|
|
44
54
|
|
|
45
55
|
export function initShellRefs() {
|
|
46
|
-
activityBar =
|
|
47
|
-
leftPanel =
|
|
48
|
-
rightPanel =
|
|
49
|
-
toolbarEl =
|
|
50
|
-
statusbarEl =
|
|
56
|
+
activityBar = shellRef("activity-bar");
|
|
57
|
+
leftPanel = shellRef("left-panel");
|
|
58
|
+
rightPanel = shellRef("right-panel");
|
|
59
|
+
toolbarEl = shellRef("toolbar");
|
|
60
|
+
statusbarEl = shellRef("statusbar");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* A shell region for a caller that cannot work without it. Reading one before `initShellRefs()` has
|
|
65
|
+
* found it is a boot-order bug, so it throws a TypeError that names the region.
|
|
66
|
+
*/
|
|
67
|
+
export function requireShellRef(ref: HTMLElement | null, id: string): HTMLElement {
|
|
68
|
+
if (!ref) {
|
|
69
|
+
throw new TypeError(`#${id} is not in the shell yet; initShellRefs() has not found it`);
|
|
70
|
+
}
|
|
71
|
+
return ref;
|
|
51
72
|
}
|
|
52
73
|
|
|
53
74
|
// ─── Shared constants ────────────────────────────────────────────────────────
|
|
@@ -130,6 +151,11 @@ export { stripEventHandlers } from "./utils/strip-events";
|
|
|
130
151
|
|
|
131
152
|
const _renderers = new Map<string, () => void>();
|
|
132
153
|
|
|
154
|
+
/** Whether a renderer's return value is a thenable — an `async` renderer that is still painting. */
|
|
155
|
+
function isThenable(value: unknown): value is PromiseLike<unknown> {
|
|
156
|
+
return (isNonNullObject(value) || isFunction(value)) && "then" in value && isFunction(value.then);
|
|
157
|
+
}
|
|
158
|
+
|
|
133
159
|
/**
|
|
134
160
|
* How many registered renderers are mid-paint right now.
|
|
135
161
|
*
|
|
@@ -154,9 +180,9 @@ function runRenderer(name: string, fn: () => void) {
|
|
|
154
180
|
};
|
|
155
181
|
let pending: PromiseLike<unknown> | null = null;
|
|
156
182
|
try {
|
|
157
|
-
const result = fn()
|
|
158
|
-
if (
|
|
159
|
-
pending = result
|
|
183
|
+
const result = fn();
|
|
184
|
+
if (isThenable(result)) {
|
|
185
|
+
pending = result;
|
|
160
186
|
}
|
|
161
187
|
} catch (error) {
|
|
162
188
|
console.error(`Renderer "${name}" failed:`, error);
|
|
@@ -165,7 +191,7 @@ function runRenderer(name: string, fn: () => void) {
|
|
|
165
191
|
done();
|
|
166
192
|
return;
|
|
167
193
|
}
|
|
168
|
-
pending.then(done, (error
|
|
194
|
+
pending.then(done, (error) => {
|
|
169
195
|
console.error(`Renderer "${name}" failed:`, error);
|
|
170
196
|
done();
|
|
171
197
|
});
|
|
@@ -232,8 +258,8 @@ export function updateSession(
|
|
|
232
258
|
selection?: JxPath[];
|
|
233
259
|
hover?: JxPath | null;
|
|
234
260
|
clipboard?: JxMutableNode | null;
|
|
235
|
-
ui?:
|
|
236
|
-
canvas?:
|
|
261
|
+
ui?: Partial<TabUi>;
|
|
262
|
+
canvas?: Partial<Tab["session"]["canvas"]>;
|
|
237
263
|
},
|
|
238
264
|
) {
|
|
239
265
|
if (tab) {
|
|
@@ -241,20 +267,16 @@ export function updateSession(
|
|
|
241
267
|
tab.session.selection = patch.selection;
|
|
242
268
|
}
|
|
243
269
|
if (patch.hover !== undefined) {
|
|
244
|
-
tab.session.hover = patch.hover
|
|
270
|
+
tab.session.hover = patch.hover;
|
|
245
271
|
}
|
|
246
272
|
if (patch.clipboard !== undefined) {
|
|
247
|
-
tab.session.clipboard = patch.clipboard
|
|
273
|
+
tab.session.clipboard = patch.clipboard;
|
|
248
274
|
}
|
|
249
275
|
if (patch.ui) {
|
|
250
|
-
|
|
251
|
-
(tab.session.ui as unknown as Record<string, unknown>)[k] = v;
|
|
252
|
-
}
|
|
276
|
+
Object.assign(tab.session.ui, patch.ui);
|
|
253
277
|
}
|
|
254
278
|
if (patch.canvas) {
|
|
255
|
-
|
|
256
|
-
(tab.session.canvas as unknown as Record<string, unknown>)[k] = v;
|
|
257
|
-
}
|
|
279
|
+
Object.assign(tab.session.canvas, patch.canvas);
|
|
258
280
|
}
|
|
259
281
|
}
|
|
260
282
|
}
|
|
@@ -263,12 +285,12 @@ export function updateSession(
|
|
|
263
285
|
* Update a single UI field on `tab`.
|
|
264
286
|
*
|
|
265
287
|
* @param {Tab | null} tab — the tab this field belongs to. `null` is a no-op.
|
|
266
|
-
* @param {
|
|
267
|
-
* @param {
|
|
288
|
+
* @param {K} field
|
|
289
|
+
* @param {TabUi[K]} value
|
|
268
290
|
*/
|
|
269
|
-
export function updateUi(tab: Tab | null, field:
|
|
291
|
+
export function updateUi<K extends keyof TabUi>(tab: Tab | null, field: K, value: TabUi[K]) {
|
|
270
292
|
if (tab) {
|
|
271
|
-
|
|
293
|
+
tab.session.ui[field] = value;
|
|
272
294
|
}
|
|
273
295
|
}
|
|
274
296
|
|
|
@@ -276,12 +298,10 @@ export function updateUi(tab: Tab | null, field: string, value: unknown) {
|
|
|
276
298
|
* Update `tab`'s canvas async state (status, scope, error).
|
|
277
299
|
*
|
|
278
300
|
* @param {Tab | null} tab — the tab whose stage produced this state. `null` is a no-op.
|
|
279
|
-
* @param {
|
|
301
|
+
* @param {Partial<Tab["session"]["canvas"]>} patch
|
|
280
302
|
*/
|
|
281
|
-
export function updateCanvas(tab: Tab | null, patch:
|
|
303
|
+
export function updateCanvas(tab: Tab | null, patch: Partial<Tab["session"]["canvas"]>) {
|
|
282
304
|
if (tab) {
|
|
283
|
-
|
|
284
|
-
(tab.session.canvas as Record<string, unknown>)[k] = v;
|
|
285
|
-
}
|
|
305
|
+
Object.assign(tab.session.canvas, patch);
|
|
286
306
|
}
|
|
287
307
|
}
|
package/src/studio.ts
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
registerRenderer,
|
|
22
22
|
render,
|
|
23
23
|
requireProjectState,
|
|
24
|
+
requireShellRef,
|
|
24
25
|
setProjectState,
|
|
25
26
|
toolbarEl,
|
|
26
27
|
updateSession,
|
|
@@ -117,13 +118,12 @@ import {
|
|
|
117
118
|
import {
|
|
118
119
|
loadProject as _loadProject,
|
|
119
120
|
openProject as _openProject,
|
|
120
|
-
renderFilesTemplate,
|
|
121
121
|
findHomePage,
|
|
122
122
|
loadDirectory,
|
|
123
|
+
loadProjectDirectories,
|
|
123
124
|
openFileInPane,
|
|
124
125
|
openFileInTab,
|
|
125
126
|
openLastSessionOrHome,
|
|
126
|
-
registerFileTreeDnD,
|
|
127
127
|
reloadCleanTab,
|
|
128
128
|
reloadTabsIfChanged,
|
|
129
129
|
} from "./files/files";
|
|
@@ -136,9 +136,7 @@ import {
|
|
|
136
136
|
configureCollabParser,
|
|
137
137
|
configureCollabSerializer,
|
|
138
138
|
} from "./collab/collab-session";
|
|
139
|
-
import {
|
|
140
|
-
import { invalidateLayoutPickerCache, renderHeadTemplate } from "./panels/head-panel";
|
|
141
|
-
import { exportCemManifest as _exportCemManifest } from "./services/cem-export";
|
|
139
|
+
import { invalidateLayoutPickerCache } from "./panels/head-panel";
|
|
142
140
|
import { installAutomationHook } from "./services/automation";
|
|
143
141
|
import { invalidateLibrary } from "./browse/library-pane";
|
|
144
142
|
import { invalidateMediaCache } from "./ui/media-picker";
|
|
@@ -175,7 +173,6 @@ import {
|
|
|
175
173
|
cloneRepository,
|
|
176
174
|
loadDiffForLens,
|
|
177
175
|
registerSourceControlCommands,
|
|
178
|
-
renderGitPanel,
|
|
179
176
|
noteFileSaved,
|
|
180
177
|
} from "./panels/git-panel";
|
|
181
178
|
|
|
@@ -191,7 +188,7 @@ import { chordsInScopes } from "./commands/keymap";
|
|
|
191
188
|
import { FRAME_KEY_SCOPES } from "./canvas/iframe-keys";
|
|
192
189
|
import { createLiveContext } from "./commands/live-context";
|
|
193
190
|
import { hasAiCredentials } from "./services/ai-models";
|
|
194
|
-
import { mount
|
|
191
|
+
import { mount } from "./surfaces/rail";
|
|
195
192
|
import * as toolbarPanel from "./surfaces/commandbar";
|
|
196
193
|
import * as overlaysPanel from "./panels/overlays";
|
|
197
194
|
import * as frontmatterPanelMod from "./panels/frontmatter-panel";
|
|
@@ -200,7 +197,8 @@ import * as chatPanelMod from "./panels/chat-panel";
|
|
|
200
197
|
import { setProjectAdopter } from "./services/project-adoption";
|
|
201
198
|
import { setImportHandoff } from "./services/import-seed";
|
|
202
199
|
import { watchConnection } from "./services/connection";
|
|
203
|
-
import { tabBufferUnsaved } from "./services/monaco-buffer";
|
|
200
|
+
import { commitTabBuffers, tabBufferUnsaved } from "./services/monaco-buffer";
|
|
201
|
+
import { clearTyping } from "./tabs/typing";
|
|
204
202
|
import * as leftPanelMod from "./panels/left-panel";
|
|
205
203
|
import * as tabStrip from "./panels/tab-strip";
|
|
206
204
|
import * as paneContext from "./panels/pane-context";
|
|
@@ -267,7 +265,7 @@ import { registerI18nCommands } from "./i18n/i18n-commands";
|
|
|
267
265
|
import { convertToComponent } from "./editor/convert-to-component";
|
|
268
266
|
import type { GitDiffState } from "./types";
|
|
269
267
|
import type { Tab } from "./tabs/tab";
|
|
270
|
-
import type { JxDocument,
|
|
268
|
+
import type { JxDocument, ProjectConfig } from "@jxsuite/schema/types";
|
|
271
269
|
import { setBundleBase } from "./services/bundle-base";
|
|
272
270
|
import { mountBootFailureTree, mountShellTree } from "./shell/tree";
|
|
273
271
|
|
|
@@ -498,7 +496,7 @@ initShellRefs();
|
|
|
498
496
|
mountShell();
|
|
499
497
|
|
|
500
498
|
// Mount extracted panel modules
|
|
501
|
-
toolbarPanel.mount(toolbarEl, {
|
|
499
|
+
toolbarPanel.mount(requireShellRef(toolbarEl, "toolbar"), {
|
|
502
500
|
closeFunctionEditor: () => closeFunctionEditor(),
|
|
503
501
|
getCanvasMode,
|
|
504
502
|
openProject: () => openProject(),
|
|
@@ -640,9 +638,8 @@ window.addEventListener("beforeunload", (e: BeforeUnloadEvent) => {
|
|
|
640
638
|
// Author may cancel the close, and the record is the same either way.
|
|
641
639
|
flushSession();
|
|
642
640
|
if (hasUnsavedTabs()) {
|
|
641
|
+
// The HTML standard's trigger for the leave-page prompt; the legacy `returnValue` is deprecated.
|
|
643
642
|
e.preventDefault();
|
|
644
|
-
// Legacy browsers require a truthy returnValue to trigger the native confirm prompt.
|
|
645
|
-
e.returnValue = "";
|
|
646
643
|
}
|
|
647
644
|
});
|
|
648
645
|
|
|
@@ -742,11 +739,8 @@ function installPaneRenderEffects(paneId: string): void {
|
|
|
742
739
|
installDerivationEffects(paneId, derivationDeps);
|
|
743
740
|
effect(() => {
|
|
744
741
|
const tab = tabOfPane(paneId);
|
|
745
|
-
if (tab) {
|
|
746
|
-
|
|
747
|
-
if (doc && consumePatchedDocument(doc, paneId)) {
|
|
748
|
-
return;
|
|
749
|
-
}
|
|
742
|
+
if (tab && consumePatchedDocument(tab.doc.document, paneId)) {
|
|
743
|
+
return;
|
|
750
744
|
}
|
|
751
745
|
scheduleCanvasRender(paneId);
|
|
752
746
|
});
|
|
@@ -870,7 +864,6 @@ leftPanelMod.mount({
|
|
|
870
864
|
navigateToComponent,
|
|
871
865
|
registerComponentsDnD,
|
|
872
866
|
registerElementsDnD,
|
|
873
|
-
registerFileTreeDnD,
|
|
874
867
|
registerLayersDnD,
|
|
875
868
|
renderCanvas: () => renderCanvas(),
|
|
876
869
|
// The Data panel's Refresh: a canvas re-render that ALSO lets automatic `Request` state entries
|
|
@@ -893,10 +886,6 @@ leftPanelMod.mount({
|
|
|
893
886
|
}
|
|
894
887
|
renderCanvas(paneId);
|
|
895
888
|
},
|
|
896
|
-
renderFilesTemplate,
|
|
897
|
-
renderGitPanel,
|
|
898
|
-
renderHeadTemplate,
|
|
899
|
-
renderImportsTemplate,
|
|
900
889
|
mountSignalsPanel,
|
|
901
890
|
setCanvasMode,
|
|
902
891
|
setGitDiffState: (state: GitDiffState | null) => {
|
|
@@ -918,7 +907,7 @@ renderStatusbar();
|
|
|
918
907
|
// The status bar mounts the jump bar too: the focused pane's breadcrumb trail is its DOCUMENT
|
|
919
908
|
// Field, and the only breadcrumb in the shell.
|
|
920
909
|
mountStatusbar();
|
|
921
|
-
|
|
910
|
+
mount();
|
|
922
911
|
|
|
923
912
|
/* The background-click deselect moved into `editor/shortcuts.ts`'s `installStageGestures`, beside
|
|
924
913
|
the wheel and the middle-drag, because it is a STAGE gesture: it compared against the app's one
|
|
@@ -982,10 +971,10 @@ if (!_projectParam) {
|
|
|
982
971
|
const _bootPlatform = getPlatform();
|
|
983
972
|
// oxlint-disable-next-line unicorn/prefer-top-level-await -- fire-and-forget: must not block the initial render
|
|
984
973
|
void _bootPlatform
|
|
985
|
-
.activate
|
|
974
|
+
.activate()
|
|
986
975
|
// No project is bound yet, so this call only warms the canvasUrl; a backend that refuses it
|
|
987
976
|
// Still gets the render below rather than an unhandled rejection.
|
|
988
|
-
|
|
977
|
+
.catch((error) => {
|
|
989
978
|
// A refusal that offers an action is the action flow's to explain; it is not a fault.
|
|
990
979
|
if (!isActionRequired(error)) {
|
|
991
980
|
console.error("Boot activation failed:", error);
|
|
@@ -1017,18 +1006,14 @@ if (_projectParam) {
|
|
|
1017
1006
|
// Report a bare `Error: <message>` because the only identifying fact was still block-scoped.
|
|
1018
1007
|
let fileRelPath = _urlParams.get("file") || _projectParam;
|
|
1019
1008
|
try {
|
|
1020
|
-
const siteCtx = platform.resolveSiteContext
|
|
1021
|
-
? await platform.resolveSiteContext(_projectParam)
|
|
1022
|
-
: { sitePath: null };
|
|
1009
|
+
const siteCtx = await platform.resolveSiteContext(_projectParam);
|
|
1023
1010
|
|
|
1024
1011
|
if (siteCtx.sitePath) {
|
|
1025
1012
|
// Set PAL project root to absolute path so file ops work
|
|
1026
1013
|
if (siteCtx.sitePath) {
|
|
1027
1014
|
platform.projectRoot = siteCtx.sitePath;
|
|
1028
1015
|
// Await activation so the server resolves project-relative static files
|
|
1029
|
-
|
|
1030
|
-
await platform.activate();
|
|
1031
|
-
}
|
|
1016
|
+
await platform.activate();
|
|
1032
1017
|
}
|
|
1033
1018
|
|
|
1034
1019
|
resetIgnoreCache();
|
|
@@ -1052,31 +1037,9 @@ if (_projectParam) {
|
|
|
1052
1037
|
await ensureDependenciesInstalled();
|
|
1053
1038
|
await loadComponentRegistry();
|
|
1054
1039
|
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
"layouts",
|
|
1059
|
-
"components",
|
|
1060
|
-
"content",
|
|
1061
|
-
"data",
|
|
1062
|
-
"public",
|
|
1063
|
-
"styles",
|
|
1064
|
-
]);
|
|
1065
|
-
/* Through `loadDirectory`, not `platform.listDirectory`: this is the second copy of the
|
|
1066
|
-
conventional-dir walk (the first is `openProject` in files/files.ts), and the loader is
|
|
1067
|
-
what reads the `.gitignore` chain governing each directory. Listing around it left the
|
|
1068
|
-
`?project=` boot as the one door into a project whose tree knew no ignore rules. */
|
|
1069
|
-
await loadDirectory(".");
|
|
1070
|
-
const dirEntries = requireProjectState().dirs.get(".") ?? [];
|
|
1071
|
-
const foundDirs = [];
|
|
1072
|
-
for (const e of dirEntries) {
|
|
1073
|
-
if (e.type === "directory" && conventionalDirs.has(e.name)) {
|
|
1074
|
-
foundDirs.push(e.name);
|
|
1075
|
-
requireProjectState().expanded.add(e.path || e.name);
|
|
1076
|
-
await loadDirectory(e.path || e.name);
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
requireProjectState().projectDirs = foundDirs;
|
|
1040
|
+
/* Through `loadDirectory` (inside `loadProjectDirectories`), not `platform.listDirectory`:
|
|
1041
|
+
the loader is what reads the `.gitignore` chain governing each directory. */
|
|
1042
|
+
await loadProjectDirectories();
|
|
1080
1043
|
void maybePromptJxsuiteUpdate(siteCtx.sitePath);
|
|
1081
1044
|
}
|
|
1082
1045
|
|
|
@@ -1143,7 +1106,7 @@ if (_projectParam) {
|
|
|
1143
1106
|
openTab({
|
|
1144
1107
|
id: fileRelPath,
|
|
1145
1108
|
documentPath: fileRelPath,
|
|
1146
|
-
document: parsedDoc
|
|
1109
|
+
document: parsedDoc,
|
|
1147
1110
|
...(frontmatter != null && { frontmatter }),
|
|
1148
1111
|
layout,
|
|
1149
1112
|
sourceFormat: fileFormat?.name ?? null,
|
|
@@ -1364,6 +1327,9 @@ async function openRecentProject(root: string) {
|
|
|
1364
1327
|
void loadFormats();
|
|
1365
1328
|
refreshExtensionUi(platform);
|
|
1366
1329
|
const content = await platform.readFile("project.json");
|
|
1330
|
+
/* SAFETY: This is `project.json` at the root the user chose to open, the project's own config
|
|
1331
|
+
file whose schema is ProjectConfig; Studio edits it in that shape and does not re-validate it
|
|
1332
|
+
on open, as the folder-picker path in `platforms/devserver.ts` does not either. */
|
|
1367
1333
|
const config = JSON.parse(content) as ProjectConfig;
|
|
1368
1334
|
|
|
1369
1335
|
closeAllTabs();
|
|
@@ -1388,26 +1354,9 @@ async function openRecentProject(root: string) {
|
|
|
1388
1354
|
activity.step("Install dependencies");
|
|
1389
1355
|
await ensureDependenciesInstalled();
|
|
1390
1356
|
activity.step("Read the project");
|
|
1391
|
-
await
|
|
1357
|
+
await loadProjectDirectories();
|
|
1392
1358
|
await loadComponentRegistry();
|
|
1393
1359
|
|
|
1394
|
-
const conventionalDirs = new Set([
|
|
1395
|
-
"pages",
|
|
1396
|
-
"layouts",
|
|
1397
|
-
"components",
|
|
1398
|
-
"content",
|
|
1399
|
-
"data",
|
|
1400
|
-
"public",
|
|
1401
|
-
"styles",
|
|
1402
|
-
]);
|
|
1403
|
-
const entries = requireProjectState().dirs.get(".") || [];
|
|
1404
|
-
for (const e of entries) {
|
|
1405
|
-
if (e.type === "directory" && conventionalDirs.has(e.name)) {
|
|
1406
|
-
requireProjectState().expanded.add(e.path || e.name);
|
|
1407
|
-
await loadDirectory(e.path || e.name);
|
|
1408
|
-
}
|
|
1409
|
-
}
|
|
1410
|
-
|
|
1411
1360
|
addRecentProject(requireProjectState().name, root);
|
|
1412
1361
|
setActivityTab("files");
|
|
1413
1362
|
renderLeftPanel();
|
|
@@ -1492,7 +1441,18 @@ registerStudioCommands(
|
|
|
1492
1441
|
// Whether the bytes landed, and a hook that neither supplies one nor reads the answer must not
|
|
1493
1442
|
// Silently forward its own first argument as the tab to save.
|
|
1494
1443
|
saveDocument: async () => {
|
|
1495
|
-
|
|
1444
|
+
const tab = activeTab.value;
|
|
1445
|
+
if (!tab) {
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
// What a source buffer holds goes into the document first, or ⌘S inside the commit's
|
|
1449
|
+
// Debounce would save the text from before the last keystrokes.
|
|
1450
|
+
await commitTabBuffers(tab);
|
|
1451
|
+
await saveFile(tab);
|
|
1452
|
+
// Text that would not parse is still only in the buffer, so it is still unsaved.
|
|
1453
|
+
if (!tabBufferUnsaved(tab)) {
|
|
1454
|
+
clearTyping(tab.id);
|
|
1455
|
+
}
|
|
1496
1456
|
},
|
|
1497
1457
|
},
|
|
1498
1458
|
stageContext,
|
|
@@ -1549,7 +1509,9 @@ const liveChrome = createLiveSurfaceSaver({
|
|
|
1549
1509
|
registry reactively. */
|
|
1550
1510
|
setDocumentSavedListener((path, doc) => {
|
|
1551
1511
|
void noteFileSaved(path);
|
|
1552
|
-
|
|
1512
|
+
/* SAFETY: The listener fires for a tab's saved ROOT document, and a root document is a
|
|
1513
|
+
JxDocument held in the editor's mutable node form; `liveChrome` only acts on surface paths. */
|
|
1514
|
+
void liveChrome(path, doc as JxDocument);
|
|
1553
1515
|
if (noteComponentSaved(path, doc)) {
|
|
1554
1516
|
renderPropertiesPanel();
|
|
1555
1517
|
renderLeftPanel();
|
|
@@ -32,5 +32,5 @@ import { activeTab } from "../workspace/workspace";
|
|
|
32
32
|
export function pushProjectStylesToCanvas(): void {
|
|
33
33
|
postSiteStyleToLiveHosts();
|
|
34
34
|
const style = transposeStylebookStyle(getEffectiveStyle(activeTab.value?.doc.document?.style));
|
|
35
|
-
postStyleUpdateToStylebookHosts(style
|
|
35
|
+
postStyleUpdateToStylebookHosts(style);
|
|
36
36
|
}
|