@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/shell.ts
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* the branch. See specs/studio.md and the level × placement matrix.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
+
import { isBoolean, isJsonObject, isNumber, isString } from "@jxsuite/schema/guards";
|
|
24
25
|
import { effect, effectScope, reactive } from "./reactivity";
|
|
25
26
|
import { SETTINGS } from "./services/settings/definitions";
|
|
26
27
|
import { readStoredSetting, setSetting } from "./services/settings/kernel";
|
|
@@ -39,18 +40,11 @@ import {
|
|
|
39
40
|
stringProperty,
|
|
40
41
|
} from "./commands/command-args";
|
|
41
42
|
import type { EffectScope } from "@vue/reactivity";
|
|
43
|
+
import type { JsonObject, JsonValue } from "@jxsuite/schema/types";
|
|
42
44
|
import type { LayoutHit } from "./canvas/iframe-protocol";
|
|
43
|
-
import type { GitBranchesResult, GitDiffState, GitStatusResult } from "./types";
|
|
45
|
+
import type { GitBranchesResult, GitDiffState, GitLogEntry, GitStatusResult } from "./types";
|
|
44
46
|
import type { AnyCommand, CommandRegistry } from "./commands/registry";
|
|
45
47
|
|
|
46
|
-
/**
|
|
47
|
-
* The canvas selection when the author clicked LAYOUT chrome rather than page content — a header, a
|
|
48
|
-
* footer, anything contributed by the layout file. It is deliberately NOT a document selection: the
|
|
49
|
-
* node is not in the open page at all, so the properties panel shows the read-only layout panel
|
|
50
|
-
* (with "Open Layout →") instead of the element inspector. See {@link setLayoutSelection}.
|
|
51
|
-
*/
|
|
52
|
-
export type LayoutSelection = LayoutHit;
|
|
53
|
-
|
|
54
48
|
/**
|
|
55
49
|
* The three resizable docks around the pane grid: two flanking it, one under it.
|
|
56
50
|
*
|
|
@@ -115,23 +109,23 @@ export type NavigatorPanelId = (typeof NAVIGATOR_PANEL_IDS)[number];
|
|
|
115
109
|
* value is the one place those old strings can still arrive from, so they are translated once, on
|
|
116
110
|
* read, and then never again — there is no alias in the registry and no branch in the rail.
|
|
117
111
|
*/
|
|
118
|
-
const RENAMED_PANEL_IDS
|
|
119
|
-
blocks
|
|
120
|
-
head
|
|
121
|
-
imports
|
|
112
|
+
const RENAMED_PANEL_IDS = new Map<string, NavigatorPanelId>([
|
|
113
|
+
["blocks", "insert"],
|
|
114
|
+
["head", "page"],
|
|
115
|
+
["imports", "packages"],
|
|
122
116
|
/* Not a rename — a MERGE. The State editor is part of the Data panel now (§5.6), so a
|
|
123
117
|
stored `leftTab: "state"` names a real place and lands on it, rather than returning `null` and
|
|
124
118
|
booting into the default the way `problems` does. Defining a value and watching it resolve are
|
|
125
119
|
one task; they were two panels. */
|
|
126
|
-
state
|
|
127
|
-
|
|
120
|
+
["state", "data"],
|
|
121
|
+
]);
|
|
128
122
|
|
|
129
123
|
/** The panel the Navigator wakes up on when nothing usable is stored. */
|
|
130
124
|
export const DEFAULT_PANEL_ID: NavigatorPanelId = "layers";
|
|
131
125
|
|
|
132
126
|
/** Whether a string is a declared panel id. */
|
|
133
127
|
export function isNavigatorPanelId(value: unknown): value is NavigatorPanelId {
|
|
134
|
-
return typeof value === "string" && (
|
|
128
|
+
return typeof value === "string" && NAVIGATOR_PANEL_IDS.some((id) => id === value);
|
|
135
129
|
}
|
|
136
130
|
|
|
137
131
|
/**
|
|
@@ -147,10 +141,12 @@ export function isNavigatorPanelId(value: unknown): value is NavigatorPanelId {
|
|
|
147
141
|
* drift was a control that silently did nothing.
|
|
148
142
|
*/
|
|
149
143
|
export function requireNavigatorPanelId(value: string, source: string): NavigatorPanelId {
|
|
150
|
-
|
|
144
|
+
// `find` hands back the DECLARED id, typed as one, which is the same string the caller sent.
|
|
145
|
+
const id = NAVIGATOR_PANEL_IDS.find((candidate) => candidate === value);
|
|
146
|
+
if (id === undefined) {
|
|
151
147
|
throw new Error(`${source}: "${value}" is not a declared Navigator panel id.`);
|
|
152
148
|
}
|
|
153
|
-
return
|
|
149
|
+
return id;
|
|
154
150
|
}
|
|
155
151
|
|
|
156
152
|
/**
|
|
@@ -166,15 +162,15 @@ export function requireNavigatorPanelId(value: string, source: string): Navigato
|
|
|
166
162
|
* Bottom dock keeps its own `bottomTab`, which already defaults to Problems. This is exactly the
|
|
167
163
|
* wedge this function exists to prevent.
|
|
168
164
|
*/
|
|
169
|
-
export function migratePanelId(stored:
|
|
170
|
-
if (
|
|
165
|
+
export function migratePanelId(stored: JsonValue | undefined): NavigatorPanelId | null {
|
|
166
|
+
if (!isString(stored)) {
|
|
171
167
|
return null;
|
|
172
168
|
}
|
|
173
|
-
const renamed = RENAMED_PANEL_IDS
|
|
169
|
+
const renamed = RENAMED_PANEL_IDS.get(stored);
|
|
174
170
|
if (renamed) {
|
|
175
171
|
return renamed;
|
|
176
172
|
}
|
|
177
|
-
return
|
|
173
|
+
return NAVIGATOR_PANEL_IDS.find((id) => id === stored) ?? null;
|
|
178
174
|
}
|
|
179
175
|
|
|
180
176
|
/**
|
|
@@ -199,7 +195,7 @@ export const DEFAULT_INSPECTOR_TAB: InspectorTabId = "properties";
|
|
|
199
195
|
|
|
200
196
|
/** Whether a string is a declared Inspector tab id. */
|
|
201
197
|
export function isInspectorTabId(value: unknown): value is InspectorTabId {
|
|
202
|
-
return typeof value === "string" && (
|
|
198
|
+
return typeof value === "string" && INSPECTOR_TAB_IDS.some((id) => id === value);
|
|
203
199
|
}
|
|
204
200
|
|
|
205
201
|
/**
|
|
@@ -225,7 +221,7 @@ export const DEFAULT_BOTTOM_TAB: BottomTabId = "problems";
|
|
|
225
221
|
|
|
226
222
|
/** Whether a string is a declared Bottom dock tab id. */
|
|
227
223
|
export function isBottomTabId(value: unknown): value is BottomTabId {
|
|
228
|
-
return typeof value === "string" && (
|
|
224
|
+
return typeof value === "string" && BOTTOM_TAB_IDS.some((id) => id === value);
|
|
229
225
|
}
|
|
230
226
|
|
|
231
227
|
/** The Studio chrome's themes — the `data-theme` stamp on `<html>` (studio-ui-guidelines.md §1.1). */
|
|
@@ -249,13 +245,9 @@ export interface DockState {
|
|
|
249
245
|
size: number;
|
|
250
246
|
}
|
|
251
247
|
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
message: string;
|
|
256
|
-
author: string;
|
|
257
|
-
date: string;
|
|
258
|
-
}
|
|
248
|
+
/* One row of `git log`, as the Source Control panel's History tab renders it: the platform's own
|
|
249
|
+
`gitLog` row, re-exported so the panels reading shell state keep one import. */
|
|
250
|
+
export type { GitLogEntry } from "./types";
|
|
259
251
|
|
|
260
252
|
/** Source control — project level, one copy, independent of which document is focused. */
|
|
261
253
|
export interface ShellGit {
|
|
@@ -354,14 +346,20 @@ export interface ShellState {
|
|
|
354
346
|
layout: string;
|
|
355
347
|
/** Every layout this project has, built-ins included. Persisted per project root. */
|
|
356
348
|
layouts: LayoutPreset[];
|
|
357
|
-
|
|
349
|
+
/**
|
|
350
|
+
* Layout chrome the author clicked, or `null`: a header, a footer, anything contributed by the
|
|
351
|
+
* layout file. It is deliberately NOT a document selection: the node is not in the open page at
|
|
352
|
+
* all, so the properties panel shows the read-only layout panel (with "Open Layout →") instead of
|
|
353
|
+
* the element inspector. See {@link setLayoutSelection}.
|
|
354
|
+
*/
|
|
355
|
+
layoutSelection: LayoutHit | null;
|
|
358
356
|
/** Which section Project Settings opens on. */
|
|
359
357
|
settingsTab: string;
|
|
360
358
|
stylebook: ShellStylebook;
|
|
361
359
|
git: ShellGit;
|
|
362
360
|
}
|
|
363
361
|
|
|
364
|
-
const DOCK_STORAGE_KEY = "jx-studio-panel-widths";
|
|
362
|
+
export const DOCK_STORAGE_KEY = "jx-studio-panel-widths";
|
|
365
363
|
|
|
366
364
|
/**
|
|
367
365
|
* The per-project record's key prefix — one namespaced record per project root (§14.8).
|
|
@@ -387,8 +385,8 @@ const PROJECT_STORAGE_PREFIX = "jx-studio-project::";
|
|
|
387
385
|
const DEFAULT_THEME: ChromeTheme = "dark";
|
|
388
386
|
|
|
389
387
|
/** Whether a string is one of the declared {@link CHROME_THEMES}. */
|
|
390
|
-
function isChromeTheme(value: unknown): value is ChromeTheme {
|
|
391
|
-
return typeof value === "string" && (
|
|
388
|
+
export function isChromeTheme(value: unknown): value is ChromeTheme {
|
|
389
|
+
return typeof value === "string" && CHROME_THEMES.some((theme) => theme === value);
|
|
392
390
|
}
|
|
393
391
|
|
|
394
392
|
/** Read the persisted theme, falling back to {@link DEFAULT_THEME} on an absent/unknown value. */
|
|
@@ -486,8 +484,8 @@ export const PANE_SPLIT_MAX = 0.8;
|
|
|
486
484
|
* range, so the only way a bad value arrives is a corrupt or hand-edited record — and that is the
|
|
487
485
|
* one caller that has to be defended.
|
|
488
486
|
*/
|
|
489
|
-
function clampPaneSplit(value:
|
|
490
|
-
return
|
|
487
|
+
function clampPaneSplit(value: JsonValue | undefined): number {
|
|
488
|
+
return isNumber(value) && value >= PANE_SPLIT_MIN && value <= PANE_SPLIT_MAX
|
|
491
489
|
? value
|
|
492
490
|
: DEFAULT_PANE_SPLIT;
|
|
493
491
|
}
|
|
@@ -497,15 +495,27 @@ export function setPaneSplit(value: number): void {
|
|
|
497
495
|
shell.paneSplit = Math.min(PANE_SPLIT_MAX, Math.max(PANE_SPLIT_MIN, value));
|
|
498
496
|
}
|
|
499
497
|
|
|
500
|
-
/**
|
|
501
|
-
|
|
498
|
+
/**
|
|
499
|
+
* Read the persisted dock record, tolerating absent/corrupt storage.
|
|
500
|
+
*
|
|
501
|
+
* What comes back is the parsed JSON object rather than a {@link PersistedDocks}: that interface is
|
|
502
|
+
* what {@link persistDocks} WRITES, and a stored record is untrusted input, so every member is
|
|
503
|
+
* checked where it is read.
|
|
504
|
+
*/
|
|
505
|
+
function readPersistedDocks(): JsonObject {
|
|
502
506
|
try {
|
|
503
|
-
|
|
507
|
+
const parsed: unknown = JSON.parse(localStorage.getItem(DOCK_STORAGE_KEY) || "{}");
|
|
508
|
+
return isJsonObject(parsed) ? parsed : {};
|
|
504
509
|
} catch {
|
|
505
510
|
return {};
|
|
506
511
|
}
|
|
507
512
|
}
|
|
508
513
|
|
|
514
|
+
/** One state per dock, in {@link DOCK_IDS} order, each built by `make`. */
|
|
515
|
+
function perDock(make: (id: DockId) => DockState): Record<DockId, DockState> {
|
|
516
|
+
return { left: make("left"), right: make("right"), bottom: make("bottom") };
|
|
517
|
+
}
|
|
518
|
+
|
|
509
519
|
function freshGit(): ShellGit {
|
|
510
520
|
return {
|
|
511
521
|
branches: null,
|
|
@@ -613,18 +623,17 @@ export const DEFAULT_LAYOUT_ID = "design";
|
|
|
613
623
|
*/
|
|
614
624
|
function createShellState(): ShellState {
|
|
615
625
|
const saved = readPersistedDocks();
|
|
616
|
-
const docks =
|
|
617
|
-
for (const id of DOCK_IDS) {
|
|
626
|
+
const docks = perDock((id) => {
|
|
618
627
|
const width = saved[id];
|
|
619
|
-
const collapsed = saved[`${id}Collapsed`
|
|
620
|
-
|
|
628
|
+
const collapsed = saved[`${id}Collapsed`];
|
|
629
|
+
return {
|
|
621
630
|
// A stored `false` has to REOPEN a dock, so this cannot be the usual
|
|
622
631
|
// `if (saved.x) { collapse() }` shape — that silently pins a dock shut forever for
|
|
623
632
|
// Everyone who ever closed it once.
|
|
624
|
-
collapsed:
|
|
625
|
-
size:
|
|
633
|
+
collapsed: isBoolean(collapsed) ? collapsed : DOCK_DEFAULTS[id].collapsed,
|
|
634
|
+
size: isNumber(width) && width > 0 ? width : DOCK_DEFAULTS[id].size,
|
|
626
635
|
};
|
|
627
|
-
}
|
|
636
|
+
});
|
|
628
637
|
return {
|
|
629
638
|
bottomTab: isBottomTabId(saved.bottomTab) ? saved.bottomTab : DEFAULT_BOTTOM_TAB,
|
|
630
639
|
docks,
|
|
@@ -652,14 +661,13 @@ function createShellState(): ShellState {
|
|
|
652
661
|
applyStartupProfile();
|
|
653
662
|
|
|
654
663
|
/*
|
|
655
|
-
*
|
|
656
|
-
*
|
|
657
|
-
*
|
|
658
|
-
*
|
|
664
|
+
* SAFETY: `reactive()` returns a deep proxy carrying its target's own members, and ShellState holds
|
|
665
|
+
* no refs for `UnwrapNestedRefs` to unwrap, so the proxy IS a ShellState. The type argument is
|
|
666
|
+
* pinned to `object` because `UnwrapNestedRefs<ShellState>` recurses through `LayoutHit` and the
|
|
667
|
+
* git result shapes deeply enough for tsc to give up (TS2589). The proxy is deep either way — only
|
|
668
|
+
* the type computation is short-circuited. Same reason `tabs/tab.ts` casts its own reactive tree.
|
|
659
669
|
*/
|
|
660
|
-
export const shell
|
|
661
|
-
createShellState() as unknown as Record<string, unknown>,
|
|
662
|
-
) as unknown as ShellState;
|
|
670
|
+
export const shell = reactive<object>(createShellState()) as ShellState;
|
|
663
671
|
|
|
664
672
|
/**
|
|
665
673
|
* Write the whole dock record in one shot.
|
|
@@ -693,10 +701,13 @@ export function persistDocks(): void {
|
|
|
693
701
|
|
|
694
702
|
/** What a project's namespaced record holds: its named layouts, and the session it was left in. */
|
|
695
703
|
interface PersistedProject {
|
|
696
|
-
layouts?:
|
|
697
|
-
activeLayout?:
|
|
698
|
-
/**
|
|
699
|
-
|
|
704
|
+
layouts?: LayoutPreset[];
|
|
705
|
+
activeLayout?: string;
|
|
706
|
+
/**
|
|
707
|
+
* §14.8's session — open documents per pane, the active one, and each one's view settings. A
|
|
708
|
+
* session this boot has not read yet is carried over as the stored JSON it was.
|
|
709
|
+
*/
|
|
710
|
+
session?: PersistedSession | JsonValue | undefined;
|
|
700
711
|
}
|
|
701
712
|
|
|
702
713
|
/** The project whose layouts are loaded, or `undefined` before the first sync. */
|
|
@@ -704,51 +715,63 @@ let _layoutRoot: string | null | undefined;
|
|
|
704
715
|
|
|
705
716
|
/** Whether a parsed value is a usable {@link LayoutPreset} — a stored record is untrusted input. */
|
|
706
717
|
function isLayoutPreset(value: unknown): value is LayoutPreset {
|
|
707
|
-
|
|
718
|
+
/* Arrays fail here where the old `typeof … === "object"` let them through, and the outcome is
|
|
719
|
+
the same: an array carries no string `id`, so it was refused one line later. */
|
|
720
|
+
if (!isJsonObject(value)) {
|
|
708
721
|
return false;
|
|
709
722
|
}
|
|
710
|
-
const
|
|
723
|
+
const { docks } = value;
|
|
711
724
|
return (
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
isNavigatorPanelId(
|
|
716
|
-
isInspectorTabId(
|
|
717
|
-
isBottomTabId(
|
|
718
|
-
|
|
725
|
+
isString(value.id) &&
|
|
726
|
+
value.id !== "" &&
|
|
727
|
+
isString(value.name) &&
|
|
728
|
+
isNavigatorPanelId(value.navigatorPanel) &&
|
|
729
|
+
isInspectorTabId(value.inspectorTab) &&
|
|
730
|
+
isBottomTabId(value.bottomTab) &&
|
|
731
|
+
isJsonObject(docks) &&
|
|
732
|
+
DOCK_IDS.every((dock) => {
|
|
733
|
+
const entry = docks[dock];
|
|
734
|
+
return isJsonObject(entry) && isNumber(entry.size);
|
|
735
|
+
})
|
|
719
736
|
);
|
|
720
737
|
}
|
|
721
738
|
|
|
722
739
|
/** The raw record for `root`, or `{}` for absent, corrupt or hand-edited storage. */
|
|
723
|
-
function rawPersistedProject(root: string | null):
|
|
740
|
+
function rawPersistedProject(root: string | null): JsonObject {
|
|
724
741
|
if (!root) {
|
|
725
742
|
return {};
|
|
726
743
|
}
|
|
727
744
|
try {
|
|
728
|
-
|
|
745
|
+
const parsed: unknown = JSON.parse(
|
|
729
746
|
localStorage.getItem(`${PROJECT_STORAGE_PREFIX}${root}`) || "{}",
|
|
730
|
-
)
|
|
747
|
+
);
|
|
748
|
+
return isJsonObject(parsed) ? parsed : {};
|
|
731
749
|
} catch {
|
|
732
750
|
return {};
|
|
733
751
|
}
|
|
734
752
|
}
|
|
735
753
|
|
|
736
|
-
/**
|
|
737
|
-
|
|
754
|
+
/** A project's layouts as {@link readPersistedProject} recovers them. */
|
|
755
|
+
interface ProjectLayouts {
|
|
738
756
|
layouts: LayoutPreset[];
|
|
739
757
|
activeLayout: string | null;
|
|
740
|
-
}
|
|
741
|
-
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
/** Read a project's namespaced record, tolerating absent, corrupt and hand-edited storage. */
|
|
761
|
+
function readPersistedProject(root: string | null): ProjectLayouts {
|
|
762
|
+
const fresh: ProjectLayouts = { activeLayout: null, layouts: builtInLayouts() };
|
|
742
763
|
if (!root) {
|
|
743
764
|
return fresh;
|
|
744
765
|
}
|
|
745
766
|
const parsed = rawPersistedProject(root);
|
|
746
|
-
const layouts = Array.isArray(parsed.layouts)
|
|
767
|
+
const layouts = Array.isArray(parsed.layouts)
|
|
768
|
+
? parsed.layouts.flatMap((entry) => (isLayoutPreset(entry) ? [entry] : []))
|
|
769
|
+
: [];
|
|
747
770
|
if (layouts.length === 0) {
|
|
748
771
|
return fresh;
|
|
749
772
|
}
|
|
750
773
|
return {
|
|
751
|
-
activeLayout:
|
|
774
|
+
activeLayout: isString(parsed.activeLayout) ? parsed.activeLayout : null,
|
|
752
775
|
layouts,
|
|
753
776
|
};
|
|
754
777
|
}
|
|
@@ -903,10 +926,10 @@ export function applyLayout(id: string, deps: LayoutDeps): void {
|
|
|
903
926
|
export function saveLayout(name: string, deps: LayoutDeps): LayoutPreset {
|
|
904
927
|
const trimmed = name.trim();
|
|
905
928
|
const id = layoutIdFor(trimmed);
|
|
906
|
-
const docks =
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
}
|
|
929
|
+
const docks = perDock((dock) => ({
|
|
930
|
+
collapsed: shell.docks[dock].collapsed,
|
|
931
|
+
size: shell.docks[dock].size,
|
|
932
|
+
}));
|
|
910
933
|
const preset: LayoutPreset = {
|
|
911
934
|
bottomTab: isBottomTabId(shell.bottomTab) ? shell.bottomTab : DEFAULT_BOTTOM_TAB,
|
|
912
935
|
docks,
|
|
@@ -1219,7 +1242,7 @@ export function toggleActivityTab(tab: NavigatorPanelId): void {
|
|
|
1219
1242
|
* a long release cycle with a reader (the properties panel's layout panel) and no writer at all,
|
|
1220
1243
|
* which is why clicking a header did nothing.
|
|
1221
1244
|
*/
|
|
1222
|
-
export function setLayoutSelection(selection:
|
|
1245
|
+
export function setLayoutSelection(selection: LayoutHit | null): void {
|
|
1223
1246
|
shell.layoutSelection = selection;
|
|
1224
1247
|
}
|
|
1225
1248
|
|
package/src/site-context.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* @docs framework/site/i18n
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
11
12
|
import { projectState } from "./store";
|
|
12
13
|
import { getPlatform } from "./platform";
|
|
13
14
|
import { commitProjectConfig } from "./tabs/project-config";
|
|
@@ -57,10 +58,8 @@ export function getEffectiveStyle(docStyle?: JxStyle) {
|
|
|
57
58
|
}
|
|
58
59
|
const merged = { ...siteStyle };
|
|
59
60
|
for (const [k, v] of Object.entries(docStyle)) {
|
|
60
|
-
merged[k]
|
|
61
|
-
|
|
62
|
-
? { ...(merged[k] as JxStyle), ...(v as JxStyle) }
|
|
63
|
-
: v;
|
|
61
|
+
const base = merged[k];
|
|
62
|
+
merged[k] = isNonNullObject(v) && isNonNullObject(base) ? { ...base, ...v } : v;
|
|
64
63
|
}
|
|
65
64
|
return merged;
|
|
66
65
|
}
|
|
@@ -101,7 +100,8 @@ export function getEffectiveElements(docElements?: (JxElement | string)[]) {
|
|
|
101
100
|
const seen = new Set<string>();
|
|
102
101
|
const merged: (JxElement | string)[] = [];
|
|
103
102
|
for (const entry of [...siteElements, ...docElements]) {
|
|
104
|
-
|
|
103
|
+
// A null entry in hand-edited JSON has no key, and is skipped rather than thrown on.
|
|
104
|
+
const key = isString(entry) ? entry : isNonNullObject(entry) ? entry.$ref : undefined;
|
|
105
105
|
if (key && !seen.has(key)) {
|
|
106
106
|
seen.add(key);
|
|
107
107
|
merged.push(entry);
|
|
@@ -127,8 +127,9 @@ export function getEffectiveHead(docHead?: JxHeadEntry[]) {
|
|
|
127
127
|
const seen = new Set<string>();
|
|
128
128
|
const merged: JxHeadEntry[] = [];
|
|
129
129
|
for (const entry of [...siteHead, ...docHead]) {
|
|
130
|
-
|
|
131
|
-
|
|
130
|
+
// A null entry in hand-edited JSON is keyed by its serialisation, like any entry without a URL.
|
|
131
|
+
const attributes = isNonNullObject(entry) ? entry.attributes : undefined;
|
|
132
|
+
const key = String(attributes?.href || attributes?.src || "") || JSON.stringify(entry);
|
|
132
133
|
if (!seen.has(key)) {
|
|
133
134
|
seen.add(key);
|
|
134
135
|
merged.push(entry);
|
|
@@ -189,13 +190,16 @@ export function getEffectiveLayoutPath(docLayout: string | false | undefined) {
|
|
|
189
190
|
*/
|
|
190
191
|
export async function resolveLayoutDoc(layoutPath: string) {
|
|
191
192
|
const normalized = layoutPath.replace(/^\.\//, "");
|
|
192
|
-
|
|
193
|
-
|
|
193
|
+
const cached = layoutCache.get(normalized);
|
|
194
|
+
if (cached !== undefined) {
|
|
195
|
+
return structuredClone(cached);
|
|
194
196
|
}
|
|
195
197
|
|
|
196
198
|
try {
|
|
197
199
|
const platform = getPlatform();
|
|
198
200
|
const content = await platform.readFile(normalized);
|
|
201
|
+
/* SAFETY: a `$layout` target is a Jx document file, which is a JSON element object; the slot
|
|
202
|
+
walk that consumes it checks `children` is an array before reading any of it. */
|
|
199
203
|
const doc = JSON.parse(content) as JxMutableNode;
|
|
200
204
|
layoutCache.set(normalized, doc);
|
|
201
205
|
return structuredClone(doc);
|
|
@@ -220,8 +224,8 @@ export function distributePageIntoLayout(layoutDoc: JxMutableNode, pageDoc: JxMu
|
|
|
220
224
|
const defaults: (JxMutableNode | string)[] = [];
|
|
221
225
|
|
|
222
226
|
for (const child of children) {
|
|
223
|
-
const slotName =
|
|
224
|
-
if (
|
|
227
|
+
const slotName = isString(child) ? undefined : child.attributes?.slot;
|
|
228
|
+
if (!isString(child) && isString(slotName) && slotName) {
|
|
225
229
|
if (!named.has(slotName)) {
|
|
226
230
|
named.set(slotName, []);
|
|
227
231
|
}
|
|
@@ -254,18 +258,15 @@ function fillSlots(
|
|
|
254
258
|
named: Map<string, JxMutableNode[]>,
|
|
255
259
|
defaults: (JxMutableNode | string)[],
|
|
256
260
|
) {
|
|
257
|
-
if (!node || typeof node !== "object") {
|
|
258
|
-
return;
|
|
259
|
-
}
|
|
260
261
|
if (!Array.isArray(node.children)) {
|
|
261
262
|
return;
|
|
262
263
|
}
|
|
263
264
|
|
|
264
265
|
const newChildren: (JxMutableNode | string)[] = [];
|
|
265
266
|
for (const child of node.children) {
|
|
266
|
-
if (child &&
|
|
267
|
+
if (isNonNullObject(child) && child.tagName === "slot") {
|
|
267
268
|
const slotName = child.attributes?.name;
|
|
268
|
-
if (
|
|
269
|
+
if (isString(slotName) && slotName && named.has(slotName)) {
|
|
269
270
|
newChildren.push(...named.get(slotName)!);
|
|
270
271
|
named.delete(slotName);
|
|
271
272
|
} else if (!slotName && defaults.length > 0) {
|
|
@@ -274,15 +275,26 @@ function fillSlots(
|
|
|
274
275
|
newChildren.push(...child.children);
|
|
275
276
|
}
|
|
276
277
|
} else {
|
|
277
|
-
|
|
278
|
+
/* Only an element has slots to fill. A null child (hand-edited JSON) used to reach the
|
|
279
|
+
`!node` guard this function opened with; it now stops here, with the same outcome. */
|
|
280
|
+
if (isNonNullObject(child)) {
|
|
278
281
|
fillSlots(child, named, defaults);
|
|
279
282
|
}
|
|
280
283
|
newChildren.push(child);
|
|
281
284
|
}
|
|
282
285
|
}
|
|
283
|
-
node.children = newChildren
|
|
286
|
+
node.children = newChildren;
|
|
284
287
|
}
|
|
285
288
|
|
|
289
|
+
/**
|
|
290
|
+
* A `project.json` patch: each key's new value, or `undefined` to remove the key.
|
|
291
|
+
*
|
|
292
|
+
* `Partial<ProjectConfig>` cannot say the second half under `exactOptionalPropertyTypes` — its
|
|
293
|
+
* `url` is `string` when present, never `undefined` — so clearing a setting had to be spelled as a
|
|
294
|
+
* double cast at every call site that wanted to.
|
|
295
|
+
*/
|
|
296
|
+
export type ProjectConfigPatch = { [K in keyof ProjectConfig]?: ProjectConfig[K] | undefined };
|
|
297
|
+
|
|
286
298
|
/**
|
|
287
299
|
* Merge a partial patch into the project's configuration and persist it.
|
|
288
300
|
*
|
|
@@ -297,12 +309,15 @@ function fillSlots(
|
|
|
297
309
|
* Problem, because the eight other sites reach this through `void updateSiteConfig(...)` and used
|
|
298
310
|
* to drop it on the floor.
|
|
299
311
|
*
|
|
300
|
-
* @param {
|
|
301
|
-
*
|
|
312
|
+
* @param {ProjectConfigPatch} patch - Fields to merge into the current projectConfig; a value of
|
|
313
|
+
* `undefined` clears the key.
|
|
302
314
|
* @throws {unknown} The platform's rejection, when the write fails.
|
|
303
315
|
*/
|
|
304
|
-
export async function updateSiteConfig(patch:
|
|
305
|
-
|
|
316
|
+
export async function updateSiteConfig(patch: ProjectConfigPatch) {
|
|
317
|
+
/* SAFETY: `commitProjectConfig` spreads the patch over the current config and serialises the
|
|
318
|
+
result with JSON.stringify, so an `undefined` member reaches disk as an absent key and the
|
|
319
|
+
written file is a ProjectConfig; every other member already has its ProjectConfig type. */
|
|
320
|
+
const result = await commitProjectConfig(patch as Partial<ProjectConfig>);
|
|
306
321
|
if (!result.ok) {
|
|
307
322
|
throw result.error;
|
|
308
323
|
}
|