@jxsuite/studio 4.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/data/elements-meta.json +5 -15
- package/data/html-meta.json +51 -6
- package/dist/chunks/{2020-xp8vnwma.js → 2020-g79n01v9.js} +14 -14
- package/dist/chunks/action-group-sp6tna8v.js +118 -0
- package/dist/chunks/adapter-nj7tnjfn.js +13 -0
- package/dist/chunks/cf-account-picker-fyf63pmy.js +495 -0
- package/dist/chunks/cf-settings-71bv5zn9.js +20 -0
- package/dist/chunks/color-area-v17df7b8.js +154 -0
- package/dist/chunks/color-field-anwybnkn.js +208 -0
- package/dist/chunks/color-slider-44ez96fc.js +79 -0
- package/dist/chunks/color-xgg3kfw7.js +35 -0
- package/dist/chunks/combobox-5e7jev23.js +236 -0
- package/dist/chunks/components-2w1f35qs.js +18 -0
- package/dist/chunks/content-source-3wqeas45.js +46 -0
- package/dist/chunks/convert-to-repeater-d0cgnb6d.js +639 -0
- package/dist/chunks/dialog-s890b918.js +85 -0
- package/dist/chunks/editor-3qhbg51x.js +35 -0
- package/dist/chunks/entry-commands-d6g50j7s.js +42 -0
- package/dist/chunks/extension-sections-fy7q4fe9.js +651 -0
- package/dist/chunks/file-ops-3btj6st0.js +47 -0
- package/dist/chunks/files-ef8fgs3w.js +72 -0
- package/dist/chunks/format-host-3c33nwr8.js +40 -0
- package/dist/chunks/fs-events-13tj6sex.js +18 -0
- package/dist/chunks/git-panel-4wp2rn9b.js +49 -0
- package/dist/chunks/icons-yy10wk9r.js +402 -0
- package/dist/chunks/iframe-entry-15g3n6xv.js +114 -0
- package/dist/chunks/iframe-entry-b27vq81n.js +203 -0
- package/dist/chunks/iframe-entry-nbyxee1y.js +154 -0
- package/dist/chunks/iframe-host-jgesd924.js +115 -0
- package/dist/chunks/{index-nj44jpzj.js → index-mdmyx6s2.js} +11 -11
- package/dist/chunks/index-n4j7qxyr.js +109 -0
- package/dist/chunks/{javascript-q8kpmfah.js → javascript-xvrfrpkb.js} +8 -9
- package/dist/chunks/{jsonMode-dkr040ga.js → jsonMode-tyx2kj6p.js} +526 -527
- package/dist/chunks/jx-validate-j0wxk72w.js +15 -0
- package/dist/chunks/layers-1nq5evsh.js +29 -0
- package/dist/chunks/layers-panel-ar2gh90g.js +40 -0
- package/dist/chunks/listbox-6v2ac08j.js +44 -0
- package/dist/chunks/lit-html-m244w9nh.js +17 -0
- package/dist/chunks/media-picker-2qbetq73.js +33 -0
- package/dist/chunks/menu-q99sy9rf.js +285 -0
- package/dist/chunks/menu-rf7n72mf.js +14 -0
- package/dist/chunks/{monaco-binding-rj6xpx9y.js → monaco-binding-sw6en4dw.js} +12 -15
- package/dist/chunks/monaco-buffer-bhy3hb6m.js +24 -0
- package/dist/chunks/{monaco-setup-rws7k4br.js → monaco-setup-8r62fj6y.js} +27 -37
- package/dist/chunks/notify-628t0anh.js +21 -0
- package/dist/chunks/number-field-5cndyft8.js +72 -0
- package/dist/chunks/parse-0zx14y15.js +10 -0
- package/dist/chunks/platform-ts9cg1a4.js +15 -0
- package/dist/chunks/popover-47z3ytva.js +25 -0
- package/dist/chunks/publish-panel-98f7sr3g.js +27 -0
- package/dist/chunks/quick-search-srzz83k2.js +45 -0
- package/dist/chunks/references-n553f0e1.js +26 -0
- package/dist/chunks/right-panel-rrgx2dn3.js +45 -0
- package/dist/chunks/section-registry-5pq32t0q.js +25 -0
- package/dist/chunks/select-2r16ez41.js +49 -0
- package/dist/chunks/split-g7nm1rgb.js +191 -0
- package/dist/chunks/studio-0hqbpbd0.js +62 -0
- package/dist/chunks/studio-18avnhjp.js +2430 -0
- package/dist/chunks/{studio-kryvsw6j.js → studio-1k325pwf.js} +48 -48
- package/dist/chunks/{studio-hbtp0eh1.js → studio-25hkdrkw.js} +356 -85
- package/dist/chunks/studio-26d7myd1.js +258 -0
- package/dist/chunks/{studio-p8j86wag.js → studio-38emantv.js} +22 -5
- package/dist/chunks/studio-3gxv60tn.js +422 -0
- package/dist/chunks/{studio-8swrjbny.js → studio-3hxkd92t.js} +275 -163
- package/dist/chunks/studio-4m0haseg.js +185 -0
- package/dist/chunks/{studio-ynxwkrzd.js → studio-4wbb9ct0.js} +1953 -1785
- package/dist/chunks/{studio-gv8vvshc.js → studio-5523bpzt.js} +11 -11
- package/dist/chunks/{studio-5q69gfag.js → studio-57mf66w2.js} +1753 -2484
- package/dist/chunks/studio-5jy81t3s.js +17463 -0
- package/dist/chunks/studio-5rt7sqa0.js +1168 -0
- package/dist/chunks/studio-5te5tqng.js +81 -0
- package/dist/chunks/{studio-p4ngc046.js → studio-6ewqv390.js} +9 -9
- package/dist/chunks/{studio-9ab8gqsm.js → studio-6nzaktvy.js} +7 -7
- package/dist/chunks/studio-6xa21ej9.js +28 -0
- package/dist/chunks/{studio-5ehhackm.js → studio-727xh0e3.js} +19 -19
- package/dist/chunks/{studio-eenfkt4e.js → studio-79y5sz51.js} +52 -38
- package/dist/chunks/{studio-4q0wznzf.js → studio-7e11jpa9.js} +461 -145
- package/dist/chunks/{studio-q7v10cg2.js → studio-7r42c6ca.js} +17 -7
- package/dist/chunks/studio-7xptrg0j.js +954 -0
- package/dist/chunks/{studio-cft9r4r7.js → studio-81390n6f.js} +22 -22
- package/dist/chunks/{studio-q43a5y9h.js → studio-8jn5yhyn.js} +16 -16
- package/dist/chunks/studio-8qtrpzr3.js +839 -0
- package/dist/chunks/{studio-dg7zyt5x.js → studio-98b3z07n.js} +1 -1
- package/dist/chunks/studio-9xxz1q69.js +1356 -0
- package/dist/chunks/studio-akbww0j5.js +13615 -0
- package/dist/chunks/studio-arfpe389.js +195 -0
- package/dist/chunks/{studio-2zkz8evn.js → studio-az3zd49t.js} +473 -281
- package/dist/chunks/studio-cpvb2ed1.js +1171 -0
- package/dist/chunks/{studio-9r6j5ev1.js → studio-d0300636.js} +5078 -19
- package/dist/chunks/{studio-bgxt93ga.js → studio-d055c37e.js} +13 -13
- package/dist/chunks/studio-d1ja2x9r.js +362 -0
- package/dist/chunks/{studio-b9b6t1dg.js → studio-e1f24eff.js} +5664 -5666
- package/dist/chunks/{studio-4pqqxbrt.js → studio-em9nw8eh.js} +301 -112
- package/dist/chunks/studio-erdatzvp.js +1190 -0
- package/dist/chunks/{studio-g1wdche0.js → studio-esrxgwh6.js} +80 -80
- package/dist/chunks/studio-fabxk6r9.js +2811 -0
- package/dist/chunks/{studio-3n4ndrzh.js → studio-h4nvnjvz.js} +303 -303
- package/dist/chunks/studio-hhvs4sdg.js +195 -0
- package/dist/chunks/{studio-68n67094.js → studio-kcgff4r0.js} +15 -18
- package/dist/chunks/{studio-685s0ytq.js → studio-nqgawfks.js} +572 -572
- package/dist/chunks/{studio-xrapxwwc.js → studio-p1dw8wfw.js} +55 -29
- package/dist/chunks/studio-pm6hgy7r.js +4763 -0
- package/dist/chunks/studio-q0a3yk4n.js +33 -0
- package/dist/chunks/{studio-wcy8trfx.js → studio-q3x06vmj.js} +23 -22
- package/dist/chunks/studio-qahxvnan.js +111 -0
- package/dist/chunks/{studio-53n8bp04.js → studio-r6xmmtfh.js} +1 -1
- package/dist/chunks/{studio-kjjsjak4.js → studio-rkstz940.js} +3661 -6136
- package/dist/chunks/{studio-tvgyw9xw.js → studio-rnyf3f8e.js} +83 -250
- package/dist/chunks/studio-rpyah2ew.js +2805 -0
- package/dist/chunks/studio-rs76k67r.js +12 -0
- package/dist/chunks/{studio-yxrkyv8a.js → studio-s6z853aq.js} +12108 -11766
- package/dist/chunks/{studio-sf7zjgv1.js → studio-sgdc5pfc.js} +8 -8
- package/dist/chunks/studio-tb3ev01j.js +763 -0
- package/dist/chunks/{studio-t5wqwzdh.js → studio-tjjk7jvk.js} +1 -1
- package/dist/chunks/studio-vhv5tgxm.js +51 -0
- package/dist/chunks/{studio-htsf0w6m.js → studio-vz68yn9e.js} +31 -154
- package/dist/chunks/studio-wqpngpsk.js +174 -0
- package/dist/chunks/{studio-eesa1myv.js → studio-x3rty6tr.js} +58 -58
- package/dist/chunks/studio-xsykpvsh.js +8448 -0
- package/dist/chunks/{studio-92ab2jqe.js → studio-y9zedyjn.js} +14 -14
- package/dist/chunks/studio-yxa81f45.js +12 -0
- package/dist/chunks/swatch-group-t0n6h2rn.js +139 -0
- package/dist/chunks/tabs-wbp1cdws.js +156 -0
- package/dist/chunks/textfield-abk6qyee.js +73 -0
- package/dist/chunks/toast-780pvfbv.js +27 -0
- package/dist/chunks/toast-host-3sqv46sn.js +116 -0
- package/dist/chunks/toolbar-xbh5bhtr.js +194 -0
- package/dist/chunks/tooltip-eptb614w.js +369 -0
- package/dist/chunks/tree-a73p0pqm.js +367 -0
- package/dist/chunks/{tsMode-76kr53q0.js → tsMode-jy4m86rv.js} +83 -85
- package/dist/chunks/workspace-wrew8zk4.js +69 -0
- package/dist/chunks/{ws-client-6shc5rze.js → ws-client-ny4zc51r.js} +20 -22
- package/dist/iframe-entry.js +1812 -698
- package/dist/manifest.json +7 -0
- package/dist/studio.js +52900 -36573
- package/dist/workers/editor.worker.js +1040 -1085
- package/dist/workers/json.worker.js +1946 -1991
- package/dist/workers/ts.worker.js +4960 -5005
- package/favicon.ico +0 -0
- package/index.html +2 -0
- package/package.json +22 -55
- package/src/about/about-modal.ts +73 -123
- package/src/browse/library-commands.ts +20 -49
- package/src/browse/library-layouts.ts +87 -218
- package/src/browse/library-pane.ts +406 -438
- package/src/canvas/canvas-helpers.ts +0 -49
- package/src/canvas/canvas-live-render.ts +25 -2
- package/src/canvas/canvas-render.ts +666 -231
- package/src/canvas/canvas-surface.ts +0 -1
- package/src/canvas/canvas-utils.ts +310 -117
- package/src/canvas/dialog-path.ts +76 -0
- package/src/canvas/dialog-state.ts +67 -0
- package/src/canvas/diff-marks.ts +252 -0
- package/src/canvas/diff-toolbar.ts +349 -0
- package/src/canvas/diff-view.ts +123 -0
- package/src/canvas/edit-width-drag.ts +187 -0
- package/src/canvas/edit-width.ts +150 -0
- package/src/canvas/iframe-entry.ts +125 -8
- package/src/canvas/iframe-host.ts +271 -15
- package/src/canvas/iframe-interaction.ts +133 -13
- package/src/canvas/iframe-patch.ts +7 -1
- package/src/canvas/iframe-position.ts +5 -6
- package/src/canvas/iframe-protocol.ts +106 -5
- package/src/canvas/iframe-render.ts +373 -5
- package/src/canvas/iframe-slash.ts +2 -2
- package/src/canvas/iframe-subtree.ts +5 -8
- package/src/canvas/path-mapping.ts +25 -3
- package/src/canvas/popover-path.ts +106 -0
- package/src/canvas/popover-state.ts +155 -0
- package/src/canvas/surface-registry.ts +21 -10
- package/src/collab/presence-chips.ts +51 -73
- package/src/commands/app-commands.ts +10 -0
- package/src/commands/budget.ts +12 -0
- package/src/commands/command-args.ts +369 -6
- package/src/commands/defaults.ts +44 -14
- package/src/commands/live-context.ts +11 -5
- package/src/commands/reference.ts +12 -2
- package/src/commands/registry.ts +165 -8
- package/src/content/entry-commands.ts +16 -23
- package/src/content/entry-editor.ts +144 -101
- package/src/editor/canvas-slash-bridge.ts +2 -2
- package/src/editor/context-menu.ts +49 -200
- package/src/editor/convert-to-component.ts +42 -82
- package/src/editor/convert-to-repeater.ts +132 -173
- package/src/editor/inline-edit.ts +11 -0
- package/src/editor/shortcuts.ts +65 -26
- package/src/editor/slash-menu.ts +150 -157
- package/src/files/file-ops.ts +117 -11
- package/src/files/files.ts +949 -664
- package/src/files/json-layout.ts +474 -0
- package/src/files/media-paths.ts +13 -42
- package/src/files/media-usage.ts +41 -131
- package/src/files/serialize-document.ts +8 -1
- package/src/format/convert-file.ts +16 -10
- package/src/format/format-host.ts +50 -1
- package/src/github/github-auth.ts +71 -29
- package/src/github/github-publish.ts +57 -65
- package/src/grid/cell-editors.ts +46 -4
- package/src/grid/cell-popovers.ts +65 -62
- package/src/grid/grid-open.ts +86 -64
- package/src/grid/grid-panel.ts +390 -469
- package/src/grid/redirects-grid.ts +40 -44
- package/src/hosting/document.ts +2 -0
- package/src/hosting/layout.ts +10 -0
- package/src/i18n/i18n-commands.ts +127 -62
- package/src/media/media-pane.ts +83 -133
- package/src/new-project/add-repo-modal.ts +125 -176
- package/src/new-project/import-tab.ts +201 -250
- package/src/new-project/location-fields.ts +101 -165
- package/src/new-project/new-project-modal.ts +376 -367
- package/src/packages/jxsuite-update.ts +76 -18
- package/src/panels/activity-panel.ts +137 -104
- package/src/panels/ai-chat/chat-markdown.ts +15 -13
- package/src/panels/ai-chat/chat-view.ts +307 -472
- package/src/panels/ai-chat/composer.ts +175 -153
- package/src/panels/ai-chat/sessions-view.ts +31 -62
- package/src/panels/ai-panel.ts +210 -185
- package/src/panels/block-action-bar.ts +437 -643
- package/src/panels/bottom-dock.ts +112 -47
- package/src/panels/chat-panel.ts +19 -14
- package/src/panels/data-explorer.ts +141 -102
- package/src/panels/data-grid.ts +183 -150
- package/src/panels/dnd.ts +75 -20
- package/src/panels/editors.ts +26 -19
- package/src/panels/elements-panel.ts +243 -186
- package/src/panels/empty-state.ts +26 -42
- package/src/panels/events-panel.ts +950 -729
- package/src/panels/formula-workspace.ts +434 -207
- package/src/panels/frontmatter-fields.ts +185 -153
- package/src/panels/frontmatter-panel.ts +411 -187
- package/src/panels/git-diff-open.ts +148 -0
- package/src/panels/git-panel.ts +679 -605
- package/src/panels/head-panel.ts +617 -435
- package/src/panels/i18n-panel.ts +153 -133
- package/src/panels/imports-panel.ts +388 -414
- package/src/panels/jump-bar.ts +174 -147
- package/src/panels/layers-panel.ts +785 -671
- package/src/panels/left-panel.ts +166 -94
- package/src/panels/navigator-panels.ts +1 -1
- package/src/panels/pane-context.ts +529 -677
- package/src/panels/pane-grid.ts +265 -241
- package/src/panels/panel-registry.ts +15 -4
- package/src/panels/problems-panel.ts +177 -99
- package/src/panels/properties-panel.ts +1525 -966
- package/src/panels/provenance.ts +31 -113
- package/src/panels/quick-search.ts +217 -172
- package/src/panels/right-panel.ts +135 -169
- package/src/panels/seo-modal.ts +346 -167
- package/src/panels/settings-menu.ts +109 -646
- package/src/panels/settings-pane.ts +102 -86
- package/src/panels/signals-panel.ts +1318 -1172
- package/src/panels/statement-editor.ts +556 -428
- package/src/panels/style-panel.ts +1367 -630
- package/src/panels/style-utils.ts +36 -32
- package/src/panels/stylebook-doc.ts +30 -73
- package/src/panels/stylebook-layers-panel.ts +202 -109
- package/src/panels/stylebook-panel.ts +124 -88
- package/src/panels/tab-strip.ts +385 -287
- package/src/platforms/cloud.ts +347 -86
- package/src/platforms/devserver.ts +13 -0
- package/src/publish/deploy-checklist.ts +124 -78
- package/src/publish/publish-commands.ts +4 -12
- package/src/publish/publish-panel.ts +165 -299
- package/src/services/a11y-report.ts +100 -43
- package/src/services/ai-command-tools.ts +468 -0
- package/src/services/ai-import-tools.ts +50 -12
- package/src/services/ai-models.ts +108 -1
- package/src/services/ai-session-store.ts +6 -0
- package/src/services/ai-system-prompt.ts +110 -18
- package/src/services/ai-tools.ts +28 -143
- package/src/services/ai-write-report.ts +174 -0
- package/src/services/context-manager.ts +12 -1
- package/src/services/document-assistant.ts +50 -2
- package/src/services/idle.ts +16 -14
- package/src/services/live-surfaces.ts +237 -0
- package/src/services/model-uri.ts +75 -0
- package/src/services/notify.ts +63 -6
- package/src/services/popover-report.ts +325 -0
- package/src/services/surface-registry.ts +56 -0
- package/src/services/tool-executor.ts +17 -0
- package/src/settings/contexts-section.ts +301 -299
- package/src/settings/contributed-section.ts +361 -222
- package/src/settings/css-vars-editor.ts +320 -325
- package/src/settings/defs-editor.ts +572 -535
- package/src/settings/dependencies-editor.ts +79 -107
- package/src/settings/extension-commands.ts +379 -0
- package/src/settings/extension-rows.ts +113 -0
- package/src/settings/extensions-section.ts +287 -0
- package/src/settings/general-settings.ts +130 -181
- package/src/settings/head-editor.ts +10 -305
- package/src/settings/locales-section.ts +146 -196
- package/src/settings/preferences-accounts.ts +193 -12
- package/src/settings/preferences-dialog.ts +384 -307
- package/src/settings/project-sections.ts +108 -181
- package/src/settings/schema-field-ui.ts +11 -399
- package/src/settings/section-registry.ts +8 -1
- package/src/settings/settings-document.ts +31 -29
- package/src/shell/tree.ts +42 -87
- package/src/shell.ts +48 -36
- package/src/studio.ts +90 -67
- package/src/style/token-ref.ts +0 -39
- package/src/surfaces/about.json +263 -0
- package/src/surfaces/about.ts +163 -0
- package/src/surfaces/add-repo.json +486 -0
- package/src/surfaces/add-repo.ts +236 -0
- package/src/surfaces/ai-chat.json +2185 -0
- package/src/surfaces/ai-chat.ts +549 -0
- package/src/surfaces/ai-credentials-form.json +332 -0
- package/src/surfaces/ai-credentials-form.ts +151 -0
- package/src/surfaces/ai-managed-connect.json +108 -0
- package/src/surfaces/ai-managed-connect.ts +123 -0
- package/src/surfaces/ai-model-picker.json +114 -0
- package/src/surfaces/ai-model-picker.ts +139 -0
- package/src/surfaces/block-action-bar.json +640 -0
- package/src/surfaces/block-action-bar.ts +368 -0
- package/src/surfaces/bottom-dock.json +154 -0
- package/src/surfaces/bottom-dock.ts +125 -0
- package/src/surfaces/canvas-stage.json +444 -0
- package/src/surfaces/canvas-stage.ts +253 -0
- package/src/surfaces/cf-account-picker.json +300 -0
- package/src/surfaces/cf-account-picker.ts +214 -0
- package/src/surfaces/commandbar.json +984 -0
- package/src/{panels/toolbar.ts → surfaces/commandbar.ts} +414 -389
- package/src/surfaces/convert-repeater.json +309 -0
- package/src/surfaces/convert-repeater.ts +276 -0
- package/src/surfaces/data-actions.json +157 -0
- package/src/surfaces/data-actions.ts +115 -0
- package/src/surfaces/dialog.json +289 -0
- package/src/surfaces/dialog.ts +343 -0
- package/src/surfaces/diff-toolbar.json +266 -0
- package/src/surfaces/diff-toolbar.ts +139 -0
- package/src/surfaces/doc-header.json +739 -0
- package/src/surfaces/doc-header.ts +223 -0
- package/src/surfaces/empty-state.json +152 -0
- package/src/surfaces/empty-state.ts +173 -0
- package/src/surfaces/entry-editor.json +281 -0
- package/src/surfaces/entry-editor.ts +191 -0
- package/src/surfaces/expression-editor.json +977 -0
- package/src/surfaces/expression-editor.ts +266 -0
- package/src/surfaces/files-panel.json +592 -0
- package/src/surfaces/files-panel.ts +301 -0
- package/src/surfaces/formula-palette.json +364 -0
- package/src/surfaces/formula-palette.ts +340 -0
- package/src/surfaces/git-panel.json +1822 -0
- package/src/surfaces/git-panel.ts +272 -0
- package/src/surfaces/github-auth.json +112 -0
- package/src/surfaces/github-auth.ts +139 -0
- package/src/surfaces/github-publish.json +206 -0
- package/src/surfaces/github-publish.ts +169 -0
- package/src/surfaces/grid-cell.json +218 -0
- package/src/surfaces/grid-cell.ts +120 -0
- package/src/surfaces/grid-open.json +147 -0
- package/src/surfaces/grid-open.ts +87 -0
- package/src/surfaces/grid-panel.json +706 -0
- package/src/surfaces/grid-panel.ts +206 -0
- package/src/surfaces/grid-replace.json +179 -0
- package/src/surfaces/grid-replace.ts +89 -0
- package/src/surfaces/grid-views.json +446 -0
- package/src/surfaces/grid-views.ts +172 -0
- package/src/surfaces/inspector-dock.json +187 -0
- package/src/surfaces/inspector-dock.ts +161 -0
- package/src/surfaces/jump-bar.json +243 -0
- package/src/surfaces/jump-bar.ts +129 -0
- package/src/surfaces/jxsuite-update.json +146 -0
- package/src/surfaces/jxsuite-update.ts +149 -0
- package/src/surfaces/library-pane.json +1509 -0
- package/src/surfaces/library-pane.ts +363 -0
- package/src/surfaces/logic-panel.json +1949 -0
- package/src/surfaces/logic-panel.ts +369 -0
- package/src/surfaces/logic-workspace.json +685 -0
- package/src/surfaces/logic-workspace.ts +238 -0
- package/src/surfaces/media-browser.json +303 -0
- package/src/surfaces/media-browser.ts +145 -0
- package/src/surfaces/media-field.json +163 -0
- package/src/surfaces/media-field.ts +116 -0
- package/src/surfaces/media-pane.json +513 -0
- package/src/surfaces/media-pane.ts +197 -0
- package/src/surfaces/menu.json +232 -0
- package/src/surfaces/menu.ts +375 -0
- package/src/surfaces/navigator-dock.json +113 -0
- package/src/surfaces/navigator-dock.ts +130 -0
- package/src/surfaces/new-project.json +1654 -0
- package/src/surfaces/new-project.ts +411 -0
- package/src/surfaces/palette.json +535 -0
- package/src/surfaces/pane-context.json +1497 -0
- package/src/surfaces/pane-context.ts +513 -0
- package/src/surfaces/pane-grid.json +188 -0
- package/src/surfaces/pane-grid.ts +250 -0
- package/src/surfaces/panel-activity.json +563 -0
- package/src/surfaces/panel-activity.ts +187 -0
- package/src/surfaces/panel-data.json +141 -0
- package/src/surfaces/panel-data.ts +156 -0
- package/src/surfaces/panel-deploy-checklist.json +283 -0
- package/src/surfaces/panel-deploy-checklist.ts +175 -0
- package/src/surfaces/panel-elements.json +367 -0
- package/src/surfaces/panel-elements.ts +175 -0
- package/src/surfaces/panel-i18n.json +569 -0
- package/src/surfaces/panel-i18n.ts +212 -0
- package/src/surfaces/panel-imports.json +780 -0
- package/src/surfaces/panel-imports.ts +209 -0
- package/src/surfaces/panel-outline.json +734 -0
- package/src/surfaces/panel-outline.ts +326 -0
- package/src/surfaces/panel-page.json +1017 -0
- package/src/surfaces/panel-page.ts +240 -0
- package/src/surfaces/panel-problems.json +497 -0
- package/src/surfaces/panel-problems.ts +157 -0
- package/src/surfaces/panel-signals.json +1973 -0
- package/src/surfaces/panel-signals.ts +436 -0
- package/src/surfaces/panel-stylebook-layers.json +317 -0
- package/src/surfaces/panel-stylebook-layers.ts +155 -0
- package/src/surfaces/preferences.json +850 -0
- package/src/surfaces/preferences.ts +332 -0
- package/src/surfaces/progress-modal.json +110 -0
- package/src/surfaces/progress-modal.ts +150 -0
- package/src/surfaces/properties-panel.json +1578 -0
- package/src/surfaces/properties-panel.ts +337 -0
- package/src/surfaces/publish.json +945 -0
- package/src/surfaces/publish.ts +392 -0
- package/src/surfaces/push-plan.json +110 -0
- package/src/surfaces/push-plan.ts +87 -0
- package/src/surfaces/rail.json +255 -0
- package/src/surfaces/rail.ts +206 -0
- package/src/surfaces/reference-field.json +191 -0
- package/src/surfaces/reference-field.ts +168 -0
- package/src/surfaces/schema-builder.json +1011 -0
- package/src/surfaces/schema-builder.ts +181 -0
- package/src/surfaces/schema-form.json +1013 -0
- package/src/surfaces/schema-form.ts +287 -0
- package/src/surfaces/secret-field.json +60 -0
- package/src/surfaces/secret-field.ts +146 -0
- package/src/surfaces/seo.json +932 -0
- package/src/surfaces/seo.ts +334 -0
- package/src/surfaces/settings-contexts.json +538 -0
- package/src/surfaces/settings-contexts.ts +196 -0
- package/src/surfaces/settings-contributed.json +489 -0
- package/src/surfaces/settings-contributed.ts +199 -0
- package/src/surfaces/settings-css-vars.json +820 -0
- package/src/surfaces/settings-css-vars.ts +199 -0
- package/src/surfaces/settings-defs.json +1363 -0
- package/src/surfaces/settings-defs.ts +232 -0
- package/src/surfaces/settings-deploy.json +108 -0
- package/src/surfaces/settings-deploy.ts +135 -0
- package/src/surfaces/settings-extensions.json +486 -0
- package/src/surfaces/settings-extensions.ts +201 -0
- package/src/surfaces/settings-head.json +779 -0
- package/src/surfaces/settings-head.ts +397 -0
- package/src/surfaces/settings-locales.json +420 -0
- package/src/surfaces/settings-locales.ts +137 -0
- package/src/surfaces/settings-overview.json +423 -0
- package/src/surfaces/settings-overview.ts +218 -0
- package/src/surfaces/settings-packages.json +549 -0
- package/src/surfaces/settings-packages.ts +158 -0
- package/src/surfaces/settings-pane.json +147 -0
- package/src/surfaces/settings-pane.ts +150 -0
- package/src/surfaces/settings-rawjson.json +104 -0
- package/src/surfaces/settings-rawjson.ts +107 -0
- package/src/surfaces/shell.json +99 -0
- package/src/surfaces/shell.ts +30 -0
- package/src/surfaces/slash-menu.json +180 -0
- package/src/surfaces/slash-menu.ts +272 -0
- package/src/surfaces/statements.json +607 -0
- package/src/surfaces/statements.ts +238 -0
- package/src/surfaces/statusbar.json +94 -0
- package/src/{panels → surfaces}/statusbar.ts +163 -90
- package/src/surfaces/style-panel.json +1643 -0
- package/src/surfaces/style-panel.ts +338 -0
- package/src/surfaces/stylebook-chrome.json +122 -0
- package/src/surfaces/stylebook-chrome.ts +122 -0
- package/src/surfaces/tab-strip.json +448 -0
- package/src/surfaces/tab-strip.ts +200 -0
- package/src/surfaces/target-line.json +419 -0
- package/src/surfaces/target-line.ts +349 -0
- package/src/surfaces/toasts.json +189 -0
- package/src/surfaces/welcome.json +571 -0
- package/src/surfaces/welcome.ts +338 -0
- package/src/tabs/project-config.ts +71 -15
- package/src/tabs/tab.ts +52 -1
- package/src/types.ts +49 -3
- package/src/ui/ai-credentials-form.ts +104 -100
- package/src/ui/ai-managed-connect.ts +116 -49
- package/src/ui/ai-model-picker.ts +102 -47
- package/src/ui/cf-account-picker.ts +135 -0
- package/src/ui/color-selector.ts +80 -301
- package/src/ui/dynamic-slot.ts +43 -283
- package/src/ui/expression-editor.ts +797 -576
- package/src/ui/field-input.ts +8 -181
- package/src/ui/form-controls.ts +838 -366
- package/src/ui/formula-chips.ts +80 -85
- package/src/ui/kit.ts +33 -0
- package/src/ui/layers.ts +293 -593
- package/src/ui/media-picker.ts +203 -284
- package/src/ui/panel-resize.ts +251 -64
- package/src/ui/popover-surface.ts +153 -0
- package/src/ui/progress-modal.ts +22 -60
- package/src/ui/regions.ts +13 -7
- package/src/ui/schema-form.ts +906 -440
- package/src/ui/surface.ts +122 -0
- package/src/ui/unit-selector.ts +15 -131
- package/src/ui/value-source.ts +14 -0
- package/src/ui/virtual-window.ts +88 -9
- package/src/utils/canvas-media.ts +72 -0
- package/src/utils/edit-display.ts +7 -2
- package/src/utils/element-selectors.ts +69 -0
- package/src/utils/link-target.ts +2 -2
- package/src/utils/studio-utils.ts +0 -10
- package/src/view.ts +15 -0
- package/src/workspace/pane-derive.ts +36 -14
- package/src/workspace/workspace.ts +15 -6
- package/styles/canvas.css +72 -467
- package/styles/forced-colors.css +48 -82
- package/styles/forced-colors.json +41 -0
- package/styles/inspector.css +2 -1301
- package/styles/overlays.css +96 -2823
- package/styles/panels.css +6 -1423
- package/styles/shell-frame.css +272 -0
- package/styles/shell-frame.json +227 -0
- package/styles/shell.css +0 -1532
- package/styles/tokens.css +65 -136
- package/styles/tokens.json +84 -0
- package/dist/chunks/Overlay.dev-723bv0df.js +0 -23
- package/dist/chunks/adapter-jkcyhgtr.js +0 -14
- package/dist/chunks/cf-settings-45fgyx8y.js +0 -21
- package/dist/chunks/components-zmx10t62.js +0 -21
- package/dist/chunks/content-source-t88vb2dr.js +0 -49
- package/dist/chunks/convert-to-repeater-dhw1nrz9.js +0 -268
- package/dist/chunks/editor-cptq5jp1.js +0 -37
- package/dist/chunks/entry-commands-6z6bhxg0.js +0 -46
- package/dist/chunks/extension-sections-3ydgjbdy.js +0 -311
- package/dist/chunks/file-ops-rskmhxyq.js +0 -48
- package/dist/chunks/files-0cratsr0.js +0 -92
- package/dist/chunks/flow-qbfgrpeh.js +0 -634
- package/dist/chunks/focus-trap.esm-ggawf1hy.js +0 -1024
- package/dist/chunks/focus-visible-6eg70z18.js +0 -167
- package/dist/chunks/format-host-tgcmfs4p.js +0 -43
- package/dist/chunks/fs-events-hrrg328g.js +0 -21
- package/dist/chunks/git-panel-0yywyk76.js +0 -58
- package/dist/chunks/index-zqxmqxmh.js +0 -109
- package/dist/chunks/jx-validate-8q2g05x1.js +0 -19
- package/dist/chunks/layers-panel-z3tqe5cd.js +0 -67
- package/dist/chunks/layers-q75tj2mf.js +0 -45
- package/dist/chunks/lit-html-j055mkh8.js +0 -22
- package/dist/chunks/monaco-buffer-dqw0xxpx.js +0 -25
- package/dist/chunks/notify-yjm79n4s.js +0 -30
- package/dist/chunks/parse-24d0gay3.js +0 -19
- package/dist/chunks/platform-ba1j1gbh.js +0 -16
- package/dist/chunks/publish-panel-54jvhskq.js +0 -28
- package/dist/chunks/quick-search-cgfmjwq5.js +0 -65
- package/dist/chunks/references-3qx8fkyp.js +0 -29
- package/dist/chunks/right-panel-cqp8bc4v.js +0 -46
- package/dist/chunks/section-registry-sx1ykvkw.js +0 -30
- package/dist/chunks/sp-overlay.dev-yztmtrs1.js +0 -18
- package/dist/chunks/sp-popover.dev-n2etmqdp.js +0 -9
- package/dist/chunks/sp-progress-circle.dev-hryhj0es.js +0 -15
- package/dist/chunks/sp-tooltip.dev-xcvpnqr0.js +0 -15
- package/dist/chunks/sp-tray.dev-tkbscm06.js +0 -199
- package/dist/chunks/studio-0a5qrh01.js +0 -3
- package/dist/chunks/studio-18j3bmcz.js +0 -14
- package/dist/chunks/studio-1hbqnt19.js +0 -1823
- package/dist/chunks/studio-4rzyrtjz.js +0 -426
- package/dist/chunks/studio-5rywrkxz.js +0 -1903
- package/dist/chunks/studio-7afd21nw.js +0 -67
- package/dist/chunks/studio-7nte2hj4.js +0 -613
- package/dist/chunks/studio-8jpzqk5s.js +0 -128
- package/dist/chunks/studio-8q517dfr.js +0 -24
- package/dist/chunks/studio-9c4k4vhv.js +0 -357
- package/dist/chunks/studio-9n4mrmnb.js +0 -184
- package/dist/chunks/studio-a0tswy0w.js +0 -58
- package/dist/chunks/studio-ahjfdy6e.js +0 -387
- package/dist/chunks/studio-ahnzd9rg.js +0 -23
- package/dist/chunks/studio-bw5dz6km.js +0 -608
- package/dist/chunks/studio-cb12yz9w.js +0 -15055
- package/dist/chunks/studio-d1ks410h.js +0 -175
- package/dist/chunks/studio-eqq1w638.js +0 -113
- package/dist/chunks/studio-ex8zyp98.js +0 -1813
- package/dist/chunks/studio-h4rxscfc.js +0 -10
- package/dist/chunks/studio-kyh9avvv.js +0 -28
- package/dist/chunks/studio-kyk2v92a.js +0 -659
- package/dist/chunks/studio-m3hwn7y1.js +0 -120
- package/dist/chunks/studio-mmv72a27.js +0 -4344
- package/dist/chunks/studio-n8b9wqwy.js +0 -291
- package/dist/chunks/studio-pdfjntbk.js +0 -6939
- package/dist/chunks/studio-qq6jym04.js +0 -53
- package/dist/chunks/studio-r1r7afxx.js +0 -1066
- package/dist/chunks/studio-rdx8jcxy.js +0 -83
- package/dist/chunks/studio-rn9ta2mz.js +0 -111
- package/dist/chunks/studio-t7qb9db8.js +0 -665
- package/dist/chunks/studio-tmc5emrw.js +0 -8
- package/dist/chunks/studio-txwkm6p9.js +0 -12
- package/dist/chunks/studio-v38hmvx1.js +0 -390
- package/dist/chunks/studio-vadzgkrz.js +0 -318
- package/dist/chunks/studio-wx5609xd.js +0 -341
- package/dist/chunks/studio-z6nw2ek2.js +0 -18
- package/dist/chunks/studio-zczps70q.js +0 -378
- package/dist/chunks/workspace-xpres40v.js +0 -89
- package/src/panels/activity-bar.ts +0 -251
- package/src/panels/panel-scheduler.ts +0 -219
- package/src/panels/style-inputs.ts +0 -237
- package/src/panels/target-line.ts +0 -274
- package/src/panels/welcome-screen.ts +0 -346
- package/src/ui/button-group.ts +0 -102
- package/src/ui/choice-field.ts +0 -72
- package/src/ui/field-row.ts +0 -249
- package/src/ui/formula-palette.ts +0 -213
- package/src/ui/icons.ts +0 -52
- package/src/ui/jx-theme.ts +0 -130
- package/src/ui/spectrum.ts +0 -340
- package/src/ui/value-selector.ts +0 -174
- package/src/ui/widgets.ts +0 -172
- /package/dist/chunks/{javascript-s56a8dpk.css → javascript-4abzjcy9.css} +0 -0
- /package/dist/chunks/{jsonMode-zr9sw0c7.css → jsonMode-vvmpmk34.css} +0 -0
- /package/dist/chunks/{monaco-setup-pav68602.css → monaco-setup-8vbyqnhr.css} +0 -0
- /package/dist/chunks/{tsMode-ef187txx.css → tsMode-hnxxb73h.css} +0 -0
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
/**
|
|
3
|
+
* Start pane — the pane-grid surface shown when no project is loaded and no document tabs are open.
|
|
4
|
+
*
|
|
5
|
+
* Three regions, in the order a first run needs them: **Start** (the ways to get a project in front
|
|
6
|
+
* of you), **Recent** (projects you have opened, identified by name + the folder that tells two
|
|
7
|
+
* same-named projects apart + when you last opened them), and **Projects** (the catalogue a cloud
|
|
8
|
+
* platform enumerates). A repository-access prompt sits above them when the account has no GitHub
|
|
9
|
+
* App installation yet, because nothing else on the pane can succeed until it does.
|
|
10
|
+
*
|
|
11
|
+
* Recents never render a raw absolute path: `recentLocations()` gives every row the shortest
|
|
12
|
+
* trailing path that distinguishes it from the other rows sharing its name.
|
|
13
|
+
*
|
|
14
|
+
* The pane is the `welcome` surface (`surfaces/welcome.json`): this module is the projection —
|
|
15
|
+
* which start actions the platform offers, the recents with their labels, the catalogue minus the
|
|
16
|
+
* recents — and the four things a click can do. The scope is reactive, so a removed recent
|
|
17
|
+
* reconciles in place.
|
|
18
|
+
*
|
|
19
|
+
* @docs studio/interface/welcome-screen
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { getAccountStatus, needsAppInstall } from "../account-status";
|
|
23
|
+
import { platformSupportsAddRepo } from "../new-project/add-repo-modal";
|
|
24
|
+
import { getProjectList } from "../project-list";
|
|
25
|
+
import { reactive } from "../reactivity";
|
|
26
|
+
import { now } from "../services/clock";
|
|
27
|
+
import { clearRecentProjects, getRecentProjects, removeRecentProject } from "../recent-projects";
|
|
28
|
+
import { platformSupportsClone } from "../panels/git-panel";
|
|
29
|
+
import { mountSurface, registerSurface } from "../ui/surface";
|
|
30
|
+
import welcomeDoc from "./welcome.json";
|
|
31
|
+
import type { JxDocument } from "@jxsuite/schema/types";
|
|
32
|
+
import type { SurfaceHandle } from "../ui/surface";
|
|
33
|
+
|
|
34
|
+
registerSurface("welcome", welcomeDoc as unknown as JxDocument);
|
|
35
|
+
|
|
36
|
+
interface WelcomeCtx {
|
|
37
|
+
openProject: () => void;
|
|
38
|
+
openRecentProject: (root: string) => void;
|
|
39
|
+
openNewProject: (options?: { tab?: "starter" }) => void;
|
|
40
|
+
cloneRepository: () => void;
|
|
41
|
+
addExistingRepo: () => void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let _ctx: WelcomeCtx | null = null;
|
|
45
|
+
|
|
46
|
+
/** @param {WelcomeCtx} ctx */
|
|
47
|
+
export function initWelcome(ctx: WelcomeCtx) {
|
|
48
|
+
_ctx = ctx;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ─── Location labels ──────────────────────────────────────────────────────────
|
|
52
|
+
|
|
53
|
+
/** Home-relative form of an absolute path (`/home/you/x` → `~/x`); other paths are unchanged. */
|
|
54
|
+
export function shortenPath(path: string): string {
|
|
55
|
+
const match = /^\/(?:home|Users)\/[^/]+(?=\/|$)/.exec(path);
|
|
56
|
+
return match ? `~${path.slice(match[0].length)}` : path;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** The ancestor segments of a root, home-shortened — everything above the project folder itself. */
|
|
60
|
+
function ancestorSegments(root: string): string[] {
|
|
61
|
+
const segments = shortenPath(root).split("/").filter(Boolean);
|
|
62
|
+
return segments.slice(0, -1);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The last `depth` ancestor folders of a root, as a path. Truncated labels lead with `…/`; a
|
|
67
|
+
* complete absolute one keeps its leading `/`, so the string always says how much it is showing.
|
|
68
|
+
*/
|
|
69
|
+
function ancestorLabel(root: string, depth: number): string {
|
|
70
|
+
const segments = ancestorSegments(root);
|
|
71
|
+
if (segments.length === 0) {
|
|
72
|
+
return shortenPath(root);
|
|
73
|
+
}
|
|
74
|
+
const tail = segments.slice(Math.max(0, segments.length - depth));
|
|
75
|
+
if (tail.length < segments.length) {
|
|
76
|
+
return `…/${tail.join("/")}`;
|
|
77
|
+
}
|
|
78
|
+
return tail[0] === "~" || !root.startsWith("/") ? tail.join("/") : `/${tail.join("/")}`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The location line for each entry: the shortest trailing path that tells apart the entries sharing
|
|
83
|
+
* a display name. One folder deep is enough for almost every list; same-named projects under the
|
|
84
|
+
* same parent fall back to their whole home-shortened root, which is unique because roots are.
|
|
85
|
+
*
|
|
86
|
+
* @param entries Projects to label, in any order.
|
|
87
|
+
* @returns Root → location label, one entry per distinct root.
|
|
88
|
+
*/
|
|
89
|
+
export function recentLocations(
|
|
90
|
+
entries: readonly { name: string; root: string }[],
|
|
91
|
+
): Map<string, string> {
|
|
92
|
+
const groups = new Map<string, { name: string; root: string }[]>();
|
|
93
|
+
for (const entry of entries) {
|
|
94
|
+
const group = groups.get(entry.name);
|
|
95
|
+
if (group) {
|
|
96
|
+
group.push(entry);
|
|
97
|
+
} else {
|
|
98
|
+
groups.set(entry.name, [entry]);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const labels = new Map<string, string>();
|
|
103
|
+
for (const group of groups.values()) {
|
|
104
|
+
const maxDepth = Math.max(...group.map((e) => ancestorSegments(e.root).length), 1);
|
|
105
|
+
let chosen = group.map((e) => ancestorLabel(e.root, maxDepth));
|
|
106
|
+
for (let depth = 1; depth <= maxDepth; depth++) {
|
|
107
|
+
const candidate = group.map((e) => ancestorLabel(e.root, depth));
|
|
108
|
+
if (new Set(candidate).size === group.length) {
|
|
109
|
+
chosen = candidate;
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (new Set(chosen).size !== group.length) {
|
|
114
|
+
chosen = group.map((e) => shortenPath(e.root));
|
|
115
|
+
}
|
|
116
|
+
for (const [index, entry] of group.entries()) {
|
|
117
|
+
labels.set(entry.root, chosen[index]!);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return labels;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const MINUTE = 60_000;
|
|
124
|
+
const HOUR = 60 * MINUTE;
|
|
125
|
+
const DAY = 24 * HOUR;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* "When you last opened it", in the coarse units a project list is read in. Deliberately vague past
|
|
129
|
+
* a week — the exact timestamp is in the row's tooltip.
|
|
130
|
+
*
|
|
131
|
+
* @param timestamp Epoch milliseconds.
|
|
132
|
+
* @param at Epoch milliseconds to measure against. Defaults to the {@link now} seam, so a pinned
|
|
133
|
+
* clock makes "last opened" answer the same on every read.
|
|
134
|
+
*/
|
|
135
|
+
export function lastOpenedLabel(timestamp: number, at: number = now()): string {
|
|
136
|
+
const elapsed = Math.max(0, at - timestamp);
|
|
137
|
+
if (elapsed < MINUTE) {
|
|
138
|
+
return "just now";
|
|
139
|
+
}
|
|
140
|
+
if (elapsed < HOUR) {
|
|
141
|
+
const minutes = Math.floor(elapsed / MINUTE);
|
|
142
|
+
return `${minutes} minute${minutes === 1 ? "" : "s"} ago`;
|
|
143
|
+
}
|
|
144
|
+
if (elapsed < DAY) {
|
|
145
|
+
const hours = Math.floor(elapsed / HOUR);
|
|
146
|
+
return `${hours} hour${hours === 1 ? "" : "s"} ago`;
|
|
147
|
+
}
|
|
148
|
+
const days = Math.floor(elapsed / DAY);
|
|
149
|
+
if (days === 1) {
|
|
150
|
+
return "yesterday";
|
|
151
|
+
}
|
|
152
|
+
if (days < 30) {
|
|
153
|
+
return `${days} days ago`;
|
|
154
|
+
}
|
|
155
|
+
const months = Math.floor(days / 30);
|
|
156
|
+
return months < 12 ? `${months} month${months === 1 ? "" : "s"} ago` : "over a year ago";
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ─── The surface ──────────────────────────────────────────────────────────────
|
|
160
|
+
|
|
161
|
+
/** One Start-list action: a labelled, icon-led button, run through `run`. */
|
|
162
|
+
interface StartAction {
|
|
163
|
+
id: "new" | "open" | "clone" | "add";
|
|
164
|
+
title: string;
|
|
165
|
+
icon: string;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
interface RecentRow {
|
|
169
|
+
root: string;
|
|
170
|
+
name: string;
|
|
171
|
+
location: string;
|
|
172
|
+
when: string;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
interface CatalogueRow {
|
|
176
|
+
root: string;
|
|
177
|
+
name: string;
|
|
178
|
+
detail: string;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
interface WelcomeScope extends Record<string, unknown> {
|
|
182
|
+
actions: StartAction[];
|
|
183
|
+
installNeeded: boolean;
|
|
184
|
+
installUrl: string;
|
|
185
|
+
hasRecent: boolean;
|
|
186
|
+
recent: RecentRow[];
|
|
187
|
+
hasCatalogue: boolean;
|
|
188
|
+
catalogue: CatalogueRow[];
|
|
189
|
+
run: (id: string) => void;
|
|
190
|
+
open: (root: string) => void;
|
|
191
|
+
remove: (root: string) => void;
|
|
192
|
+
clear: () => void;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
let _state: WelcomeScope | null = null;
|
|
196
|
+
let _host: HTMLElement | null = null;
|
|
197
|
+
let _mount: Promise<SurfaceHandle> | null = null;
|
|
198
|
+
let _handle: SurfaceHandle | null = null;
|
|
199
|
+
|
|
200
|
+
/** The pane, as the surface reads it, from the platform and the stores as they stand now. */
|
|
201
|
+
function project(): Omit<WelcomeScope, "run" | "open" | "remove" | "clear"> {
|
|
202
|
+
const recent = getRecentProjects();
|
|
203
|
+
// Catalogue entries already in Recent stay in that section only.
|
|
204
|
+
const catalogue = getProjectList().filter((p) => !recent.some((r) => r.root === p.root));
|
|
205
|
+
const recentLabels = recentLocations(recent);
|
|
206
|
+
const catalogueLabels = recentLocations(catalogue);
|
|
207
|
+
const actions: StartAction[] = [
|
|
208
|
+
// One entry, not two: the starter gallery IS the first step of New Project now, so the
|
|
209
|
+
// Separate "Start from an Example…" button it used to hide behind is gone.
|
|
210
|
+
{ icon: "plus", id: "new", title: "New Project…" },
|
|
211
|
+
{ icon: "folder-open", id: "open", title: "Open Project…" },
|
|
212
|
+
...(platformSupportsClone()
|
|
213
|
+
? [{ icon: "download-simple", id: "clone", title: "Clone Git Repository…" } as const]
|
|
214
|
+
: []),
|
|
215
|
+
...(platformSupportsAddRepo()
|
|
216
|
+
? [{ icon: "cube", id: "add", title: "Add Existing Repository…" } as const]
|
|
217
|
+
: []),
|
|
218
|
+
];
|
|
219
|
+
return {
|
|
220
|
+
actions,
|
|
221
|
+
catalogue: catalogue.map((entry) => ({
|
|
222
|
+
detail: entry.description ?? catalogueLabels.get(entry.root) ?? entry.root,
|
|
223
|
+
name: entry.name,
|
|
224
|
+
root: entry.root,
|
|
225
|
+
})),
|
|
226
|
+
hasCatalogue: catalogue.length > 0,
|
|
227
|
+
hasRecent: recent.length > 0,
|
|
228
|
+
/* The GitHub-App install prompt, gated on `needsAppInstall()`: the account is connected,
|
|
229
|
+
reports zero installations, and told us where to fix that — the recovery path for the
|
|
230
|
+
structured needs-installation 403 that `platform-errors.ts` decodes. */
|
|
231
|
+
installNeeded: needsAppInstall(),
|
|
232
|
+
installUrl: getAccountStatus()?.appInstallUrl ?? "#",
|
|
233
|
+
recent: recent.map((entry) => ({
|
|
234
|
+
location: recentLabels.get(entry.root) ?? entry.root,
|
|
235
|
+
name: entry.name,
|
|
236
|
+
root: entry.root,
|
|
237
|
+
when: lastOpenedLabel(entry.timestamp),
|
|
238
|
+
})),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/** The reactive scope the surface reads, made once. */
|
|
243
|
+
function state(): WelcomeScope {
|
|
244
|
+
_state ??= reactive({
|
|
245
|
+
actions: [],
|
|
246
|
+
catalogue: [],
|
|
247
|
+
clear: () => {
|
|
248
|
+
clearRecentProjects();
|
|
249
|
+
refresh();
|
|
250
|
+
},
|
|
251
|
+
hasCatalogue: false,
|
|
252
|
+
hasRecent: false,
|
|
253
|
+
installNeeded: false,
|
|
254
|
+
installUrl: "#",
|
|
255
|
+
open: (root: string) => {
|
|
256
|
+
_ctx?.openRecentProject(root);
|
|
257
|
+
},
|
|
258
|
+
recent: [],
|
|
259
|
+
remove: (root: string) => {
|
|
260
|
+
removeRecentProject(root);
|
|
261
|
+
refresh();
|
|
262
|
+
},
|
|
263
|
+
run: (id: string) => {
|
|
264
|
+
switch (id) {
|
|
265
|
+
case "new": {
|
|
266
|
+
_ctx?.openNewProject();
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
case "open": {
|
|
270
|
+
_ctx?.openProject();
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
case "clone": {
|
|
274
|
+
_ctx?.cloneRepository();
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
case "add": {
|
|
278
|
+
_ctx?.addExistingRepo();
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
default: {
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
}) as WelcomeScope;
|
|
287
|
+
return _state;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/** Recompute the projection; the surface follows. */
|
|
291
|
+
function refresh(): void {
|
|
292
|
+
Object.assign(state(), project());
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Draw the pane into `host`, or bring the one already there up to date.
|
|
297
|
+
*
|
|
298
|
+
* The canvas calls this on every render while nothing is open, into the same wrap it clears when
|
|
299
|
+
* something opens — so a mount whose root has since left the document is disposed and remade, and
|
|
300
|
+
* one still standing is only refreshed.
|
|
301
|
+
*
|
|
302
|
+
* @param {HTMLElement} host
|
|
303
|
+
*/
|
|
304
|
+
export function renderWelcome(host: HTMLElement): void {
|
|
305
|
+
refresh();
|
|
306
|
+
const standing = _host === host && _handle !== null && _handle.root.isConnected;
|
|
307
|
+
if (standing) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (_mount && _host === host && !_handle) {
|
|
311
|
+
// Still mounting into this very host.
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
disposeWelcome();
|
|
315
|
+
_host = host;
|
|
316
|
+
const pending = mountSurface("welcome", state(), host);
|
|
317
|
+
_mount = pending;
|
|
318
|
+
void pending.then((handle) => {
|
|
319
|
+
if (_mount === pending) {
|
|
320
|
+
_handle = handle;
|
|
321
|
+
} else {
|
|
322
|
+
handle.dispose();
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/** Take the pane down and forget its host. */
|
|
328
|
+
export function disposeWelcome(): void {
|
|
329
|
+
const pending = _mount;
|
|
330
|
+
_mount = null;
|
|
331
|
+
if (_handle) {
|
|
332
|
+
_handle.dispose();
|
|
333
|
+
_handle = null;
|
|
334
|
+
} else if (pending) {
|
|
335
|
+
void pending.then((handle) => handle.dispose());
|
|
336
|
+
}
|
|
337
|
+
_host = null;
|
|
338
|
+
}
|
|
@@ -33,18 +33,24 @@
|
|
|
33
33
|
* from the other side: a config that reached disk without passing through here (the assistant's
|
|
34
34
|
* `write_file`) is put INTO the document rather than left beside it as a rival.
|
|
35
35
|
*
|
|
36
|
-
* **One serialisation.** {@link serializeProjectConfig} is `
|
|
37
|
-
* byte-for-byte what `files/
|
|
38
|
-
* settings edit produce the same file. The predecessor
|
|
39
|
-
* `"\t"` in both `settings/contributed-section.ts` and
|
|
40
|
-
* edit re-indented the entire file — every `project.json`
|
|
41
|
-
* spaces.
|
|
36
|
+
* **One serialisation.** {@link serializeProjectConfig} is `files/json-layout.ts`'s serializer over
|
|
37
|
+
* the layout the file was read in — byte-for-byte what `files/serialize-document.ts`'s native-JSON
|
|
38
|
+
* branch writes, so a ⌘S on the open tab and a settings edit produce the same file. The predecessor
|
|
39
|
+
* had `null, 2` in `site-context.ts` and `"\t"` in both `settings/contributed-section.ts` and
|
|
40
|
+
* `settings/defs-editor.ts`, so a settings edit re-indented the entire file — every `project.json`
|
|
41
|
+
* in this repository is on disk with two spaces. It was then `JSON.stringify(config, null, 2)`,
|
|
42
|
+
* which agreed with the tab's save and disagreed with the formatter: a one-field edit re-laid every
|
|
43
|
+
* short array in the file (issue 308).
|
|
42
44
|
*
|
|
43
45
|
* **A no-op edit writes nothing.** A form that re-commits the value it already holds — and every
|
|
44
46
|
* one of these surfaces has such a path — used to rewrite the whole file. A commit now compares the
|
|
45
47
|
* serialised result against what the file itself says and returns without a transaction, without a
|
|
46
48
|
* write, and therefore with an empty diff.
|
|
47
49
|
*
|
|
50
|
+
* **A real edit is a one-line diff.** The file's layout — which objects sit on one line, where a
|
|
51
|
+
* blank line falls — is read once per binding ({@link seedCommitted}) and every serialisation here
|
|
52
|
+
* honours it, so what changes on disk is the field that changed.
|
|
53
|
+
*
|
|
48
54
|
* **Collaboration.** `project.json` is out of collab replication; the gate is in
|
|
49
55
|
* `collab/collab-session.ts`'s `ensureCollab`, which is what would otherwise register the Yjs
|
|
50
56
|
* history delegate over this tab.
|
|
@@ -58,6 +64,8 @@ import { requireProjectState, setProjectState } from "../state";
|
|
|
58
64
|
import { setWorkspaceProject, workspace } from "../workspace/workspace";
|
|
59
65
|
import { PROJECT_CONFIG_PATH, createTab, disposeTab } from "./tab";
|
|
60
66
|
import { transactDoc } from "./transact";
|
|
67
|
+
import { parseJsonDocument, serializeJson } from "../files/json-layout";
|
|
68
|
+
import type { JsonLayout } from "../files/json-layout";
|
|
61
69
|
|
|
62
70
|
import type { Tab } from "./tab";
|
|
63
71
|
import type { ProjectConfig } from "@jxsuite/schema/types";
|
|
@@ -67,15 +75,16 @@ export { PROJECT_CONFIG_PATH } from "./tab";
|
|
|
67
75
|
/**
|
|
68
76
|
* The project configuration, as a file.
|
|
69
77
|
*
|
|
70
|
-
* The ONE serialisation. Identical to the native-JSON branch of `files/
|
|
78
|
+
* The ONE serialisation. Identical to the native-JSON branch of `files/serialize-document.ts`'s
|
|
71
79
|
* `serializeDocument`, which is what ⌘S on the open `project.json` tab goes through — the two must
|
|
72
|
-
* agree or every save would fight the last one.
|
|
80
|
+
* agree or every save would fight the last one. Both honour the layout the file was read in ({@link
|
|
81
|
+
* configLayout}); with none known, the formatter's layout for fresh output.
|
|
73
82
|
*
|
|
74
83
|
* @param {ProjectConfig} config
|
|
75
84
|
* @returns {string}
|
|
76
85
|
*/
|
|
77
86
|
export function serializeProjectConfig(config: ProjectConfig): string {
|
|
78
|
-
return
|
|
87
|
+
return serializeJson(config, configLayout());
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
// ─── The document of record ───────────────────────────────────────────────────
|
|
@@ -94,15 +103,34 @@ let _detached: Tab | null = null;
|
|
|
94
103
|
* variables editor writes into `config.style` and then hands the same object over as a patch. A
|
|
95
104
|
* value taken from memory would call every one of those edits a no-op.
|
|
96
105
|
*
|
|
97
|
-
* Comparing two
|
|
98
|
-
* not a textual one, which is the point: `project.json`
|
|
99
|
-
*
|
|
100
|
-
*
|
|
106
|
+
* Comparing two renderings of the same key order through the same serializer is a SEMANTIC test,
|
|
107
|
+
* not a textual one, which is the point: a `project.json` formatted some other way than the
|
|
108
|
+
* serializer would lay it out — every array expanded, say — would otherwise look changed on every
|
|
109
|
+
* commit, and a byte comparison against the file would rewrite it whole. This calls it unchanged
|
|
110
|
+
* and writes nothing.
|
|
101
111
|
*
|
|
102
112
|
* `null` means "unknown" — no project file, or one that would not parse — and every commit writes.
|
|
103
113
|
*/
|
|
104
114
|
let _committed: string | null = null;
|
|
105
115
|
|
|
116
|
+
/**
|
|
117
|
+
* The layout the file was read in ({@link seedCommitted}), for a binding with no open tab to carry
|
|
118
|
+
* it. Reset with the binding: a different project is a different file.
|
|
119
|
+
*/
|
|
120
|
+
let _layout: JsonLayout | null = null;
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* The layout a configuration write honours.
|
|
124
|
+
*
|
|
125
|
+
* The open tab's, when there is one — it read the file when it opened, or was lent the seed's
|
|
126
|
+
* record ({@link lendProjectConfigLayout}), and a source-view commit or a reload from disk keeps it
|
|
127
|
+
* current — and otherwise what the seed read. The two describe the same file, so the choice only
|
|
128
|
+
* matters for freshness, and the tab is the fresher.
|
|
129
|
+
*/
|
|
130
|
+
function configLayout(): JsonLayout | null {
|
|
131
|
+
return openConfigTab()?.doc.layout ?? _layout;
|
|
132
|
+
}
|
|
133
|
+
|
|
106
134
|
/** Whether {@link _committed} has been sought for the current binding. One read per project. */
|
|
107
135
|
let _seeding: Promise<void> | null = null;
|
|
108
136
|
|
|
@@ -126,6 +154,7 @@ function unbind(): void {
|
|
|
126
154
|
}
|
|
127
155
|
_bound = null;
|
|
128
156
|
_committed = null;
|
|
157
|
+
_layout = null;
|
|
129
158
|
_seeding = null;
|
|
130
159
|
}
|
|
131
160
|
|
|
@@ -134,7 +163,9 @@ function seedCommitted(): Promise<void> {
|
|
|
134
163
|
_seeding ??= (async () => {
|
|
135
164
|
try {
|
|
136
165
|
const text = await getPlatform().readFile(PROJECT_CONFIG_PATH);
|
|
137
|
-
|
|
166
|
+
const { document, layout } = parseJsonDocument(text);
|
|
167
|
+
_layout = layout;
|
|
168
|
+
_committed = serializeProjectConfig(document as unknown as ProjectConfig);
|
|
138
169
|
} catch {
|
|
139
170
|
// No file, an unreadable one, or one that does not parse. "Unknown" is the honest answer,
|
|
140
171
|
// And an unknown file is one every commit must write.
|
|
@@ -144,6 +175,29 @@ function seedCommitted(): Promise<void> {
|
|
|
144
175
|
return _seeding;
|
|
145
176
|
}
|
|
146
177
|
|
|
178
|
+
/**
|
|
179
|
+
* Lend the file's layout to `tab` when it has none of its own.
|
|
180
|
+
*
|
|
181
|
+
* The Settings door (`settings/settings-document.ts`) opens the `project.json` tab over the
|
|
182
|
+
* configuration object the project was loaded with — an object the platform parsed, with no text
|
|
183
|
+
* behind it — so that tab arrives with `doc.layout === null`. Left there, a ⌘S on it would write
|
|
184
|
+
* the formatter's layout for fresh output while a settings commit on the SAME document wrote the
|
|
185
|
+
* file's: every short object in the file blown open by the save the settings edit had just kept,
|
|
186
|
+
* which is the one disagreement this module exists to make impossible. The file is read once per
|
|
187
|
+
* binding anyway ({@link seedCommitted}); this hands the record that read made to the tab, and
|
|
188
|
+
* {@link configLayout} then takes it back from the tab like every other writer. A tab that read the
|
|
189
|
+
* file itself — the Files tree, a reload, a source-view commit — keeps the fresher record it has.
|
|
190
|
+
*
|
|
191
|
+
* @param {Tab} tab
|
|
192
|
+
* @returns {Promise<void>}
|
|
193
|
+
*/
|
|
194
|
+
export async function lendProjectConfigLayout(tab: Tab): Promise<void> {
|
|
195
|
+
await seedCommitted();
|
|
196
|
+
if (tab.doc.layout === null && _layout !== null) {
|
|
197
|
+
tab.doc.layout = _layout;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
147
201
|
/**
|
|
148
202
|
* Forget the configuration document — the project-switch and test hook.
|
|
149
203
|
*
|
|
@@ -307,7 +361,9 @@ export async function commitProjectConfig(
|
|
|
307
361
|
// Tab's own parse, and the caller has already mutated the object it rendered from.
|
|
308
362
|
const live = liveConfig();
|
|
309
363
|
const tab = projectConfigDocument();
|
|
310
|
-
|
|
364
|
+
// The seed, and the record it read handed to the document — so the tab the Settings door opened
|
|
365
|
+
// Writes the same bytes from ⌘S that this commit is about to.
|
|
366
|
+
await lendProjectConfigLayout(tab);
|
|
311
367
|
const current = toRaw(tab.doc.document) as unknown as ProjectConfig;
|
|
312
368
|
const currentText = serializeProjectConfig(current);
|
|
313
369
|
|
package/src/tabs/tab.ts
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
import { effectScope, reactive } from "../reactivity";
|
|
3
3
|
import { formatByName, formatForPath } from "../format/format-host";
|
|
4
4
|
import { normalizeArrayChildren } from "../state";
|
|
5
|
+
import type { JxPath } from "../state";
|
|
5
6
|
import type { FormulaEditDef, FunctionEditDef, InlineEditDef, JsonValue } from "../types";
|
|
6
7
|
import { editorKindForMode } from "../commands/context";
|
|
7
8
|
import type { EditorKind } from "../commands/context";
|
|
8
9
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
9
10
|
import type { JxDocOp, JxFmOp } from "./patch-ops";
|
|
11
|
+
import type { JsonLayout } from "../files/json-layout";
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* The project's configuration file, project-relative.
|
|
@@ -39,6 +41,29 @@ export interface TabUi {
|
|
|
39
41
|
editZoom: number;
|
|
40
42
|
activeMedia: string | null;
|
|
41
43
|
activeSelector: string | null;
|
|
44
|
+
/**
|
|
45
|
+
* The popover the canvas is drawing OPEN, by document path, or null for none.
|
|
46
|
+
*
|
|
47
|
+
* Per tab rather than per pane, beside `activeMedia` and `previewColorScheme`, because it is a
|
|
48
|
+
* fact about a DOCUMENT's elements: two panes showing the same tab show the same open panel,
|
|
49
|
+
* which is correct — it is the same element.
|
|
50
|
+
*
|
|
51
|
+
* Exactly one, never a set. Several de-popovered panels in flow at once would shove the page
|
|
52
|
+
* around and make the canvas unreadable; native `popover="auto"` already enforces a single stack,
|
|
53
|
+
* so a set would model something the platform does not have; and "exactly one" makes the
|
|
54
|
+
* open-on-selection rule total, with no ordering decision to make.
|
|
55
|
+
*
|
|
56
|
+
* A VIEW state — it writes nothing to the document, so it takes no undo entry, does not dirty the
|
|
57
|
+
* tab and is not replicated over collaboration. It is also deliberately not restored with a
|
|
58
|
+
* session (§14.8): reopening a project with a modal spread across the page is a worse first frame
|
|
59
|
+
* than reopening it closed.
|
|
60
|
+
*/
|
|
61
|
+
openPopover: JxPath | null;
|
|
62
|
+
/**
|
|
63
|
+
* The `<dialog>` the canvas draws open in place, per tab and exactly one; view state like
|
|
64
|
+
* `openPopover`.
|
|
65
|
+
*/
|
|
66
|
+
openDialog: JxPath | null;
|
|
42
67
|
editingFunction: FunctionEditDef | null;
|
|
43
68
|
/** Logic-tab formula target ($expression editing); editingFunction wins if both are set. */
|
|
44
69
|
editingFormula: FormulaEditDef | null;
|
|
@@ -161,6 +186,18 @@ export interface Tab {
|
|
|
161
186
|
sourceFormat: string | null;
|
|
162
187
|
handlersSource: string | null;
|
|
163
188
|
dirty: boolean;
|
|
189
|
+
/**
|
|
190
|
+
* The layout the document's JSON file was written in (`files/json-layout.ts`), or null for a
|
|
191
|
+
* document with no JSON source — a format-class file, a new document, a stub.
|
|
192
|
+
*
|
|
193
|
+
* On the document record because it is a fact about the FILE the document came from, and it
|
|
194
|
+
* lives exactly as long as that fact does: every edit leaves it alone (the pointers it is keyed
|
|
195
|
+
* by survive a changed value, a new sibling, a removed one), a reload from disk or a
|
|
196
|
+
* source-view commit replaces it with the layout of the text just read, and opening a different
|
|
197
|
+
* file makes a new tab. The history ring never snapshots it — undo restores a document, not a
|
|
198
|
+
* file.
|
|
199
|
+
*/
|
|
200
|
+
layout: JsonLayout | null;
|
|
164
201
|
};
|
|
165
202
|
session: {
|
|
166
203
|
/**
|
|
@@ -216,6 +253,8 @@ function createDefaultUi(canvasMode: string, preview = false) {
|
|
|
216
253
|
return {
|
|
217
254
|
activeMedia: null,
|
|
218
255
|
activeSelector: null,
|
|
256
|
+
openPopover: null,
|
|
257
|
+
openDialog: null,
|
|
219
258
|
canvasMode,
|
|
220
259
|
editZoom: 1,
|
|
221
260
|
editingFormula: null,
|
|
@@ -239,7 +278,15 @@ function createDefaultUi(canvasMode: string, preview = false) {
|
|
|
239
278
|
};
|
|
240
279
|
}
|
|
241
280
|
|
|
242
|
-
|
|
281
|
+
/*
|
|
282
|
+
* `git-diff` is here because a comparison is a MODE of a document, and until now nothing said so.
|
|
283
|
+
* The Source Control panel reached it through the injected `setCanvasMode`, which performs no
|
|
284
|
+
* capability check — so the mode worked while `editorKindsOf` could never report `diff`, the Editor
|
|
285
|
+
* picker could never offer it, and `canvas.setMode { mode: "git-diff" }` threw for every document in
|
|
286
|
+
* the project. Declaring it makes the palette, the assistant and the screenshot runner able to open
|
|
287
|
+
* a comparison by name, and puts Diff on the Editor axis where §18.4 already says it belongs.
|
|
288
|
+
*/
|
|
289
|
+
const ALL_MODES = ["edit", "design", "preview", "source", "stylebook", "git-diff"];
|
|
243
290
|
|
|
244
291
|
/**
|
|
245
292
|
* Create a new tab with reactive doc/session/history trees, owned by an effectScope.
|
|
@@ -254,6 +301,7 @@ const ALL_MODES = ["edit", "design", "preview", "source", "stylebook"];
|
|
|
254
301
|
* capabilities?: { modes?: string[] };
|
|
255
302
|
* openedFrom?: TabOrigin | null;
|
|
256
303
|
* preview?: boolean;
|
|
304
|
+
* layout?: JsonLayout | null;
|
|
257
305
|
* }} opts
|
|
258
306
|
* @returns {Tab}
|
|
259
307
|
*/
|
|
@@ -267,6 +315,7 @@ export function createTab({
|
|
|
267
315
|
capabilities,
|
|
268
316
|
openedFrom = null,
|
|
269
317
|
preview: previewTab = false,
|
|
318
|
+
layout = null,
|
|
270
319
|
}: {
|
|
271
320
|
id: string;
|
|
272
321
|
documentPath?: string | null;
|
|
@@ -277,6 +326,7 @@ export function createTab({
|
|
|
277
326
|
capabilities?: { modes?: string[] };
|
|
278
327
|
openedFrom?: TabOrigin | null;
|
|
279
328
|
preview?: boolean;
|
|
329
|
+
layout?: JsonLayout | null;
|
|
280
330
|
}) {
|
|
281
331
|
const scope = effectScope();
|
|
282
332
|
|
|
@@ -299,6 +349,7 @@ export function createTab({
|
|
|
299
349
|
dirty: false,
|
|
300
350
|
document,
|
|
301
351
|
handlersSource: null,
|
|
352
|
+
layout,
|
|
302
353
|
mode: inferDocumentMode(documentPath, sourceFormat),
|
|
303
354
|
sourceFormat,
|
|
304
355
|
}),
|