@jxsuite/studio 6.1.2 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/chunks/2020-5wtzce5g.js +4 -0
- package/dist/chunks/adapter-5tphg7xe.js +4 -0
- package/dist/chunks/add-new-flow-psym14sn.js +4 -0
- package/dist/chunks/cf-account-picker-haqazq5r.js +4 -0
- package/dist/chunks/cf-settings-h2wrh6hq.js +4 -0
- package/dist/chunks/{color-area-0fj8a4ga.js → color-area-6rbra5dy.js} +2 -2
- package/dist/chunks/{color-field-xch8kx2g.js → color-field-gy56c94g.js} +3 -3
- package/dist/chunks/color-m7r1vk54.js +4 -0
- package/dist/chunks/{color-slider-jxd8v350.js → color-slider-sqqdyf6c.js} +2 -2
- package/dist/chunks/{combobox-p0efwjke.js → combobox-72h32ejk.js} +3 -3
- package/dist/chunks/components-r22xca09.js +4 -0
- package/dist/chunks/content-source-mmppmcyg.js +4 -0
- package/dist/chunks/convert-to-repeater-he70fc2b.js +4 -0
- package/dist/chunks/editor-ccd9jwsa.js +4 -0
- package/dist/chunks/entry-commands-6qxz9e8p.js +4 -0
- package/dist/chunks/extension-sections-0egb88dm.js +4 -0
- package/dist/chunks/file-ops-qnab36ek.js +4 -0
- package/dist/chunks/files-rcn56qvm.js +4 -0
- package/dist/chunks/format-host-yxz0kjjs.js +4 -0
- package/dist/chunks/fs-events-d1qxq4z4.js +4 -0
- package/dist/chunks/grid-open-4z1g062t.js +4 -0
- package/dist/chunks/{grid-view-d2wq9ezg.js → grid-view-qg1b5eqx.js} +25 -25
- package/dist/chunks/{icons-pnfz478q.js → icons-63bjtbs7.js} +2 -2
- package/dist/chunks/{iframe-entry-jdcktez8.js → iframe-entry-2zggzajv.js} +4 -4
- package/dist/chunks/{iframe-entry-zap785cw.js → iframe-entry-76j8vwwx.js} +4 -4
- package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
- package/dist/chunks/{iframe-entry-x0ygf2yr.js → iframe-entry-pkgmcgp0.js} +4 -4
- package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
- package/dist/chunks/{index-zpjmzqfk.js → index-32eqzv1k.js} +3 -3
- package/dist/chunks/index-f0jn7nnp.js +4 -0
- package/dist/chunks/{javascript-m54mnwp6.js → javascript-pjp734q4.js} +3 -3
- package/dist/chunks/jsonMode-njkvsa02.js +13 -0
- package/dist/chunks/jx-validate-ttasrbh7.js +4 -0
- package/dist/chunks/layers-bgyr11tr.js +4 -0
- package/dist/chunks/layers-panel-7ez66zeq.js +4 -0
- package/dist/chunks/{listbox-e74qjyq6.js → listbox-c421cf8c.js} +2 -2
- package/dist/chunks/lit-html-v9gh687x.js +4 -0
- package/dist/chunks/media-library-sq468wts.js +4 -0
- package/dist/chunks/media-picker-shfe59pt.js +4 -0
- package/dist/chunks/{menu-n6yzswmy.js → menu-bdpzbfvs.js} +2 -2
- package/dist/chunks/{monaco-binding-7gx83x3r.js → monaco-binding-vq1hgnn0.js} +3 -3
- package/dist/chunks/monaco-buffer-3afgwvbp.js +4 -0
- package/dist/chunks/monaco-setup-xrd2cbkp.js +4 -0
- package/dist/chunks/notify-kzrjr3fv.js +4 -0
- package/dist/chunks/parse-v77xtwv7.js +4 -0
- package/dist/chunks/platform-7v4rtd7m.js +4 -0
- package/dist/chunks/popover-b89sfej7.js +4 -0
- package/dist/chunks/publish-panel-2z9gw8ee.js +4 -0
- package/dist/chunks/publish-quick-qx2455cj.js +4 -0
- package/dist/chunks/publish-workspace-wrc1dgwx.js +4 -0
- package/dist/chunks/quick-search-n0t0eqxb.js +4 -0
- package/dist/chunks/references-9547rg5s.js +4 -0
- package/dist/chunks/right-panel-wsgnr9pn.js +4 -0
- package/dist/chunks/source-control-kwktr9y6.js +4 -0
- package/dist/chunks/{split-n2gfpm5m.js → split-c9zfdgxf.js} +2 -2
- package/dist/chunks/studio-03ct6yfv.js +9 -0
- package/dist/chunks/studio-07rcfje3.js +5 -0
- package/dist/chunks/studio-3e54qh39.js +7 -0
- package/dist/chunks/studio-3exxhz5g.js +5 -0
- package/dist/chunks/studio-3q40e3rj.js +5 -0
- package/dist/chunks/studio-3qeh9t0h.js +6 -0
- package/dist/chunks/studio-3qqjeep5.js +6 -0
- package/dist/chunks/studio-43sd2mam.js +4 -0
- package/dist/chunks/studio-4hp8pkyt.js +5 -0
- package/dist/chunks/studio-58xg6j2q.js +9 -0
- package/dist/chunks/studio-5g0rprdt.js +7 -0
- package/dist/chunks/{studio-2j1cb95x.js → studio-6m380wp7.js} +4 -4
- package/dist/chunks/studio-80jyh1xh.js +4 -0
- package/dist/chunks/studio-83mk4bgg.js +9 -0
- package/dist/chunks/{studio-v0jzqdjm.js → studio-881z1xrx.js} +4 -4
- package/dist/chunks/studio-8m0y2qe7.js +5 -0
- package/dist/chunks/{studio-d81xfh1g.js → studio-8tr6cfrc.js} +4 -4
- package/dist/chunks/studio-8vcvfs7r.js +6 -0
- package/dist/chunks/studio-9tmebf0s.js +5 -0
- package/dist/chunks/studio-a2bvaptz.js +5 -0
- package/dist/chunks/studio-b7y5mr30.js +5 -0
- package/dist/chunks/studio-bavb31r0.js +5 -0
- package/dist/chunks/{studio-dgz8d0c1.js → studio-bbe4c90a.js} +4 -4
- package/dist/chunks/studio-c05wdnt3.js +5 -0
- package/dist/chunks/studio-ccv2svc6.js +5 -0
- package/dist/chunks/studio-d5grtb9e.js +16 -0
- package/dist/chunks/studio-df0baea9.js +5 -0
- package/dist/chunks/studio-dgk4dqtx.js +7 -0
- package/dist/chunks/studio-e1g64q43.js +5 -0
- package/dist/chunks/studio-ed1hp6zf.js +6 -0
- package/dist/chunks/studio-ed3xx40h.js +7 -0
- package/dist/chunks/studio-f14e1zdj.js +5 -0
- package/dist/chunks/studio-fbhxxc5f.js +5 -0
- package/dist/chunks/studio-fyh0jc96.js +5 -0
- package/dist/chunks/studio-gcxk20n7.js +5 -0
- package/dist/chunks/studio-jaaz8ce9.js +5 -0
- package/dist/chunks/{studio-90pq9km1.js → studio-jcnsdaep.js} +4 -4
- package/dist/chunks/studio-jsgf2q5k.js +7 -0
- package/dist/chunks/{studio-0q988f9w.js → studio-k3xxbagr.js} +3 -3
- package/dist/chunks/{studio-5ve6bbep.js → studio-k7evxqh4.js} +4 -4
- package/dist/chunks/studio-kt3pjkwd.js +5 -0
- package/dist/chunks/studio-m8g16bgz.js +5 -0
- package/dist/chunks/studio-mn0476ag.js +5 -0
- package/dist/chunks/studio-mx1smyq0.js +5 -0
- package/dist/chunks/studio-n0c5h6mf.js +5 -0
- package/dist/chunks/{studio-485046te.js → studio-nh6d342n.js} +7 -7
- package/dist/chunks/studio-nqxqf8p2.js +4 -0
- package/dist/chunks/studio-p4nrkvqr.js +5 -0
- package/dist/chunks/{studio-1fxkaaea.js → studio-pbxa5fpc.js} +4 -4
- package/dist/chunks/studio-pgmvdv7z.js +7 -0
- package/dist/chunks/studio-ph84avkf.js +5 -0
- package/dist/chunks/{studio-tq0rtfwj.js → studio-q0mvbaq6.js} +4 -4
- package/dist/chunks/studio-q0tccd43.js +5 -0
- package/dist/chunks/studio-q7rtx6zq.js +14 -0
- package/dist/chunks/{studio-a3g98wjr.js → studio-qgh13jtz.js} +4 -4
- package/dist/chunks/studio-qmn1xc24.js +5 -0
- package/dist/chunks/studio-qwdqwkj0.js +5 -0
- package/dist/chunks/studio-r5qy30vx.js +5 -0
- package/dist/chunks/studio-rj9eamf8.js +5 -0
- package/dist/chunks/studio-rptgsk96.js +5 -0
- package/dist/chunks/studio-rthyg42z.js +928 -0
- package/dist/chunks/studio-s19tp1xr.js +5 -0
- package/dist/chunks/studio-s32578pn.js +5 -0
- package/dist/chunks/studio-svb7yyve.js +5 -0
- package/dist/chunks/studio-syreb644.js +5 -0
- package/dist/chunks/studio-tf9jryb1.js +10 -0
- package/dist/chunks/studio-tfkznv39.js +5 -0
- package/dist/chunks/studio-tft6r105.js +5 -0
- package/dist/chunks/studio-txf2kysx.js +5 -0
- package/dist/chunks/studio-v8867ddv.js +12 -0
- package/dist/chunks/studio-vxq7fcvv.js +5 -0
- package/dist/chunks/studio-w4rz9hdk.js +5 -0
- package/dist/chunks/studio-wbcjbhy1.js +9 -0
- package/dist/chunks/studio-wc649wss.js +5 -0
- package/dist/chunks/studio-wys23mxz.js +5 -0
- package/dist/chunks/studio-x1x167jh.js +5 -0
- package/dist/chunks/studio-x9hsze61.js +5 -0
- package/dist/chunks/studio-y0n7yxea.js +9 -0
- package/dist/chunks/studio-y3ahhdpx.js +5 -0
- package/dist/chunks/studio-z97c48fk.js +5 -0
- package/dist/chunks/studio-zat62m0c.js +5 -0
- package/dist/chunks/studio-zcd2e7yz.js +5 -0
- package/dist/chunks/studio-zz9qe3rw.js +64 -0
- package/dist/chunks/toast-1gv0h53h.js +4 -0
- package/dist/chunks/{toast-host-ke5z4ng7.js → toast-host-1yg5ar8d.js} +3 -3
- package/dist/chunks/{tooltip-5v8ngwj2.js → tooltip-yypz28gq.js} +3 -3
- package/dist/chunks/{tree-mdq3v5cw.js → tree-9xa4hm7n.js} +2 -2
- package/dist/chunks/tsMode-epyfz1hv.js +14 -0
- package/dist/chunks/workspace-dz7nxfhv.js +4 -0
- package/dist/chunks/workspace-home-xsd7hkjw.js +4 -0
- package/dist/chunks/{ws-client-nze0k6mv.js → ws-client-bv552sfx.js} +3 -3
- package/dist/iframe-entry.js +20 -16
- package/dist/manifest.json +77 -63
- package/dist/studio.js +103 -104
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +12 -11
- package/src/browse/component-examples.ts +272 -0
- package/src/browse/library-commands.ts +64 -104
- package/src/browse/library-layouts.ts +263 -49
- package/src/browse/library-model.ts +181 -133
- package/src/browse/library-pane.ts +738 -446
- package/src/browse/library-preview.ts +149 -19
- package/src/browse/library-source.ts +308 -41
- package/src/browse/preview-root.ts +78 -0
- package/src/browse/preview-style.ts +155 -0
- package/src/canvas/asset-refs.ts +16 -1
- package/src/canvas/canvas-live-render.ts +222 -30
- package/src/canvas/canvas-origin.ts +37 -12
- package/src/canvas/canvas-page-context.ts +112 -0
- package/src/canvas/canvas-render.ts +113 -107
- package/src/canvas/canvas-utils.ts +57 -12
- package/src/canvas/iframe-drop.ts +107 -0
- package/src/canvas/iframe-entry.ts +24 -12
- package/src/canvas/iframe-host.ts +134 -62
- package/src/canvas/iframe-keys.ts +11 -0
- package/src/canvas/iframe-patch.ts +8 -7
- package/src/canvas/iframe-protocol.ts +24 -5
- package/src/canvas/iframe-render.ts +48 -1
- package/src/canvas/iframe-subtree.ts +5 -2
- package/src/canvas/npm-modules.ts +22 -0
- package/src/canvas/preview-navigate.ts +16 -0
- package/src/canvas/repeater-sources.ts +200 -0
- package/src/canvas/stage-scrollbar.ts +5 -1
- package/src/canvas/surface-registry.ts +6 -0
- package/src/commands/app-commands.ts +16 -6
- package/src/commands/budget.ts +10 -8
- package/src/commands/context.ts +35 -10
- package/src/commands/defaults.ts +69 -45
- package/src/commands/keymap.ts +9 -0
- package/src/commands/levels.ts +11 -5
- package/src/commands/live-context.ts +2 -0
- package/src/commands/registry.ts +10 -1
- package/src/content/collection-match.ts +6 -5
- package/src/content/collection-pages.ts +412 -0
- package/src/content/content-collections.ts +270 -0
- package/src/content/entry-commands.ts +51 -60
- package/src/content/entry-editor.ts +111 -18
- package/src/content/entry-fields.ts +13 -1
- package/src/content/entry-inspector.ts +225 -0
- package/src/content/entry-model.ts +17 -3
- package/src/content/entry-open.ts +80 -0
- package/src/content/entry-summaries.ts +440 -0
- package/src/content/file-record-ids.ts +80 -0
- package/src/content/file-records.ts +125 -0
- package/src/content/page-summaries.ts +129 -0
- package/src/content/record-entry.ts +201 -0
- package/src/content/writing-banner.ts +177 -0
- package/src/create/add-new-commands.ts +185 -0
- package/src/create/add-new-flow.ts +1116 -0
- package/src/create/add-new.ts +1014 -0
- package/src/create/element-name.ts +121 -0
- package/src/editor/convert-to-component.ts +67 -43
- package/src/editor/file-drop-action.ts +9 -1
- package/src/editor/inline-edit-apply.ts +44 -0
- package/src/editor/inline-edit.ts +10 -0
- package/src/editor/insert-component.ts +91 -0
- package/src/editor/insert-zone-action.ts +13 -4
- package/src/editor/shortcuts.ts +44 -22
- package/src/editor/slash-menu.ts +51 -8
- package/src/files/components.ts +74 -10
- package/src/files/file-ops.ts +15 -5
- package/src/files/files.ts +164 -150
- package/src/files/fs-events.ts +18 -7
- package/src/files/media-meta.ts +95 -1
- package/src/files/media-types.ts +55 -0
- package/src/files/media-upload.ts +209 -52
- package/src/files/new-file-name.ts +156 -0
- package/src/files/serialize-document.ts +13 -3
- package/src/format/format-host.ts +15 -0
- package/src/github/github-auth.ts +2 -2
- package/src/github/github-publish.ts +4 -3
- package/src/grid/grid-controller.ts +5 -1
- package/src/grid/grid-open.ts +0 -27
- package/src/grid/grid-panel.ts +54 -2
- package/src/grid/grid-reveal.ts +34 -0
- package/src/grid/grid-source.ts +3 -25
- package/src/grid/grid-view.ts +31 -6
- package/src/grid/sources/content-source.ts +75 -7
- package/src/grid/tabulator-tables.d.ts +6 -0
- package/src/hosting/document.ts +2 -2
- package/src/i18n/i18n-commands.ts +2 -1
- package/src/media/media-commands.ts +181 -0
- package/src/media/media-library-model.ts +232 -0
- package/src/media/media-library.ts +1283 -0
- package/src/media/media-pane.ts +47 -19
- package/src/packages/pull-package-sync.ts +1 -1
- package/src/panels/activity-panel.ts +21 -5
- package/src/panels/ai-chat/chat-markdown.ts +8 -8
- package/src/panels/block-action-bar.ts +11 -11
- package/src/panels/canvas-dnd-bridge.ts +5 -2
- package/src/panels/chat-panel.ts +6 -6
- package/src/panels/collections-panel.ts +306 -0
- package/src/panels/component-preview.ts +35 -13
- package/src/panels/data-explorer.ts +1 -1
- package/src/panels/data-grid.ts +4 -0
- package/src/panels/dnd.ts +17 -30
- package/src/panels/elements-panel.ts +9 -2
- package/src/panels/empty-state.ts +2 -2
- package/src/panels/formula-workspace.ts +2 -3
- package/src/panels/frontmatter-fields.ts +9 -9
- package/src/panels/git-diff-open.ts +9 -5
- package/src/panels/head-panel.ts +369 -103
- package/src/panels/i18n-panel.ts +11 -10
- package/src/panels/imports-panel.ts +2 -0
- package/src/panels/jump-bar.ts +27 -2
- package/src/panels/layers-panel.ts +36 -30
- package/src/panels/left-panel.ts +22 -8
- package/src/panels/navigator-panels.ts +23 -11
- package/src/panels/pane-context.ts +111 -29
- package/src/panels/pane-grid.ts +6 -6
- package/src/panels/panel-registry.ts +14 -9
- package/src/panels/properties-panel.ts +7 -3
- package/src/panels/right-panel.ts +199 -43
- package/src/panels/seo-modal.ts +41 -108
- package/src/panels/settings-menu.ts +52 -50
- package/src/panels/settings-pane.ts +268 -162
- package/src/panels/signals-panel.ts +3 -4
- package/src/panels/site-model.ts +367 -0
- package/src/panels/site-panel.ts +638 -0
- package/src/panels/style-panel.ts +37 -3
- package/src/panels/stylebook-doc.ts +142 -10
- package/src/panels/stylebook-layers-panel.ts +39 -80
- package/src/panels/stylebook-panel.ts +47 -10
- package/src/panels/styles-panel.ts +327 -0
- package/src/panels/tab-strip.ts +109 -25
- package/src/platform.ts +1 -1
- package/src/platforms/cloud.ts +28 -1
- package/src/platforms/default-platform.ts +4 -4
- package/src/platforms/devserver.ts +51 -25
- package/src/publish/deploy-checklist.ts +12 -7
- package/src/publish/pages-service.ts +38 -14
- package/src/publish/publish-changes.ts +491 -0
- package/src/publish/publish-commands.ts +83 -18
- package/src/publish/publish-ids.ts +49 -0
- package/src/publish/publish-quick.ts +148 -0
- package/src/publish/publish-workspace.ts +926 -0
- package/src/publish/source-control.ts +907 -0
- package/src/services/automation.ts +16 -20
- package/src/services/cf-settings.ts +4 -4
- package/src/services/connection.ts +2 -2
- package/src/services/directory-picker.ts +2 -2
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +21 -2
- package/src/services/settings/definitions.ts +25 -14
- package/src/settings/contributed-section.ts +49 -10
- package/src/settings/css-vars-editor.ts +93 -27
- package/src/settings/developer-panels.ts +43 -0
- package/src/settings/extension-sections.ts +20 -2
- package/src/settings/general-settings.ts +91 -21
- package/src/settings/preferences-dialog.ts +8 -1
- package/src/settings/project-sections.ts +27 -10
- package/src/settings/schema-field-ui.ts +3 -1
- package/src/settings/section-registry.ts +116 -11
- package/src/settings/settings-dialog.ts +192 -0
- package/src/settings/settings-document.ts +182 -162
- package/src/shell.ts +467 -431
- package/src/site-context.ts +64 -10
- package/src/state.ts +28 -9
- package/src/studio.ts +194 -41
- package/src/style/project-styles.ts +34 -0
- package/src/style/stylebook-specimens.ts +89 -0
- package/src/style/stylebook-target.ts +26 -0
- package/src/style/tag-inheritance.ts +105 -0
- package/src/style/variables-focus.ts +61 -0
- package/src/style/variables-view.ts +235 -0
- package/src/surfaces/add-new.json +1482 -0
- package/src/surfaces/add-new.ts +325 -0
- package/src/surfaces/ai-chat.ts +2 -2
- package/src/surfaces/boot-failure.json +4 -3
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/canvas-stage.json +30 -19
- package/src/surfaces/canvas-stage.ts +5 -5
- package/src/surfaces/collections-panel.json +615 -0
- package/src/surfaces/collections-panel.ts +168 -0
- package/src/surfaces/commandbar.json +241 -96
- package/src/surfaces/commandbar.ts +134 -99
- package/src/surfaces/empty-state.json +1 -1
- package/src/surfaces/entry-editor.json +136 -0
- package/src/surfaces/entry-editor.ts +21 -0
- package/src/surfaces/entry-inspector.json +371 -0
- package/src/surfaces/entry-inspector.ts +143 -0
- package/src/surfaces/inspector-dock.json +162 -14
- package/src/surfaces/inspector-dock.ts +46 -19
- package/src/surfaces/library-pane.json +670 -437
- package/src/surfaces/library-pane.ts +94 -59
- package/src/surfaces/media-browser.json +62 -6
- package/src/surfaces/media-browser.ts +15 -1
- package/src/surfaces/media-field.json +1 -1
- package/src/surfaces/media-library.json +1586 -0
- package/src/surfaces/media-library.ts +282 -0
- package/src/surfaces/media-pick-dialog.json +71 -0
- package/src/surfaces/media-pick-dialog.ts +132 -0
- package/src/surfaces/menu.ts +18 -0
- package/src/surfaces/pane-context.json +144 -77
- package/src/surfaces/pane-context.ts +24 -0
- package/src/surfaces/panel-deploy-checklist.json +12 -6
- package/src/surfaces/panel-deploy-checklist.ts +3 -1
- package/src/surfaces/panel-page.json +72 -2
- package/src/surfaces/panel-page.ts +38 -7
- package/src/surfaces/panel-signals.json +1 -1
- package/src/surfaces/panel-signals.ts +5 -5
- package/src/surfaces/panel-stylebook-layers.json +71 -204
- package/src/surfaces/panel-stylebook-layers.ts +0 -21
- package/src/surfaces/preferences.json +120 -48
- package/src/surfaces/preferences.ts +8 -0
- package/src/surfaces/publish-quick.json +428 -0
- package/src/surfaces/publish-quick.ts +165 -0
- package/src/surfaces/publish-workspace.json +2892 -0
- package/src/surfaces/publish-workspace.ts +391 -0
- package/src/surfaces/rail.json +1 -159
- package/src/surfaces/rail.ts +18 -75
- package/src/surfaces/schema-form.json +10 -2
- package/src/surfaces/schema-form.ts +2 -0
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/settings-contributed.json +5 -5
- package/src/surfaces/settings-contributed.ts +18 -2
- package/src/surfaces/settings-css-vars.json +44 -36
- package/src/surfaces/settings-css-vars.ts +77 -4
- package/src/surfaces/settings-deploy.json +2 -15
- package/src/surfaces/settings-deploy.ts +1 -1
- package/src/surfaces/settings-dialog.json +51 -0
- package/src/surfaces/settings-dialog.ts +169 -0
- package/src/surfaces/settings-overview.json +3 -3
- package/src/surfaces/settings-overview.ts +9 -2
- package/src/surfaces/settings-pane.json +269 -46
- package/src/surfaces/settings-pane.ts +85 -24
- package/src/surfaces/shell.json +2 -1
- package/src/surfaces/site-panel.json +1029 -0
- package/src/surfaces/site-panel.ts +233 -0
- package/src/surfaces/slash-menu.json +63 -21
- package/src/surfaces/slash-menu.ts +23 -0
- package/src/surfaces/statusbar.ts +39 -15
- package/src/surfaces/styles-panel.json +735 -0
- package/src/surfaces/styles-panel.ts +195 -0
- package/src/surfaces/styles-variables.json +149 -0
- package/src/surfaces/styles-variables.ts +145 -0
- package/src/surfaces/tab-strip.json +4 -4
- package/src/surfaces/welcome.ts +1 -1
- package/src/surfaces/writing-banner.json +94 -0
- package/src/surfaces/writing-banner.ts +80 -0
- package/src/tabs/bare-repeaters.ts +101 -0
- package/src/tabs/tab.ts +47 -7
- package/src/types.ts +21 -26
- package/src/ui/form-controls.ts +47 -8
- package/src/ui/layers.ts +13 -0
- package/src/ui/media-picker.ts +284 -40
- package/src/ui/regions.ts +7 -6
- package/src/ui/schema-form.ts +259 -27
- package/src/ui/virtual-window.ts +26 -1
- package/src/utils/base64.ts +3 -3
- package/src/utils/edit-display.ts +322 -67
- package/src/utils/local-day.ts +18 -0
- package/src/workspace/pane-derive.ts +4 -4
- package/src/workspace/session.ts +28 -7
- package/src/workspace/tab-workspace.ts +137 -0
- package/src/workspace/workspace-back.ts +189 -0
- package/src/workspace/workspace-home.ts +133 -0
- package/src/workspace/workspace-ids.ts +129 -0
- package/src/workspace/workspace-switch.ts +372 -0
- package/src/workspace/workspace.ts +125 -11
- package/styles/shell-frame.css +30 -7
- package/styles/shell-frame.json +15 -3
- package/dist/chunks/2020-f2gkpy8d.js +0 -4
- package/dist/chunks/adapter-4912g339.js +0 -4
- package/dist/chunks/cf-account-picker-wccaenh6.js +0 -4
- package/dist/chunks/cf-settings-br6105tr.js +0 -4
- package/dist/chunks/color-28ksk2qm.js +0 -4
- package/dist/chunks/components-db68vsn7.js +0 -4
- package/dist/chunks/content-source-1449qesq.js +0 -4
- package/dist/chunks/convert-to-repeater-5h457egj.js +0 -4
- package/dist/chunks/editor-x9jn86a7.js +0 -4
- package/dist/chunks/entry-commands-may24cpt.js +0 -4
- package/dist/chunks/extension-sections-pvr14vxr.js +0 -4
- package/dist/chunks/file-ops-x9v54pcj.js +0 -4
- package/dist/chunks/files-j3knqf0s.js +0 -4
- package/dist/chunks/format-host-tyre2trb.js +0 -4
- package/dist/chunks/fs-events-64ma9htc.js +0 -4
- package/dist/chunks/git-panel-84ps5dex.js +0 -4
- package/dist/chunks/iframe-entry-fvbk89gm.js +0 -5
- package/dist/chunks/iframe-host-ck6vejt5.js +0 -4
- package/dist/chunks/index-b8xw3vy9.js +0 -4
- package/dist/chunks/jsonMode-w15cmrcm.js +0 -13
- package/dist/chunks/jx-validate-at3zn8wa.js +0 -4
- package/dist/chunks/layers-h4xp1pss.js +0 -4
- package/dist/chunks/layers-panel-m5hw1d7g.js +0 -4
- package/dist/chunks/lit-html-8t8t3dnr.js +0 -4
- package/dist/chunks/media-picker-2cweexc5.js +0 -4
- package/dist/chunks/menu-ynw13y0s.js +0 -4
- package/dist/chunks/monaco-buffer-qzxn567r.js +0 -4
- package/dist/chunks/monaco-setup-gxf6656g.js +0 -4
- package/dist/chunks/notify-cj5zbrs2.js +0 -4
- package/dist/chunks/parse-b7ddhr8m.js +0 -4
- package/dist/chunks/platform-3dfws9js.js +0 -4
- package/dist/chunks/popover-jt2gxmzs.js +0 -4
- package/dist/chunks/publish-panel-1gvxbj21.js +0 -4
- package/dist/chunks/quick-search-0dajrwqg.js +0 -4
- package/dist/chunks/references-49qgt404.js +0 -4
- package/dist/chunks/right-panel-jm1bwe53.js +0 -4
- package/dist/chunks/section-registry-6kwc4fky.js +0 -4
- package/dist/chunks/studio-0rt52vpq.js +0 -5
- package/dist/chunks/studio-18vgbhs5.js +0 -5
- package/dist/chunks/studio-24mccdrj.js +0 -5
- package/dist/chunks/studio-2eh507zk.js +0 -9
- package/dist/chunks/studio-2hcbccfv.js +0 -5
- package/dist/chunks/studio-2jbs3rxv.js +0 -5
- package/dist/chunks/studio-4h8k4dw9.js +0 -5
- package/dist/chunks/studio-5f6n18kx.js +0 -5
- package/dist/chunks/studio-5gthpky6.js +0 -5
- package/dist/chunks/studio-6ep3js6b.js +0 -9
- package/dist/chunks/studio-6wkmf3wz.js +0 -9
- package/dist/chunks/studio-841rf3cg.js +0 -5
- package/dist/chunks/studio-8gmwgheg.js +0 -5
- package/dist/chunks/studio-8qm0ep50.js +0 -5
- package/dist/chunks/studio-924p1tm1.js +0 -6
- package/dist/chunks/studio-a3shpz9y.js +0 -5
- package/dist/chunks/studio-amsbaaar.js +0 -6
- package/dist/chunks/studio-at5spjbc.js +0 -7
- package/dist/chunks/studio-b2xv945e.js +0 -5
- package/dist/chunks/studio-bn5nkafw.js +0 -5
- package/dist/chunks/studio-bw6q5xjf.js +0 -9
- package/dist/chunks/studio-c7q0t9x1.js +0 -5
- package/dist/chunks/studio-camnhc96.js +0 -6
- package/dist/chunks/studio-cffqvnzd.js +0 -5
- package/dist/chunks/studio-efvfrsf8.js +0 -5
- package/dist/chunks/studio-er30bpcx.js +0 -5
- package/dist/chunks/studio-ezscgr64.js +0 -5
- package/dist/chunks/studio-ffrrncvz.js +0 -5
- package/dist/chunks/studio-fpphgn8y.js +0 -10
- package/dist/chunks/studio-j1kvhdjk.js +0 -4
- package/dist/chunks/studio-j430n16g.js +0 -7
- package/dist/chunks/studio-jjkg84nj.js +0 -5
- package/dist/chunks/studio-m0q32ars.js +0 -4
- package/dist/chunks/studio-m6bdst11.js +0 -5
- package/dist/chunks/studio-nv2cptd4.js +0 -64
- package/dist/chunks/studio-nwfrc98n.js +0 -5
- package/dist/chunks/studio-p1wgvp7r.js +0 -5
- package/dist/chunks/studio-pag2wncm.js +0 -5
- package/dist/chunks/studio-qvanvzfd.js +0 -5
- package/dist/chunks/studio-qwa64kt7.js +0 -5
- package/dist/chunks/studio-rk1zc4x3.js +0 -928
- package/dist/chunks/studio-se2r3ptc.js +0 -5
- package/dist/chunks/studio-sg2a0dh0.js +0 -5
- package/dist/chunks/studio-tjzjhe68.js +0 -5
- package/dist/chunks/studio-v2w7q8r1.js +0 -7
- package/dist/chunks/studio-v5vjq1h0.js +0 -4
- package/dist/chunks/studio-v8aga3vp.js +0 -14
- package/dist/chunks/studio-vfcdrfmv.js +0 -5
- package/dist/chunks/studio-vmfkgdjf.js +0 -5
- package/dist/chunks/studio-wt1816jj.js +0 -5
- package/dist/chunks/studio-wz73q5kq.js +0 -4
- package/dist/chunks/studio-y04qtxvp.js +0 -7
- package/dist/chunks/studio-y21g8zzg.js +0 -5
- package/dist/chunks/studio-y64hrt8p.js +0 -12
- package/dist/chunks/studio-ynn90f58.js +0 -16
- package/dist/chunks/studio-yxz682sx.js +0 -5
- package/dist/chunks/studio-zp7snvkq.js +0 -5
- package/dist/chunks/studio-zq4z6tm6.js +0 -5
- package/dist/chunks/toast-c9fn075p.js +0 -4
- package/dist/chunks/tsMode-sf49ee9x.js +0 -14
- package/dist/chunks/workspace-jtfahpee.js +0 -4
- package/src/panels/frontmatter-panel.ts +0 -711
- package/src/panels/git-panel.ts +0 -1108
- package/src/surfaces/doc-header.json +0 -776
- package/src/surfaces/doc-header.ts +0 -222
- package/src/surfaces/git-panel.json +0 -1880
- package/src/surfaces/git-panel.ts +0 -264
package/src/editor/shortcuts.ts
CHANGED
|
@@ -528,15 +528,15 @@ function cycleRegion(direction: 1 | -1): void {
|
|
|
528
528
|
}
|
|
529
529
|
}
|
|
530
530
|
|
|
531
|
-
// ─── Panel and inspector focus (
|
|
531
|
+
// ─── Panel and inspector focus (`panel.focus.*`, ⌘⇧1–4) ──────────────────────
|
|
532
532
|
|
|
533
533
|
/**
|
|
534
534
|
* Toggle-FOCUS, not toggle-visible.
|
|
535
535
|
*
|
|
536
|
-
*
|
|
537
|
-
* — collapses the dock and hands the caret back to the pane. The distinction
|
|
538
|
-
* common case is "take me there", and a toggle-visible binding makes that a
|
|
539
|
-
* panel happened to be showing.
|
|
536
|
+
* `Show Files` from the canvas reveals Files and puts the caret in it; running it again — with
|
|
537
|
+
* Files already focused — collapses the dock and hands the caret back to the pane. The distinction
|
|
538
|
+
* matters because the common case is "take me there", and a toggle-visible binding makes that a
|
|
539
|
+
* coin flip on whichever panel happened to be showing.
|
|
540
540
|
*
|
|
541
541
|
* Every panel this can be handed lives in the Navigator. The roster is the rail plus the rail-less
|
|
542
542
|
* NAVIGATOR panels (`panels/navigator-panels.ts`), so a Bottom-dock record cannot reach here — the
|
|
@@ -546,14 +546,14 @@ function cycleRegion(direction: 1 | -1): void {
|
|
|
546
546
|
*/
|
|
547
547
|
function focusPanel(panelId: string): void {
|
|
548
548
|
/* THE DOOR. `shell.ts`'s `NAVIGATOR_PANEL_IDS` docstring says the command is what refuses an
|
|
549
|
-
undeclared id, "at the one door a caller comes through" — this is that door for
|
|
549
|
+
undeclared id, "at the one door a caller comes through" — this is that door for `panel.focus.*`, and it
|
|
550
550
|
was the only one of three doors that had no lock. `setActivityTab` now takes a
|
|
551
551
|
`NavigatorPanelId`, so the roster's `string` has to be narrowed somewhere; narrowing HERE keeps
|
|
552
552
|
`commands/defaults.ts` free of shell types, which is the property that lets three CI checks
|
|
553
553
|
load the command set in a bare Bun process.
|
|
554
554
|
|
|
555
555
|
A throw rather than a silent return: `tests/navigator-panels.test.ts` asserts the enum and the
|
|
556
|
-
registry agree, so this is unreachable while that passes, and a
|
|
556
|
+
registry agree, so this is unreachable while that passes, and a command that quietly does nothing
|
|
557
557
|
is precisely the defect this change is closing. */
|
|
558
558
|
const id = requireNavigatorPanelId(panelId, "panel.focus");
|
|
559
559
|
const alreadyThere =
|
|
@@ -990,7 +990,6 @@ export function initShortcuts(registry: CommandRegistry, stageContext: StageCont
|
|
|
990
990
|
* scrolled with the wheel at all.
|
|
991
991
|
*
|
|
992
992
|
* - `grid` — a Tabulator viewport with its own virtual scroller.
|
|
993
|
-
* - `manage` — the Library's ordinary overflow container.
|
|
994
993
|
* - `settings` — the Project Settings document (`panels/settings-pane.ts`): an `overflow-y: auto`
|
|
995
994
|
* section column, plus the Raw JSON `<pre>`'s own box inside it.
|
|
996
995
|
* - `entry` — the Entry editor's `overflow-y: auto` form (`content/entry-editor.ts`).
|
|
@@ -1000,28 +999,30 @@ export function initShortcuts(registry: CommandRegistry, stageContext: StageCont
|
|
|
1000
999
|
* there is no artboard here to zoom, either.
|
|
1001
1000
|
*/
|
|
1002
1001
|
const SELF_SCROLLING_MODES: ReadonlySet<string> = new Set([
|
|
1002
|
+
/* The Content home — `browse/library-pane.ts`. Its own scrolling list, nothing to zoom. */
|
|
1003
|
+
"content-home",
|
|
1003
1004
|
"entry",
|
|
1004
1005
|
"grid",
|
|
1005
|
-
"manage",
|
|
1006
1006
|
/* `media` — the Media viewer's own scrolling column (`media/media-pane.ts`). There is no artboard
|
|
1007
1007
|
here either: a wheel over an image is a scroll down the page it sits on, not a zoom. */
|
|
1008
1008
|
"media",
|
|
1009
|
+
/* A workspace's home — `workspace/workspace-home.ts`. A centred column with nothing to zoom. */
|
|
1010
|
+
"media-home",
|
|
1009
1011
|
"preview",
|
|
1010
|
-
"
|
|
1012
|
+
"publish-home",
|
|
1011
1013
|
]);
|
|
1012
1014
|
|
|
1013
1015
|
/**
|
|
1014
1016
|
* Can a box between `target` and the stage still answer this wheel itself?
|
|
1015
1017
|
*
|
|
1016
|
-
* Edit forwards every wheel to the page's scroller (see the branch below)
|
|
1017
|
-
*
|
|
1018
|
-
*
|
|
1019
|
-
*
|
|
1020
|
-
*
|
|
1021
|
-
*
|
|
1022
|
-
*
|
|
1023
|
-
*
|
|
1024
|
-
* and letting the browser scroll the page natively would chain out of it into the shell.
|
|
1018
|
+
* Edit forwards every wheel to the page's scroller (see the branch below). A `preventDefault` from
|
|
1019
|
+
* an ANCESTOR listener cancels the native scroll of whatever the pointer is over, so any box in the
|
|
1020
|
+
* stage cell that scrolls itself (a sideways strip, a capped list) would otherwise be unwheelable
|
|
1021
|
+
* while the page scrolled underneath it instead. So the stage takes the wheel only when nothing
|
|
1022
|
+
* inside it wants one: the walk stops at the stage cell, and it steps over the page's scroller
|
|
1023
|
+
* because that box is what the forwarding is FOR — a wheel forwarded out of the cross-origin frame
|
|
1024
|
+
* is dispatched on the cell itself and reaches no scrollable element on the way, and letting the
|
|
1025
|
+
* browser scroll the page natively would chain out of it into the shell.
|
|
1025
1026
|
*
|
|
1026
1027
|
* @param {WheelEvent} e
|
|
1027
1028
|
* @param {HTMLElement} stage The cell the listener is on — the walk's upper bound, exclusive.
|
|
@@ -1146,8 +1147,8 @@ export function installStageGestures(surface: CanvasSurface): () => void {
|
|
|
1146
1147
|
/* The stage's own scroller, by the `part` the stage document draws it with — the same
|
|
1147
1148
|
attribute every other consumer of the canvas's chrome now addresses it by. */
|
|
1148
1149
|
const sc = canvasWrap.querySelector<HTMLElement>('[part="edit-canvas"]');
|
|
1149
|
-
/* …unless the pointer is over a box in this cell that scrolls itself
|
|
1150
|
-
|
|
1150
|
+
/* …unless the pointer is over a box in this cell that scrolls itself. See
|
|
1151
|
+
{@link wheelBelongsInside}. */
|
|
1151
1152
|
if (sc && !wheelBelongsInside(e, canvasWrap, sc)) {
|
|
1152
1153
|
e.preventDefault();
|
|
1153
1154
|
sc.scrollTop += e.deltaY;
|
|
@@ -1231,7 +1232,7 @@ export function installStageGestures(surface: CanvasSurface): () => void {
|
|
|
1231
1232
|
canvasWrap.addEventListener(
|
|
1232
1233
|
"click",
|
|
1233
1234
|
(e: MouseEvent) => {
|
|
1234
|
-
if (e.target
|
|
1235
|
+
if (!isStageBackground(e.target, canvasWrap, surface.panzoomWrap)) {
|
|
1235
1236
|
return;
|
|
1236
1237
|
}
|
|
1237
1238
|
const tab = tabOfPane(surface.paneId);
|
|
@@ -1249,6 +1250,27 @@ export function installStageGestures(surface: CanvasSurface): () => void {
|
|
|
1249
1250
|
};
|
|
1250
1251
|
}
|
|
1251
1252
|
|
|
1253
|
+
/**
|
|
1254
|
+
* Whether a click landed on a stage's BACKGROUND rather than on anything drawn in it: the stage
|
|
1255
|
+
* itself, the pan/zoom surface, or the frame box every view draws its artboards in.
|
|
1256
|
+
*
|
|
1257
|
+
* The frame box is the one that matters in Edit. Edit has no pan/zoom surface; its frame is the
|
|
1258
|
+
* scrolling `[part="edit-canvas"]` that fills the stage around the page column, so the grey margin
|
|
1259
|
+
* beside the page IS that box, and a test that knew only the stage and the pan/zoom surface never
|
|
1260
|
+
* saw a click there. The frame is recognised by its static `data-slot`, which the stage document
|
|
1261
|
+
* stamps on it in every view.
|
|
1262
|
+
*/
|
|
1263
|
+
export function isStageBackground(
|
|
1264
|
+
target: EventTarget | null,
|
|
1265
|
+
stage: Element,
|
|
1266
|
+
panzoom: Element | null,
|
|
1267
|
+
): boolean {
|
|
1268
|
+
if (target === stage || (panzoom !== null && target === panzoom)) {
|
|
1269
|
+
return true;
|
|
1270
|
+
}
|
|
1271
|
+
return target instanceof HTMLElement && target.dataset.slot === "frame" && stage.contains(target);
|
|
1272
|
+
}
|
|
1273
|
+
|
|
1252
1274
|
/** The context a stage answers with before the bootstrap has published a reader. */
|
|
1253
1275
|
function stageless(): ShortcutPointerContext {
|
|
1254
1276
|
return {
|
package/src/editor/slash-menu.ts
CHANGED
|
@@ -27,8 +27,14 @@
|
|
|
27
27
|
*/
|
|
28
28
|
|
|
29
29
|
import { openSlashMenuSurface } from "../surfaces/slash-menu";
|
|
30
|
+
import { componentSlashCommands } from "./insert-component";
|
|
30
31
|
import { rectOf } from "../utils/geometry";
|
|
31
|
-
import type {
|
|
32
|
+
import type {
|
|
33
|
+
SlashMenuGroup,
|
|
34
|
+
SlashMenuRow,
|
|
35
|
+
SlashMenuSurface,
|
|
36
|
+
SlashMenuView,
|
|
37
|
+
} from "../surfaces/slash-menu";
|
|
32
38
|
import type { SlashCommand } from "./inline-edit";
|
|
33
39
|
|
|
34
40
|
// ─── Commands ─────────────────────────────────────────────────────────────────
|
|
@@ -115,9 +121,43 @@ export function showSlashMenuAtRect(
|
|
|
115
121
|
showAt(rect, filter, cbs);
|
|
116
122
|
}
|
|
117
123
|
|
|
124
|
+
/**
|
|
125
|
+
* The standard set: the HTML elements, then the project's components under their own heading
|
|
126
|
+
* (§5.7), read from the registry at the moment the menu opens so a component saved a moment ago is
|
|
127
|
+
* on offer.
|
|
128
|
+
*/
|
|
129
|
+
function standardCommands(): SlashCommand[] {
|
|
130
|
+
return [...SLASH_COMMANDS, ...componentSlashCommands()];
|
|
131
|
+
}
|
|
132
|
+
|
|
118
133
|
/** Everything on offer right now: what the caller named, or the standard set. */
|
|
119
134
|
function source(): SlashCommand[] {
|
|
120
|
-
return callbacks?.commands ||
|
|
135
|
+
return callbacks?.commands || standardCommands();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* The rows as the panel groups them: consecutive offers with the same heading share a group, and
|
|
140
|
+
* the first, unheaded group is the HTML elements. Each row keeps its index in the FLAT list, which
|
|
141
|
+
* is the one the keyboard, the highlight and a pick count in.
|
|
142
|
+
*/
|
|
143
|
+
function groupsOf(rows: readonly SlashMenuRow[], items: readonly SlashCommand[]): SlashMenuGroup[] {
|
|
144
|
+
const groups: SlashMenuGroup[] = [];
|
|
145
|
+
for (const [index, row] of rows.entries()) {
|
|
146
|
+
const label = items[index]?.group ?? "";
|
|
147
|
+
const last = groups.at(-1);
|
|
148
|
+
if (last?.label === label) {
|
|
149
|
+
last.rows.push(row);
|
|
150
|
+
} else {
|
|
151
|
+
groups.push({
|
|
152
|
+
hasLabel: label !== "",
|
|
153
|
+
key: label || "elements",
|
|
154
|
+
label,
|
|
155
|
+
name: label || "Elements",
|
|
156
|
+
rows: [row],
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return groups;
|
|
121
161
|
}
|
|
122
162
|
|
|
123
163
|
/** The offers a filter leaves standing. An empty filter leaves all of them. */
|
|
@@ -132,14 +172,17 @@ function matching(filter: string, from: SlashCommand[]): SlashCommand[] {
|
|
|
132
172
|
/** What the panel should be showing, from the state above. */
|
|
133
173
|
function view(): SlashMenuView {
|
|
134
174
|
const rect = _anchorRect;
|
|
175
|
+
const rows = filteredItems.map((cmd, index): SlashMenuRow => ({
|
|
176
|
+
description: cmd.description,
|
|
177
|
+
index,
|
|
178
|
+
key: cmd.tag,
|
|
179
|
+
label: cmd.label,
|
|
180
|
+
}));
|
|
135
181
|
return {
|
|
136
182
|
activeIndex: activeIdx,
|
|
137
183
|
filter: filterText,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
key: cmd.tag,
|
|
141
|
-
label: cmd.label,
|
|
142
|
-
})),
|
|
184
|
+
groups: groupsOf(rows, filteredItems),
|
|
185
|
+
rows,
|
|
143
186
|
showFilter,
|
|
144
187
|
// The gap between the anchor and the panel is the `--jx-popover-offset` token the element
|
|
145
188
|
// Already applies, so this is the anchor's own edge rather than an edge plus a guess.
|
|
@@ -163,7 +206,7 @@ function showAt(
|
|
|
163
206
|
callbacks = cbs;
|
|
164
207
|
_anchorRect = rect;
|
|
165
208
|
|
|
166
|
-
filteredItems = matching(filter, cbs.commands ||
|
|
209
|
+
filteredItems = matching(filter, cbs.commands || standardCommands());
|
|
167
210
|
|
|
168
211
|
if (filteredItems.length === 0 && !cbs.showFilter) {
|
|
169
212
|
dismissSlashMenu();
|
package/src/files/components.ts
CHANGED
|
@@ -18,14 +18,39 @@ export interface ComponentEntry extends Omit<ComponentMeta, "path"> {
|
|
|
18
18
|
export let componentRegistry: ComponentEntry[] = [];
|
|
19
19
|
export let _componentRegistryLoaded = false;
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
/** Bumped by every load, so only the newest scan may write the registry. */
|
|
22
|
+
let _generation = 0;
|
|
23
|
+
/** The newest scan, which a superseded one waits on so its caller still sees a loaded registry. */
|
|
24
|
+
let _newest: Promise<void> = Promise.resolve();
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Scan the project's components into the registry.
|
|
28
|
+
*
|
|
29
|
+
* Scans can overlap (the project-open path and the Site panel each start one), and a scan bound to
|
|
30
|
+
* the project being closed may resolve after the next project's. So the newest scan wins: an older
|
|
31
|
+
* one discards what it read and resolves when the newest has written the registry.
|
|
32
|
+
*/
|
|
33
|
+
export function loadComponentRegistry(): Promise<void> {
|
|
34
|
+
_generation += 1;
|
|
35
|
+
const generation = _generation;
|
|
36
|
+
const scan = (async () => {
|
|
37
|
+
let found: ComponentEntry[] | null = null;
|
|
38
|
+
try {
|
|
39
|
+
found = await getPlatform().discoverComponents(projectState?.projectRoot || undefined);
|
|
40
|
+
} catch {
|
|
41
|
+
found = null;
|
|
42
|
+
}
|
|
43
|
+
if (generation !== _generation) {
|
|
44
|
+
await _newest;
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (found) {
|
|
48
|
+
componentRegistry = found;
|
|
49
|
+
}
|
|
27
50
|
_componentRegistryLoaded = true;
|
|
28
|
-
}
|
|
51
|
+
})();
|
|
52
|
+
_newest = scan;
|
|
53
|
+
return scan;
|
|
29
54
|
}
|
|
30
55
|
|
|
31
56
|
/**
|
|
@@ -107,18 +132,57 @@ export function buildComponentInstance(comp: ComponentEntry): JxMutableNode {
|
|
|
107
132
|
}
|
|
108
133
|
|
|
109
134
|
/**
|
|
135
|
+
* Walk `parts` the way a path resolver does: `.` stays, `..` climbs, the rest descend. A climb
|
|
136
|
+
* above the start is kept as a leading `..`, which is how a project-relative path names a file
|
|
137
|
+
* outside the project.
|
|
138
|
+
*/
|
|
139
|
+
function normalizeParts(parts: readonly string[]): string[] {
|
|
140
|
+
const out: string[] = [];
|
|
141
|
+
for (const part of parts) {
|
|
142
|
+
if (part === ".") {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (part === ".." && out.length > 0 && out.at(-1) !== "..") {
|
|
146
|
+
out.pop();
|
|
147
|
+
} else {
|
|
148
|
+
out.push(part);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return out;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* The `$ref` a document at `fromDocPath` writes to reach `toCompPath`, both project-relative.
|
|
156
|
+
*
|
|
157
|
+
* A document can sit OUTSIDE the project: jxsuite.com's docs collection is `../../docs`, so an
|
|
158
|
+
* entry is `../../docs/extending/x.md`. Climbing from there back into the project needs the names
|
|
159
|
+
* of the folders the project sits in, which a project-relative path does not carry; counting its
|
|
160
|
+
* segments gave five `../` and a ref into a folder that does not exist, so every component a docs
|
|
161
|
+
* layout imports failed to register on the canvas. Such a path is resolved against `projectRoot`
|
|
162
|
+
* (the open project's, by default), the way the browser resolves the ref.
|
|
163
|
+
*
|
|
110
164
|
* @param {string | null} fromDocPath
|
|
111
165
|
* @param {string} toCompPath
|
|
166
|
+
* @param {string | null} [projectRoot]
|
|
112
167
|
*/
|
|
113
|
-
export function computeRelativePath(
|
|
168
|
+
export function computeRelativePath(
|
|
169
|
+
fromDocPath: string | null,
|
|
170
|
+
toCompPath: string,
|
|
171
|
+
projectRoot: string | null = projectState?.projectRoot ?? null,
|
|
172
|
+
) {
|
|
114
173
|
if (!fromDocPath) {
|
|
115
174
|
return `./${toCompPath}`;
|
|
116
175
|
}
|
|
117
176
|
const from = fromDocPath.replaceAll("\\", "/");
|
|
118
177
|
const to = toCompPath.replaceAll("\\", "/");
|
|
119
178
|
const fromDir = from.includes("/") ? from.slice(0, from.lastIndexOf("/")) : "";
|
|
120
|
-
|
|
121
|
-
|
|
179
|
+
let fromParts = normalizeParts(fromDir.split("/").filter(Boolean));
|
|
180
|
+
let toParts = normalizeParts(to.split("/").filter(Boolean));
|
|
181
|
+
if (fromParts[0] === ".." && projectRoot) {
|
|
182
|
+
const rootParts = projectRoot.replaceAll("\\", "/").split("/").filter(Boolean);
|
|
183
|
+
fromParts = normalizeParts([...rootParts, ...fromParts]);
|
|
184
|
+
toParts = normalizeParts([...rootParts, ...toParts]);
|
|
185
|
+
}
|
|
122
186
|
let common = 0;
|
|
123
187
|
while (
|
|
124
188
|
common < fromParts.length &&
|
package/src/files/file-ops.ts
CHANGED
|
@@ -105,6 +105,8 @@ export async function parseSourceForPath(path: string, source: string) {
|
|
|
105
105
|
export const parseCollabSource: CollabParser = async (tab, text) => {
|
|
106
106
|
if (tab.documentPath && formatForPath(tab.documentPath)) {
|
|
107
107
|
const parsed = await parseSourceForPath(tab.documentPath, text);
|
|
108
|
+
// The peer's text is what this client saves against now, as `layout` is for a JSON file.
|
|
109
|
+
tab.doc.source = text;
|
|
108
110
|
return { document: parsed.document, frontmatter: parsed.frontmatter };
|
|
109
111
|
}
|
|
110
112
|
const parsed = parseJsonDocument(text);
|
|
@@ -195,6 +197,7 @@ export async function openFile() {
|
|
|
195
197
|
fileHandle: handle,
|
|
196
198
|
frontmatter,
|
|
197
199
|
id: name,
|
|
200
|
+
source: text,
|
|
198
201
|
sourceFormat: format.name,
|
|
199
202
|
});
|
|
200
203
|
} else if (name.endsWith(".json")) {
|
|
@@ -254,26 +257,27 @@ export async function openFile() {
|
|
|
254
257
|
* **By injection**, the idiom `setSurfaceTeardown` and `setDiffRepaint` already use. The one
|
|
255
258
|
* listener today is source control: a comparison is two texts read once, so it does not notice a
|
|
256
259
|
* save on its own, and the file an author is most likely to save is the one they are reviewing. A
|
|
257
|
-
* direct import would put `
|
|
258
|
-
* every suite that mocks the canvas host out from under
|
|
260
|
+
* direct import would put `publish/source-control.ts` and the comparison opener behind it into this
|
|
261
|
+
* module's graph, which is a load error for every suite that mocks the canvas host out from under
|
|
262
|
+
* it.
|
|
259
263
|
*
|
|
260
264
|
* The listener is handed the document as well as the path, for the second listener: the live chrome
|
|
261
265
|
* lane (`services/live-surfaces.ts`) re-mounts a saved surface from the document the tab just wrote
|
|
262
266
|
* rather than reading the file back, which is what keeps the shipped app from ever reading its
|
|
263
267
|
* chrome from disk.
|
|
264
268
|
*/
|
|
265
|
-
let _onDocumentSaved: (path: string | null, doc: JxMutableNode) => void = () => {};
|
|
269
|
+
let _onDocumentSaved: (path: string | null, doc: JxMutableNode, tab: Tab) => void = () => {};
|
|
266
270
|
|
|
267
271
|
/** Register the save listener. Called once, from the bootstrap. */
|
|
268
272
|
export function setDocumentSavedListener(
|
|
269
|
-
listener: (path: string | null, doc: JxMutableNode) => void,
|
|
273
|
+
listener: (path: string | null, doc: JxMutableNode, tab: Tab) => void,
|
|
270
274
|
): void {
|
|
271
275
|
_onDocumentSaved = listener;
|
|
272
276
|
}
|
|
273
277
|
|
|
274
278
|
function reportSaved(tab: Tab) {
|
|
275
279
|
const doc = tab.doc.document;
|
|
276
|
-
_onDocumentSaved(tab.documentPath, doc);
|
|
280
|
+
_onDocumentSaved(tab.documentPath, doc, tab);
|
|
277
281
|
const warning =
|
|
278
282
|
isString(doc.tagName) && doc.tagName.includes("-") ? validateComponentSlots(doc) : null;
|
|
279
283
|
if (warning) {
|
|
@@ -398,6 +402,9 @@ export async function saveFile(tab: Tab | null = activeTab.value): Promise<boole
|
|
|
398
402
|
const platform = getPlatform();
|
|
399
403
|
await platform.writeFile(tab.documentPath, output);
|
|
400
404
|
tab.doc.dirty = false;
|
|
405
|
+
if (tab.doc.sourceFormat !== null) {
|
|
406
|
+
tab.doc.source = output;
|
|
407
|
+
}
|
|
401
408
|
/* Retract the unsaved bytes NOW rather than a debounce later. The write also reaches the
|
|
402
409
|
backend's filesystem watcher, and a live preview coalesces both into one reload only if
|
|
403
410
|
they arrive together — otherwise a save costs two. */
|
|
@@ -418,6 +425,9 @@ export async function saveFile(tab: Tab | null = activeTab.value): Promise<boole
|
|
|
418
425
|
await writable.write(output);
|
|
419
426
|
await writable.close();
|
|
420
427
|
tab.doc.dirty = false;
|
|
428
|
+
if (tab.doc.sourceFormat !== null) {
|
|
429
|
+
tab.doc.source = output;
|
|
430
|
+
}
|
|
421
431
|
reportSaved(tab);
|
|
422
432
|
return true;
|
|
423
433
|
}
|