@jxsuite/studio 6.1.1 → 8.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 +5 -5
- package/dist/chunks/2020-5wtzce5g.js +4 -0
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- 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-6rbra5dy.js +4 -0
- package/dist/chunks/color-field-gy56c94g.js +4 -0
- package/dist/chunks/color-m7r1vk54.js +4 -0
- package/dist/chunks/color-slider-sqqdyf6c.js +4 -0
- package/dist/chunks/combobox-72h32ejk.js +4 -0
- 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/dialog-c4x05vyx.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-qg1b5eqx.js +51 -0
- package/dist/chunks/icons-63bjtbs7.js +4 -0
- package/dist/chunks/iframe-entry-2zggzajv.js +5 -0
- package/dist/chunks/iframe-entry-76j8vwwx.js +5 -0
- package/dist/chunks/iframe-entry-99nr5zfb.js +5 -0
- package/dist/chunks/iframe-entry-pkgmcgp0.js +5 -0
- package/dist/chunks/iframe-host-ssv7kyj0.js +4 -0
- package/dist/chunks/{index-2veqmnhr.js → index-32eqzv1k.js} +3 -3
- package/dist/chunks/index-f0jn7nnp.js +4 -0
- package/dist/chunks/{javascript-8nbvs12s.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-c421cf8c.js +4 -0
- 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-bdpzbfvs.js +4 -0
- package/dist/chunks/monaco-binding-vq1hgnn0.js +4 -0
- 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/number-field-y62xq0ty.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/select-rzds841e.js +4 -0
- package/dist/chunks/source-control-kwktr9y6.js +4 -0
- package/dist/chunks/split-c9zfdgxf.js +4 -0
- 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-6m380wp7.js +5 -0
- package/dist/chunks/studio-80jyh1xh.js +4 -0
- package/dist/chunks/studio-83mk4bgg.js +9 -0
- package/dist/chunks/{studio-kggey1jt.js → studio-881z1xrx.js} +4 -4
- package/dist/chunks/studio-8m0y2qe7.js +5 -0
- package/dist/chunks/studio-8tr6cfrc.js +5 -0
- 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-bbe4c90a.js +5 -0
- 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-8grwxtqk.js → studio-jcnsdaep.js} +4 -4
- package/dist/chunks/studio-jsgf2q5k.js +7 -0
- package/dist/chunks/{studio-1q1sh2ax.js → studio-k3xxbagr.js} +3 -3
- package/dist/chunks/studio-k7evxqh4.js +5 -0
- 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-rv11kfwa.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-h46vtzk8.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-wszjyh0j.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-pre0skq6.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-t6b6qe31.js → studio-r5qy30vx.js} +4 -4
- 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/swatch-group-ewh24n1f.js +4 -0
- package/dist/chunks/tabs-f5cw3tgp.js +4 -0
- package/dist/chunks/textfield-wewc8rq2.js +4 -0
- package/dist/chunks/toast-1gv0h53h.js +4 -0
- package/dist/chunks/toast-host-1yg5ar8d.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-yypz28gq.js +4 -0
- package/dist/chunks/tree-9xa4hm7n.js +4 -0
- 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-bv552sfx.js +4 -0
- package/dist/iframe-entry.js +20 -16
- package/dist/manifest.json +77 -63
- package/dist/studio.js +106 -107
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +17 -16
- package/src/about/about-modal.ts +4 -3
- package/src/account/action-flow.ts +45 -38
- package/src/account-status.ts +7 -2
- package/src/browse/component-examples.ts +272 -0
- package/src/browse/library-commands.ts +64 -104
- package/src/browse/library-layouts.ts +270 -53
- package/src/browse/library-model.ts +194 -134
- package/src/browse/library-pane.ts +748 -440
- package/src/browse/library-preview.ts +161 -26
- 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 +40 -10
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +260 -77
- package/src/canvas/canvas-origin.ts +37 -12
- package/src/canvas/canvas-page-context.ts +112 -0
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +175 -148
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +147 -61
- package/src/canvas/dialog-path.ts +9 -4
- package/src/canvas/dialog-state.ts +1 -2
- package/src/canvas/diff-marks.ts +9 -16
- package/src/canvas/diff-toolbar.ts +8 -7
- package/src/canvas/edit-width-drag.ts +4 -1
- package/src/canvas/edit-width.ts +1 -3
- package/src/canvas/iframe-channel.ts +27 -13
- package/src/canvas/iframe-drop.ts +120 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +104 -75
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +269 -158
- package/src/canvas/iframe-inline-edit.ts +49 -30
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +30 -25
- package/src/canvas/iframe-keys.ts +11 -0
- package/src/canvas/iframe-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +25 -21
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +36 -21
- package/src/canvas/iframe-render.ts +84 -35
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +10 -3
- package/src/canvas/npm-modules.ts +22 -0
- package/src/canvas/path-mapping.ts +19 -12
- package/src/canvas/popover-path.ts +7 -3
- package/src/canvas/popover-state.ts +1 -2
- package/src/canvas/preview-navigate.ts +16 -0
- package/src/canvas/repeater-sources.ts +200 -0
- package/src/canvas/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +7 -2
- package/src/canvas/surface-registry.ts +27 -3
- package/src/collab/collab-commands.ts +7 -2
- package/src/collab/collab-session.ts +84 -45
- package/src/collab/collab-state.ts +4 -3
- package/src/collab/monaco-binding.ts +16 -13
- package/src/collab/monaco-cursors.ts +5 -2
- package/src/commands/app-commands.ts +16 -6
- package/src/commands/budget.ts +13 -11
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +55 -28
- package/src/commands/defaults.ts +69 -45
- package/src/commands/keymap.ts +56 -43
- package/src/commands/levels.ts +14 -8
- package/src/commands/live-context.ts +9 -7
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +22 -11
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +11 -9
- package/src/content/collection-pages.ts +412 -0
- package/src/content/content-collections.ts +270 -0
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +54 -62
- package/src/content/entry-editor.ts +137 -32
- package/src/content/entry-fields.ts +25 -8
- package/src/content/entry-inspector.ts +225 -0
- package/src/content/entry-model.ts +38 -15
- 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/canvas-context-menu.ts +1 -2
- package/src/editor/canvas-slash-bridge.ts +3 -6
- package/src/editor/content-slice.ts +16 -14
- package/src/editor/context-menu.ts +35 -22
- package/src/editor/convert-targets.ts +30 -35
- package/src/editor/convert-to-component.ts +78 -48
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +29 -22
- package/src/editor/inline-edit-apply.ts +79 -17
- package/src/editor/inline-edit.ts +76 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-component.ts +91 -0
- package/src/editor/insert-zone-action.ts +14 -5
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +76 -42
- package/src/editor/slash-menu.ts +52 -14
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +89 -20
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +92 -41
- package/src/files/files.ts +248 -239
- package/src/files/fs-events.ts +18 -7
- package/src/files/media-meta.ts +97 -2
- package/src/files/media-paths.ts +3 -0
- 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 +15 -5
- package/src/format/constraints.ts +1 -1
- package/src/format/convert-file.ts +27 -13
- package/src/format/format-choices.ts +2 -1
- package/src/format/format-host.ts +91 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +21 -11
- package/src/github/github-publish.ts +28 -23
- package/src/grid/cell-editors.ts +46 -31
- package/src/grid/cell-popovers.ts +5 -3
- package/src/grid/edit-buffer.ts +10 -9
- package/src/grid/grid-controller.ts +25 -23
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -33
- package/src/grid/grid-panel.ts +65 -6
- package/src/grid/grid-reveal.ts +34 -0
- package/src/grid/grid-source.ts +9 -31
- package/src/grid/grid-view.ts +45 -23
- package/src/grid/redirects-grid.ts +14 -5
- package/src/grid/redirects.ts +16 -14
- package/src/grid/schema-columns.ts +25 -19
- package/src/grid/sources/connector-source.ts +47 -20
- package/src/grid/sources/content-source.ts +100 -31
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +61 -34
- package/src/hosting/document.ts +2 -2
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +3 -3
- 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 +51 -20
- package/src/new-project/add-repo-modal.ts +20 -19
- package/src/new-project/import-tab.ts +10 -14
- package/src/new-project/location-fields.ts +2 -1
- package/src/new-project/new-project-modal.ts +12 -9
- package/src/packages/jxsuite-update.ts +4 -3
- package/src/packages/pull-package-sync.ts +26 -25
- package/src/page-params.ts +97 -68
- package/src/panels/activity-panel.ts +38 -14
- package/src/panels/ai-chat/attached-context.ts +13 -7
- package/src/panels/ai-chat/chat-markdown.ts +8 -8
- package/src/panels/ai-chat/chat-view.ts +80 -73
- package/src/panels/ai-chat/composer.ts +30 -33
- package/src/panels/ai-chat/sessions-view.ts +1 -2
- package/src/panels/ai-panel.ts +23 -20
- package/src/panels/block-action-bar.ts +57 -46
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +36 -26
- 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 +63 -26
- package/src/panels/data-grid.ts +18 -11
- package/src/panels/dnd.ts +115 -138
- package/src/panels/editors.ts +52 -21
- package/src/panels/elements-panel.ts +19 -5
- package/src/panels/empty-state.ts +2 -2
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +78 -54
- package/src/panels/frontmatter-fields.ts +33 -28
- package/src/panels/git-diff-open.ts +10 -6
- package/src/panels/head-panel.ts +488 -202
- package/src/panels/i18n-panel.ts +20 -12
- package/src/panels/imports-panel.ts +25 -47
- package/src/panels/jump-bar.ts +75 -31
- package/src/panels/layers-panel.ts +130 -101
- package/src/panels/left-panel.ts +25 -11
- package/src/panels/navigator-panels.ts +23 -11
- package/src/panels/pane-context.ts +140 -49
- package/src/panels/pane-grid.ts +55 -26
- package/src/panels/panel-registry.ts +36 -46
- package/src/panels/properties-panel.ts +182 -124
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +201 -45
- package/src/panels/seo-modal.ts +54 -125
- package/src/panels/settings-menu.ts +63 -61
- package/src/panels/settings-pane.ts +268 -162
- package/src/panels/signals-panel.ts +156 -135
- package/src/panels/site-model.ts +367 -0
- package/src/panels/site-panel.ts +638 -0
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +253 -206
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +195 -60
- package/src/panels/stylebook-layers-panel.ts +48 -89
- package/src/panels/stylebook-panel.ts +60 -27
- package/src/panels/styles-panel.ts +327 -0
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +143 -49
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +59 -31
- package/src/platforms/cloud.ts +373 -176
- package/src/platforms/default-platform.ts +14 -8
- package/src/platforms/devserver.ts +180 -142
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +20 -9
- package/src/publish/pages-service.ts +66 -27
- package/src/publish/publish-changes.ts +491 -0
- package/src/publish/publish-commands.ts +88 -22
- package/src/publish/publish-ids.ts +49 -0
- package/src/publish/publish-panel.ts +10 -6
- 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/recent-projects.ts +15 -8
- package/src/resize-edges.ts +26 -36
- package/src/services/a11y-report.ts +26 -19
- package/src/services/agent-seed.ts +23 -11
- package/src/services/ai-ask.ts +9 -12
- package/src/services/ai-command-tools.ts +68 -62
- package/src/services/ai-import-tools.ts +80 -67
- package/src/services/ai-models.ts +17 -13
- package/src/services/ai-project-tools.ts +68 -32
- package/src/services/ai-session-store.ts +19 -10
- package/src/services/ai-system-prompt.ts +46 -20
- package/src/services/ai-tools.ts +71 -27
- package/src/services/ai-write-report.ts +20 -12
- package/src/services/ai-writes.ts +4 -4
- package/src/services/automation.ts +74 -51
- package/src/services/cem-export.ts +149 -58
- package/src/services/cf-settings.ts +4 -4
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- package/src/services/connection.ts +2 -2
- package/src/services/context-manager.ts +14 -10
- package/src/services/context-resolver.ts +20 -8
- package/src/services/data-service.ts +19 -15
- package/src/services/directory-picker.ts +20 -14
- package/src/services/document-assistant.ts +39 -19
- package/src/services/gated-registry.ts +10 -6
- package/src/services/harness/chat-reducer.ts +23 -1
- package/src/services/import-client.ts +91 -38
- package/src/services/import-seed.ts +8 -2
- package/src/services/jx-validate.ts +28 -31
- package/src/services/live-preview.ts +0 -0
- package/src/services/live-surfaces.ts +6 -3
- package/src/services/model-uri.ts +10 -2
- package/src/services/module-preloads.ts +12 -8
- package/src/services/monaco-buffer.ts +43 -24
- package/src/services/monaco-lazy.ts +7 -8
- package/src/services/monaco-setup.ts +23 -16
- package/src/services/notify.ts +44 -17
- package/src/services/popover-report.ts +25 -10
- package/src/services/preview-eval.ts +20 -8
- package/src/services/profile.ts +13 -6
- package/src/services/project-path.ts +13 -10
- package/src/services/references.ts +0 -0
- package/src/services/render-critic.ts +29 -9
- package/src/services/settings/definitions.ts +25 -14
- package/src/services/settings/kernel.ts +13 -4
- package/src/services/settings/write-queue.ts +9 -9
- package/src/services/token-lint.ts +12 -10
- package/src/services/tool-executor.ts +17 -5
- package/src/services/tool-outcomes.ts +44 -24
- package/src/services/trusted-types.ts +24 -7
- package/src/settings/contexts-section.ts +11 -8
- package/src/settings/contributed-section.ts +128 -70
- package/src/settings/css-vars-editor.ts +119 -32
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/developer-panels.ts +43 -0
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +42 -14
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +101 -28
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +17 -7
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +28 -11
- package/src/settings/schema-field-ui.ts +12 -1
- package/src/settings/section-registry.ts +116 -11
- package/src/settings/settings-dialog.ts +192 -0
- package/src/settings/settings-document.ts +186 -166
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +536 -477
- package/src/site-context.ts +101 -32
- package/src/state.ts +68 -57
- package/src/store.ts +54 -34
- package/src/studio.ts +219 -116
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +40 -7
- 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/token-ref.ts +5 -4
- package/src/style/variables-focus.ts +61 -0
- package/src/style/variables-view.ts +235 -0
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-new.json +1482 -0
- package/src/surfaces/add-new.ts +325 -0
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +33 -38
- package/src/surfaces/ai-credentials-form.ts +6 -16
- package/src/surfaces/ai-managed-connect.ts +3 -4
- package/src/surfaces/ai-model-picker.ts +3 -5
- package/src/surfaces/block-action-bar.ts +22 -11
- package/src/surfaces/boot-failure.json +4 -3
- package/src/surfaces/boot-failure.ts +4 -5
- package/src/surfaces/bottom-dock.json +1 -1
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.json +30 -19
- package/src/surfaces/canvas-stage.ts +17 -16
- package/src/surfaces/cf-account-picker.ts +17 -18
- 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 +145 -105
- package/src/surfaces/convert-repeater.ts +17 -19
- package/src/surfaces/data-actions.ts +9 -7
- package/src/surfaces/dialog.ts +26 -28
- package/src/surfaces/diff-toolbar.ts +9 -7
- package/src/surfaces/empty-state.json +1 -1
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.json +136 -0
- package/src/surfaces/entry-editor.ts +35 -11
- package/src/surfaces/entry-inspector.json +371 -0
- package/src/surfaces/entry-inspector.ts +143 -0
- package/src/surfaces/expression-editor.ts +11 -25
- package/src/surfaces/files-panel.ts +27 -14
- package/src/surfaces/formula-palette.ts +4 -5
- package/src/surfaces/github-auth.ts +16 -20
- package/src/surfaces/github-publish.ts +17 -22
- package/src/surfaces/grid-cell.ts +30 -31
- package/src/surfaces/grid-open.ts +10 -14
- package/src/surfaces/grid-panel.ts +13 -9
- package/src/surfaces/grid-replace.ts +13 -13
- package/src/surfaces/grid-views.ts +15 -18
- package/src/surfaces/inspector-dock.json +162 -14
- package/src/surfaces/inspector-dock.ts +59 -31
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.json +670 -437
- package/src/surfaces/library-pane.ts +111 -77
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.json +62 -6
- package/src/surfaces/media-browser.ts +26 -11
- package/src/surfaces/media-field.json +1 -1
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-library.json +1586 -0
- package/src/surfaces/media-library.ts +282 -0
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/media-pick-dialog.json +71 -0
- package/src/surfaces/media-pick-dialog.ts +132 -0
- package/src/surfaces/menu.ts +47 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.json +144 -77
- package/src/surfaces/pane-context.ts +44 -25
- package/src/surfaces/pane-grid.ts +15 -10
- package/src/surfaces/panel-activity.ts +5 -6
- package/src/surfaces/panel-data.ts +3 -4
- package/src/surfaces/panel-deploy-checklist.json +12 -6
- package/src/surfaces/panel-deploy-checklist.ts +8 -7
- package/src/surfaces/panel-elements.ts +5 -7
- package/src/surfaces/panel-i18n.ts +5 -7
- package/src/surfaces/panel-imports.ts +6 -13
- package/src/surfaces/panel-outline.ts +25 -19
- package/src/surfaces/panel-page.json +72 -2
- package/src/surfaces/panel-page.ts +49 -25
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.json +1 -1
- package/src/surfaces/panel-signals.ts +25 -39
- package/src/surfaces/panel-stylebook-layers.json +71 -204
- package/src/surfaces/panel-stylebook-layers.ts +5 -29
- package/src/surfaces/preferences.json +120 -48
- package/src/surfaces/preferences.ts +29 -11
- package/src/surfaces/progress-modal.ts +15 -9
- package/src/surfaces/properties-panel.json +1 -1
- package/src/surfaces/properties-panel.ts +20 -42
- package/src/surfaces/publish-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/publish.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.json +1 -159
- package/src/surfaces/rail.ts +22 -79
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.json +10 -2
- package/src/surfaces/schema-form.ts +17 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.json +1 -1
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.json +5 -5
- package/src/surfaces/settings-contributed.ts +32 -12
- package/src/surfaces/settings-css-vars.json +44 -36
- package/src/surfaces/settings-css-vars.ts +82 -16
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.json +2 -15
- package/src/surfaces/settings-deploy.ts +9 -16
- package/src/surfaces/settings-dialog.json +51 -0
- package/src/surfaces/settings-dialog.ts +169 -0
- package/src/surfaces/settings-extensions.ts +5 -6
- package/src/surfaces/settings-head.ts +33 -39
- package/src/surfaces/settings-locales.ts +8 -20
- package/src/surfaces/settings-overview.json +3 -3
- package/src/surfaces/settings-overview.ts +14 -8
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.json +269 -46
- package/src/surfaces/settings-pane.ts +88 -36
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.json +2 -1
- package/src/surfaces/shell.ts +1 -2
- 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 +42 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +56 -29
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- 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/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +6 -8
- 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/patch-ops.ts +4 -3
- package/src/tabs/project-config.ts +32 -21
- package/src/tabs/selection.ts +36 -8
- package/src/tabs/tab.ts +99 -48
- package/src/tabs/transact.ts +98 -53
- package/src/types.ts +53 -43
- package/src/ui/ai-credentials-form.ts +10 -13
- package/src/ui/ai-model-picker.ts +3 -3
- package/src/ui/cf-account-picker.ts +7 -9
- package/src/ui/color-selector.ts +9 -5
- package/src/ui/dynamic-slot.ts +7 -8
- package/src/ui/expression-editor.ts +112 -105
- package/src/ui/form-controls.ts +104 -56
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +57 -31
- package/src/ui/media-picker.ts +300 -47
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +14 -12
- package/src/ui/schema-form.ts +372 -97
- package/src/ui/surface.ts +71 -8
- package/src/ui/timing.ts +9 -0
- package/src/ui/value-source.ts +44 -31
- package/src/ui/virtual-window.ts +29 -3
- package/src/utils/base64.ts +6 -4
- package/src/utils/edit-display.ts +366 -111
- package/src/utils/element-selectors.ts +3 -2
- package/src/utils/google-fonts.ts +15 -14
- package/src/utils/inherited-style.ts +18 -20
- package/src/utils/link-target.ts +1 -1
- package/src/utils/local-day.ts +18 -0
- package/src/utils/preview-format.ts +25 -3
- package/src/utils/strip-events.ts +49 -22
- package/src/utils/studio-utils.ts +29 -14
- package/src/view.ts +2 -3
- package/src/workspace/pane-derive.ts +14 -16
- package/src/workspace/session.ts +81 -50
- 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 +165 -47
- package/styles/shell-frame.css +30 -7
- package/styles/shell-frame.json +15 -3
- package/dist/chunks/2020-va2wwra4.js +0 -4
- package/dist/chunks/adapter-f93pafd7.js +0 -4
- package/dist/chunks/cf-account-picker-af1h381v.js +0 -4
- package/dist/chunks/cf-settings-125tdm0w.js +0 -4
- package/dist/chunks/color-area-jqhna8zy.js +0 -4
- package/dist/chunks/color-field-embq5ctg.js +0 -4
- package/dist/chunks/color-fpezvnkt.js +0 -4
- package/dist/chunks/color-slider-1qmw7wqy.js +0 -4
- package/dist/chunks/combobox-773hdzyj.js +0 -4
- package/dist/chunks/components-ax2f1fnn.js +0 -4
- package/dist/chunks/content-source-108aqtk1.js +0 -4
- package/dist/chunks/convert-to-repeater-ry5rmppr.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-pfgdmkb0.js +0 -4
- package/dist/chunks/entry-commands-t0k1q0kx.js +0 -4
- package/dist/chunks/extension-sections-6mwh2hf8.js +0 -4
- package/dist/chunks/file-ops-meej5mqf.js +0 -4
- package/dist/chunks/files-44vp8a2s.js +0 -4
- package/dist/chunks/format-host-7q1petb9.js +0 -4
- package/dist/chunks/fs-events-h2mwnxaz.js +0 -4
- package/dist/chunks/git-panel-zngbymvd.js +0 -4
- package/dist/chunks/grid-view-sx9vynsp.js +0 -51
- package/dist/chunks/icons-p44xhjf0.js +0 -4
- package/dist/chunks/iframe-entry-f7mqjwpm.js +0 -5
- package/dist/chunks/iframe-entry-haw7jkvz.js +0 -5
- package/dist/chunks/iframe-entry-z6qrytv3.js +0 -5
- package/dist/chunks/iframe-host-qk3ycq87.js +0 -4
- package/dist/chunks/index-wkyfjeqz.js +0 -4
- package/dist/chunks/jsonMode-s8kt9dsj.js +0 -13
- package/dist/chunks/jx-validate-psgd7vsx.js +0 -4
- package/dist/chunks/layers-panel-1kq2jyfk.js +0 -4
- package/dist/chunks/layers-xd92fg8d.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-ac4cwwr4.js +0 -4
- package/dist/chunks/media-picker-0svzkdyb.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/menu-5c55ea3d.js +0 -4
- package/dist/chunks/monaco-binding-z6r70pdt.js +0 -4
- package/dist/chunks/monaco-buffer-fz6gq5y7.js +0 -4
- package/dist/chunks/monaco-setup-q4axkgj7.js +0 -4
- package/dist/chunks/notify-0xgtn8q1.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-v1qctbe6.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-ym1fmgq5.js +0 -4
- package/dist/chunks/quick-search-a54e6t5n.js +0 -4
- package/dist/chunks/references-gmqp82fs.js +0 -4
- package/dist/chunks/right-panel-v7t9awbk.js +0 -4
- package/dist/chunks/section-registry-vhyf3zsr.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0bhx5hz6.js +0 -5
- package/dist/chunks/studio-0k1ddnyy.js +0 -6
- package/dist/chunks/studio-1b04pd0j.js +0 -64
- package/dist/chunks/studio-4dwbj6gb.js +0 -5
- package/dist/chunks/studio-4tanh828.js +0 -5
- package/dist/chunks/studio-55h4mstj.js +0 -4
- package/dist/chunks/studio-5tnvjkz4.js +0 -5
- package/dist/chunks/studio-60dqgb0c.js +0 -5
- package/dist/chunks/studio-61dp09qg.js +0 -9
- package/dist/chunks/studio-63epcrj2.js +0 -5
- package/dist/chunks/studio-74k29dy9.js +0 -5
- package/dist/chunks/studio-7vg6jcd3.js +0 -5
- package/dist/chunks/studio-7zx31knw.js +0 -9
- package/dist/chunks/studio-8bxk97km.js +0 -5
- package/dist/chunks/studio-933e30n4.js +0 -5
- package/dist/chunks/studio-98wnwhbg.js +0 -5
- package/dist/chunks/studio-9mccjwjh.js +0 -14
- package/dist/chunks/studio-a2ke1e4t.js +0 -5
- package/dist/chunks/studio-e3a2a6v3.js +0 -4
- package/dist/chunks/studio-e81q1vb9.js +0 -5
- package/dist/chunks/studio-epgrmqqm.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-g1shz58g.js +0 -5
- package/dist/chunks/studio-gf0fz03c.js +0 -5
- package/dist/chunks/studio-gjtpe62q.js +0 -6
- package/dist/chunks/studio-gkskhg7m.js +0 -5
- package/dist/chunks/studio-gx4dnjzd.js +0 -5
- package/dist/chunks/studio-j03zga3y.js +0 -9
- package/dist/chunks/studio-jhpxeckz.js +0 -5
- package/dist/chunks/studio-k01r7ykp.js +0 -5
- package/dist/chunks/studio-kk7h30ne.js +0 -7
- package/dist/chunks/studio-kt1zqney.js +0 -5
- package/dist/chunks/studio-m3cwhvye.js +0 -5
- package/dist/chunks/studio-mcayt6hz.js +0 -5
- package/dist/chunks/studio-myjcghv3.js +0 -5
- package/dist/chunks/studio-n8bxwc3y.js +0 -4
- package/dist/chunks/studio-ngm8gvpb.js +0 -5
- package/dist/chunks/studio-nj5a01jy.js +0 -928
- package/dist/chunks/studio-pcgz8heb.js +0 -5
- package/dist/chunks/studio-qcsq0t15.js +0 -5
- package/dist/chunks/studio-qkstvve9.js +0 -5
- package/dist/chunks/studio-qv1pwd3c.js +0 -5
- package/dist/chunks/studio-rc6dvxjb.js +0 -7
- package/dist/chunks/studio-s8dmmz66.js +0 -5
- package/dist/chunks/studio-sp5xzbj4.js +0 -6
- package/dist/chunks/studio-szsjbj0g.js +0 -5
- package/dist/chunks/studio-t1xzawhr.js +0 -16
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- package/dist/chunks/studio-vrmcjf9g.js +0 -7
- package/dist/chunks/studio-vyc0b4he.js +0 -10
- package/dist/chunks/studio-w0cgf6jg.js +0 -5
- package/dist/chunks/studio-w3hskzqk.js +0 -5
- package/dist/chunks/studio-xgrgcdyh.js +0 -9
- package/dist/chunks/studio-xz2yxfcb.js +0 -5
- package/dist/chunks/studio-y6n42tgs.js +0 -5
- package/dist/chunks/studio-yb560vxr.js +0 -5
- package/dist/chunks/studio-yn9f8vtx.js +0 -5
- package/dist/chunks/studio-yw05w8f0.js +0 -7
- package/dist/chunks/studio-z16sgavc.js +0 -5
- package/dist/chunks/studio-zey7zsdw.js +0 -12
- package/dist/chunks/studio-zyqn40w4.js +0 -5
- package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
- package/dist/chunks/tabs-jwthg40w.js +0 -4
- package/dist/chunks/textfield-spy3hc77.js +0 -4
- package/dist/chunks/toast-4d35zd64.js +0 -4
- package/dist/chunks/toast-host-8sjmfed3.js +0 -4
- package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
- package/dist/chunks/tree-h19v1jfz.js +0 -4
- package/dist/chunks/tsMode-2frah6h1.js +0 -14
- package/dist/chunks/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
- package/src/panels/frontmatter-panel.ts +0 -701
- package/src/panels/git-panel.ts +0 -1120
- package/src/surfaces/doc-header.json +0 -776
- package/src/surfaces/doc-header.ts +0 -231
- package/src/surfaces/git-panel.json +0 -1880
- package/src/surfaces/git-panel.ts +0 -272
package/src/surfaces/welcome.ts
CHANGED
|
@@ -24,16 +24,15 @@ import { runOfferedAction } from "../account/action-flow";
|
|
|
24
24
|
import { platformSupportsAddRepo } from "../new-project/add-repo-modal";
|
|
25
25
|
import { getProjectList } from "../project-list";
|
|
26
26
|
import { reactive } from "../reactivity";
|
|
27
|
-
import { now } from "../services/clock";
|
|
27
|
+
import { MINUTE, now } from "../services/clock";
|
|
28
28
|
import { clearRecentProjects, getRecentProjects, removeRecentProject } from "../recent-projects";
|
|
29
|
-
import { platformSupportsClone } from "../
|
|
29
|
+
import { platformSupportsClone } from "../publish/source-control";
|
|
30
30
|
import { mountSurface, registerSurface } from "../ui/surface";
|
|
31
31
|
import welcomeDoc from "./welcome.json";
|
|
32
|
-
import type { JxDocument } from "@jxsuite/schema/types";
|
|
33
32
|
import type { SurfaceHandle } from "../ui/surface";
|
|
34
33
|
import type { AccountNotice, OfferedAction } from "../types";
|
|
35
34
|
|
|
36
|
-
registerSurface("welcome", welcomeDoc
|
|
35
|
+
registerSurface("welcome", welcomeDoc);
|
|
37
36
|
|
|
38
37
|
interface WelcomeCtx {
|
|
39
38
|
openProject: () => void;
|
|
@@ -122,7 +121,6 @@ export function recentLocations(
|
|
|
122
121
|
return labels;
|
|
123
122
|
}
|
|
124
123
|
|
|
125
|
-
const MINUTE = 60_000;
|
|
126
124
|
const HOUR = 60 * MINUTE;
|
|
127
125
|
const DAY = 24 * HOUR;
|
|
128
126
|
|
|
@@ -195,7 +193,7 @@ interface CatalogueRow {
|
|
|
195
193
|
detail: string;
|
|
196
194
|
}
|
|
197
195
|
|
|
198
|
-
interface WelcomeScope
|
|
196
|
+
interface WelcomeScope {
|
|
199
197
|
actions: StartAction[];
|
|
200
198
|
installNeeded: boolean;
|
|
201
199
|
installUrl: string;
|
|
@@ -292,7 +290,7 @@ function noticeAction(key: string): OfferedAction | null {
|
|
|
292
290
|
|
|
293
291
|
/** The reactive scope the surface reads, made once. */
|
|
294
292
|
function state(): WelcomeScope {
|
|
295
|
-
_state ??= reactive({
|
|
293
|
+
_state ??= reactive<WelcomeScope>({
|
|
296
294
|
actions: [],
|
|
297
295
|
catalogue: [],
|
|
298
296
|
clear: () => {
|
|
@@ -342,7 +340,7 @@ function state(): WelcomeScope {
|
|
|
342
340
|
}
|
|
343
341
|
}
|
|
344
342
|
},
|
|
345
|
-
})
|
|
343
|
+
});
|
|
346
344
|
return _state;
|
|
347
345
|
}
|
|
348
346
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://jxsuite.com/schema/v1",
|
|
3
|
+
"$id": "StudioWritingBanner",
|
|
4
|
+
"$description": "The writing-mode banner (specs/studio.md §22.5): one slim line above the canvas while a collection entry is written inside its template's layout, saying what the arrangement is (the text and media are editable, the layout is locked) with the door to the template, which opens it in Design. `content/writing-banner.ts` decides whether there is a template to open and what it is called; this document draws a sentence and, when there is one, the button.",
|
|
5
|
+
"tagName": "div",
|
|
6
|
+
"attributes": {
|
|
7
|
+
"part": "banner",
|
|
8
|
+
"role": "note",
|
|
9
|
+
"data-jx-region": "${state.region}"
|
|
10
|
+
},
|
|
11
|
+
"style": {
|
|
12
|
+
"$description": "A quiet band, the Content-Entry board's: the canvas is the subject, so the banner is a tinted line rather than a panel, and its action is a quiet button.",
|
|
13
|
+
"display": "flex",
|
|
14
|
+
"alignItems": "center",
|
|
15
|
+
"flexWrap": "wrap",
|
|
16
|
+
"gap": "var(--jx-space-2)",
|
|
17
|
+
"padding": "var(--jx-space-1) var(--jx-space-4)",
|
|
18
|
+
"background": "color-mix(in srgb, var(--accent) 10%, var(--bg-panel))",
|
|
19
|
+
"borderBottom": "1px solid var(--border)",
|
|
20
|
+
"fontFamily": "var(--jx-font-sans)",
|
|
21
|
+
"fontSize": "var(--jx-text-sm)",
|
|
22
|
+
"color": "var(--fg-dim)",
|
|
23
|
+
"& [part=\"glyph\"]": {
|
|
24
|
+
"flexShrink": "0",
|
|
25
|
+
"color": "var(--accent)"
|
|
26
|
+
},
|
|
27
|
+
"& [part=\"text\"]": {
|
|
28
|
+
"flex": "1",
|
|
29
|
+
"minWidth": "0"
|
|
30
|
+
},
|
|
31
|
+
"& [part=\"action-slot\"]": {
|
|
32
|
+
"display": "contents"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"children": [
|
|
36
|
+
{
|
|
37
|
+
"tagName": "jx-icon",
|
|
38
|
+
"attributes": {
|
|
39
|
+
"part": "glyph"
|
|
40
|
+
},
|
|
41
|
+
"$props": {
|
|
42
|
+
"name": "lock-simple"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"tagName": "span",
|
|
47
|
+
"attributes": {
|
|
48
|
+
"part": "text"
|
|
49
|
+
},
|
|
50
|
+
"textContent": "${state.text}"
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"tagName": "div",
|
|
54
|
+
"attributes": {
|
|
55
|
+
"part": "action-slot",
|
|
56
|
+
"role": "none"
|
|
57
|
+
},
|
|
58
|
+
"$switch": {
|
|
59
|
+
"$ref": "#/state/actionState"
|
|
60
|
+
},
|
|
61
|
+
"cases": {
|
|
62
|
+
"shown": {
|
|
63
|
+
"tagName": "jx-action-button",
|
|
64
|
+
"attributes": {
|
|
65
|
+
"part": "edit-template"
|
|
66
|
+
},
|
|
67
|
+
"$props": {
|
|
68
|
+
"size": "sm",
|
|
69
|
+
"quiet": true
|
|
70
|
+
},
|
|
71
|
+
"onclick": {
|
|
72
|
+
"$prototype": "Function",
|
|
73
|
+
"body": [
|
|
74
|
+
{
|
|
75
|
+
"operator": "call",
|
|
76
|
+
"target": {
|
|
77
|
+
"$ref": "#/state/openTemplate"
|
|
78
|
+
},
|
|
79
|
+
"value": []
|
|
80
|
+
}
|
|
81
|
+
],
|
|
82
|
+
"description": "Opening the template is activating it, which enters Design (studio.md §22.1)."
|
|
83
|
+
},
|
|
84
|
+
"children": [
|
|
85
|
+
{
|
|
86
|
+
"tagName": "span",
|
|
87
|
+
"textContent": "${state.actionLabel}"
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
/**
|
|
3
|
+
* The writing-mode banner surface: one line over the canvas while a collection entry is written
|
|
4
|
+
* inside its template's layout (`specs/studio.md` §22.5).
|
|
5
|
+
*
|
|
6
|
+
* This is the adapter. `content/writing-banner.ts` decides what the line says and where its button
|
|
7
|
+
* goes; this module writes the projection into a scope and mounts `writing-banner.json`.
|
|
8
|
+
*
|
|
9
|
+
* @docs studio/projects/content-types
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { reactive } from "../reactivity";
|
|
13
|
+
import { mountSurface, registerSurface } from "../ui/surface";
|
|
14
|
+
import writingBannerDoc from "./writing-banner.json";
|
|
15
|
+
import type { SurfaceHandle } from "../ui/surface";
|
|
16
|
+
|
|
17
|
+
registerSurface("writing-banner", writingBannerDoc);
|
|
18
|
+
|
|
19
|
+
/** What the banner draws. */
|
|
20
|
+
export interface WritingBannerView {
|
|
21
|
+
/** The region id stamped on the root: `pane.<id>/writing-banner`. */
|
|
22
|
+
region: string;
|
|
23
|
+
text: string;
|
|
24
|
+
/** "Design the post page", or "Edit the Base template in Design" when the entry has no page. */
|
|
25
|
+
actionLabel: string;
|
|
26
|
+
/** Whether there is a template to open at all. */
|
|
27
|
+
actionState: "hidden" | "shown";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface WritingBannerActions {
|
|
31
|
+
/** Open the entry's template in Design. */
|
|
32
|
+
openTemplate: () => void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface WritingBannerHandle {
|
|
36
|
+
readonly ready: Promise<unknown>;
|
|
37
|
+
update: (view: WritingBannerView) => void;
|
|
38
|
+
dispose: () => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
interface WritingBannerScope extends WritingBannerView, WritingBannerActions {}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Mount the banner into `host`, the empty node the canvas stage drew for it.
|
|
45
|
+
*
|
|
46
|
+
* @param host The stage's `writing-banner` host.
|
|
47
|
+
* @param view What it says.
|
|
48
|
+
* @param actions What its button does.
|
|
49
|
+
*/
|
|
50
|
+
export function mountWritingBannerSurface(
|
|
51
|
+
host: HTMLElement,
|
|
52
|
+
view: WritingBannerView,
|
|
53
|
+
actions: WritingBannerActions,
|
|
54
|
+
): WritingBannerHandle {
|
|
55
|
+
const scope: WritingBannerScope = reactive<WritingBannerScope>({ ...view, ...actions });
|
|
56
|
+
let mounted: SurfaceHandle | null = null;
|
|
57
|
+
let disposed = false;
|
|
58
|
+
const ready = mountSurface("writing-banner", scope, host).then((surface) => {
|
|
59
|
+
if (disposed) {
|
|
60
|
+
surface.dispose();
|
|
61
|
+
} else {
|
|
62
|
+
mounted = surface;
|
|
63
|
+
}
|
|
64
|
+
return surface;
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
dispose() {
|
|
68
|
+
disposed = true;
|
|
69
|
+
mounted?.dispose();
|
|
70
|
+
mounted = null;
|
|
71
|
+
},
|
|
72
|
+
ready,
|
|
73
|
+
update(next) {
|
|
74
|
+
scope.region = next.region;
|
|
75
|
+
scope.text = next.text;
|
|
76
|
+
scope.actionLabel = next.actionLabel;
|
|
77
|
+
scope.actionState = next.actionState;
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The repeaters a file wrote as a node's whole `children`, so a save can write them back that way.
|
|
3
|
+
*
|
|
4
|
+
* A node may hold a repeater two ways: as a member of its children array (`children: [{ $prototype:
|
|
5
|
+
* "Array", … }]`) or as the whole children slot (`children: { $prototype: "Array", … }`). The two
|
|
6
|
+
* render the same, and the editor works in the first form only: `normalizeArrayChildren` rewrites
|
|
7
|
+
* every document a tab loads, because every mutation, path and history checkpoint assumes a
|
|
8
|
+
* children array. Without a record of what the file said, a save then rewrote every bare repeater
|
|
9
|
+
* in it into the member form, so one inserted paragraph produced a diff in a list nobody touched,
|
|
10
|
+
* and undoing every edit still left the file different from the one on disk.
|
|
11
|
+
*
|
|
12
|
+
* **Two keys, either of which is enough.** The pointer of the node that held the repeater survives
|
|
13
|
+
* an edit inside the repeater (a restyled template); the repeater's own JSON survives an edit that
|
|
14
|
+
* moves it (a sibling inserted above an ancestor shifts every pointer below it). A repeater both
|
|
15
|
+
* moved and changed loses both and is written in the member form, which renders the same. Only a
|
|
16
|
+
* children array whose ONLY member is a repeater is unwrapped: a node that has gained a sibling of
|
|
17
|
+
* its repeater can no longer be written the bare way at all.
|
|
18
|
+
*
|
|
19
|
+
* @docs studio/interface/tabs
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { isJsonObject, isMappedArray } from "@jxsuite/schema/guards";
|
|
23
|
+
import type { JsonObject, JsonValue, JxMutableNode } from "@jxsuite/schema/types";
|
|
24
|
+
import { normalizeArrayChildren, pointerToken } from "../state";
|
|
25
|
+
|
|
26
|
+
/** What a file said about its bare repeaters, in the normalized document's coordinates. */
|
|
27
|
+
export interface BareRepeaters {
|
|
28
|
+
/** The JSON Pointer of each node whose `children` WAS the repeater. */
|
|
29
|
+
readonly pointers: ReadonlySet<string>;
|
|
30
|
+
/** `JSON.stringify` of each such repeater as it was read. */
|
|
31
|
+
readonly fingerprints: ReadonlySet<string>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Normalize a freshly read document in place (`normalizeArrayChildren`) and return what it rewrote,
|
|
36
|
+
* or null when the file held no bare repeater — the common case, which needs no record.
|
|
37
|
+
*/
|
|
38
|
+
export function normalizeDocument(document: JxMutableNode): BareRepeaters | null {
|
|
39
|
+
const pointers = new Set<string>();
|
|
40
|
+
const fingerprints = new Set<string>();
|
|
41
|
+
normalizeArrayChildren(document, (pointer, repeater) => {
|
|
42
|
+
pointers.add(pointer);
|
|
43
|
+
fingerprints.add(JSON.stringify(repeater));
|
|
44
|
+
});
|
|
45
|
+
return pointers.size === 0 ? null : { fingerprints, pointers };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The document as the file should hold it: every single-member children array whose repeater the
|
|
50
|
+
* record names, written back as the node's whole `children`. Copy-on-write, so the tab's document
|
|
51
|
+
* (a reactive tree the editor owns) is never touched, and a document with nothing to restore is
|
|
52
|
+
* returned as it is.
|
|
53
|
+
*/
|
|
54
|
+
export function restoreBareRepeaters(
|
|
55
|
+
document: JxMutableNode,
|
|
56
|
+
record: BareRepeaters | null,
|
|
57
|
+
): JxMutableNode {
|
|
58
|
+
if (!record) {
|
|
59
|
+
return document;
|
|
60
|
+
}
|
|
61
|
+
/* SAFETY: a Jx document is JSON (it is read from, and written to, a JSON file); the restored copy
|
|
62
|
+
is the same node with some `children` slots holding their sole repeater directly — the bare
|
|
63
|
+
form the node's schema allows. */
|
|
64
|
+
return restoreValue(document as JsonValue, "", record) as JxMutableNode;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Restore inside one value of the tree, returning it unchanged when nothing below it moved. */
|
|
68
|
+
function restoreValue(value: JsonValue, pointer: string, record: BareRepeaters): JsonValue {
|
|
69
|
+
if (Array.isArray(value)) {
|
|
70
|
+
let copy: JsonValue[] | null = null;
|
|
71
|
+
for (const [i, item] of value.entries()) {
|
|
72
|
+
const next = restoreValue(item, `${pointer}/${i}`, record);
|
|
73
|
+
if (next !== item) {
|
|
74
|
+
copy ??= [...value];
|
|
75
|
+
copy[i] = next;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return copy ?? value;
|
|
79
|
+
}
|
|
80
|
+
if (!isJsonObject(value)) {
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
let copy: JsonObject | null = null;
|
|
84
|
+
for (const [key, child] of Object.entries(value)) {
|
|
85
|
+
let next = restoreValue(child, `${pointer}/${pointerToken(key)}`, record);
|
|
86
|
+
if (key === "children" && Array.isArray(next) && next.length === 1) {
|
|
87
|
+
const [only] = next;
|
|
88
|
+
if (
|
|
89
|
+
isMappedArray(only) &&
|
|
90
|
+
(record.pointers.has(pointer) || record.fingerprints.has(JSON.stringify(only)))
|
|
91
|
+
) {
|
|
92
|
+
next = only;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (next !== child) {
|
|
96
|
+
copy ??= { ...value };
|
|
97
|
+
copy[key] = next;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return copy ?? value;
|
|
101
|
+
}
|
package/src/tabs/patch-ops.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
// oxlint-disable-next-line unicorn/prefer-export-from -- JxDocOpPair is also used locally (TransactionRecord)
|
|
9
9
|
import type { JxDocOpPair } from "@jxsuite/schema/doc-ops";
|
|
10
|
+
import type { JxDocumentValue, JxMutableNode } from "@jxsuite/schema/types";
|
|
10
11
|
import type { JxPath } from "../state";
|
|
11
12
|
import type { Tab } from "./tab.js";
|
|
12
13
|
|
|
@@ -48,8 +49,8 @@ export type { JxDocOpPair };
|
|
|
48
49
|
*/
|
|
49
50
|
export interface JxFmOp {
|
|
50
51
|
field: string;
|
|
51
|
-
before?:
|
|
52
|
-
after?:
|
|
52
|
+
before?: JxDocumentValue | undefined;
|
|
53
|
+
after?: JxDocumentValue | undefined;
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
/** Everything recorded during one transaction. */
|
|
@@ -82,7 +83,7 @@ export interface PatchConsumer {
|
|
|
82
83
|
* was consumed by whichever pane's effect ran first, so the second full-rendered every patched
|
|
83
84
|
* edit while the skip counter reported one skip.
|
|
84
85
|
*/
|
|
85
|
-
markConsumed: (docRef:
|
|
86
|
+
markConsumed: (docRef: JxMutableNode, tab: Tab) => void;
|
|
86
87
|
/**
|
|
87
88
|
* Apply the batch to all ready canvas panels. Throws on any failure (caller escalates). `record`
|
|
88
89
|
* carries the value-carrying `docOps` the iframe consumer posts across the frame boundary; the
|
|
@@ -63,7 +63,7 @@ import { errorMessage } from "@jxsuite/schema/parse";
|
|
|
63
63
|
import { effect, toRaw } from "../reactivity";
|
|
64
64
|
import { getPlatform } from "../platform";
|
|
65
65
|
import { notify } from "../services/notify";
|
|
66
|
-
import { requireProjectState, setProjectState } from "../state";
|
|
66
|
+
import { projectState, requireProjectState, setProjectState } from "../state";
|
|
67
67
|
import { setWorkspaceProject, workspace } from "../workspace/workspace";
|
|
68
68
|
import { PROJECT_CONFIG_PATH, createTab, disposeTab } from "./tab";
|
|
69
69
|
import { transactDoc } from "./transact";
|
|
@@ -71,7 +71,7 @@ import { deriveJsonLayout, parseJsonDocument, serializeJson } from "@jxsuite/sch
|
|
|
71
71
|
import type { JsonLayout } from "@jxsuite/schema/json-layout";
|
|
72
72
|
|
|
73
73
|
import type { Tab } from "./tab";
|
|
74
|
-
import type { ProjectConfig } from "@jxsuite/schema/types";
|
|
74
|
+
import type { JxMutableNode, ProjectConfig } from "@jxsuite/schema/types";
|
|
75
75
|
|
|
76
76
|
export { PROJECT_CONFIG_PATH } from "./tab";
|
|
77
77
|
|
|
@@ -147,7 +147,7 @@ let _seeding: Promise<void> | null = null;
|
|
|
147
147
|
*/
|
|
148
148
|
function openConfigTab(): Tab | null {
|
|
149
149
|
const tab = workspace.tabs.get(PROJECT_CONFIG_PATH);
|
|
150
|
-
return tab ?
|
|
150
|
+
return tab ? toRaw(tab) : null;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/** Drop the current binding, disposing the detached document if that is what it was. */
|
|
@@ -169,7 +169,8 @@ function seedCommitted(): Promise<void> {
|
|
|
169
169
|
const text = await getPlatform().readFile(PROJECT_CONFIG_PATH);
|
|
170
170
|
const { document, layout } = parseJsonDocument(text);
|
|
171
171
|
_layout = layout;
|
|
172
|
-
|
|
172
|
+
// {@link serializeProjectConfig}'s serialisation, over the file's parse rather than a config.
|
|
173
|
+
_committed = serializeJson(document, configLayout());
|
|
173
174
|
} catch {
|
|
174
175
|
// No file, an unreadable one, or one that does not parse. "Unknown" is the honest answer,
|
|
175
176
|
// And an unknown file is one every commit must write.
|
|
@@ -240,8 +241,22 @@ function syncProjectState(config: ProjectConfig): void {
|
|
|
240
241
|
* @returns {ProjectConfig | null}
|
|
241
242
|
*/
|
|
242
243
|
function liveConfig(): ProjectConfig | null {
|
|
243
|
-
const config =
|
|
244
|
-
return config ?
|
|
244
|
+
const config = projectState?.projectConfig;
|
|
245
|
+
return config ? toRaw(config) : null;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* The configuration a configuration document holds, unwrapped.
|
|
250
|
+
*
|
|
251
|
+
* @param {JxMutableNode} document The bound tab's `doc.document`.
|
|
252
|
+
* @returns {ProjectConfig}
|
|
253
|
+
*/
|
|
254
|
+
function configOf(document: JxMutableNode): ProjectConfig {
|
|
255
|
+
/* SAFETY: every document this module reads is the `project.json` tab's root, and that root is
|
|
256
|
+
only ever installed as a ProjectConfig: `createTab` below seeds it from `projectConfig`, an open
|
|
257
|
+
tab parsed the file the schema gate wrote, and every transaction here assigns configuration
|
|
258
|
+
keys. The Tab type calls every root a JxMutableNode; this is the one place that says which. */
|
|
259
|
+
return toRaw(document) as ProjectConfig;
|
|
245
260
|
}
|
|
246
261
|
|
|
247
262
|
/**
|
|
@@ -261,10 +276,10 @@ function liveConfig(): ProjectConfig | null {
|
|
|
261
276
|
* settings surfaces render from `projectState` and mutate it in place, and every reader of the
|
|
262
277
|
* document follows the root reference {@link transactDoc} replaces when the transaction ends.
|
|
263
278
|
*
|
|
264
|
-
* @param {
|
|
279
|
+
* @param {JxMutableNode} target
|
|
265
280
|
* @param {ProjectConfig} source
|
|
266
281
|
*/
|
|
267
|
-
function replaceContents(target:
|
|
282
|
+
function replaceContents(target: JxMutableNode, source: ProjectConfig): void {
|
|
268
283
|
for (const key of Object.keys(target)) {
|
|
269
284
|
delete target[key];
|
|
270
285
|
}
|
|
@@ -282,10 +297,10 @@ function bind(tab: Tab): Tab {
|
|
|
282
297
|
tab.scope.run(() => {
|
|
283
298
|
effect(() => {
|
|
284
299
|
const doc = tab.doc.document;
|
|
285
|
-
if (_bound !== tab || !
|
|
300
|
+
if (_bound !== tab || !projectState) {
|
|
286
301
|
return;
|
|
287
302
|
}
|
|
288
|
-
syncProjectState(
|
|
303
|
+
syncProjectState(configOf(doc));
|
|
289
304
|
});
|
|
290
305
|
});
|
|
291
306
|
return tab;
|
|
@@ -316,7 +331,7 @@ export function projectConfigDocument(): Tab {
|
|
|
316
331
|
return bind(open);
|
|
317
332
|
}
|
|
318
333
|
_detached = createTab({
|
|
319
|
-
document:
|
|
334
|
+
document: state.projectConfig ?? {},
|
|
320
335
|
documentPath: PROJECT_CONFIG_PATH,
|
|
321
336
|
id: PROJECT_CONFIG_PATH,
|
|
322
337
|
});
|
|
@@ -380,7 +395,7 @@ export async function commitProjectConfig(
|
|
|
380
395
|
// The seed, and the record it read handed to the document — so the tab the Settings door opened
|
|
381
396
|
// Writes the same bytes from ⌘S that this commit is about to.
|
|
382
397
|
await lendProjectConfigLayout(tab);
|
|
383
|
-
const current =
|
|
398
|
+
const current = configOf(tab.doc.document);
|
|
384
399
|
const currentText = serializeProjectConfig(current);
|
|
385
400
|
|
|
386
401
|
// Two objects that disagree — whichever one loses, an edit written into it is lost. Null when
|
|
@@ -404,7 +419,7 @@ export async function commitProjectConfig(
|
|
|
404
419
|
}
|
|
405
420
|
|
|
406
421
|
const base = rival ?? current;
|
|
407
|
-
const next = patch ?
|
|
422
|
+
const next: ProjectConfig = patch ? { ...base, ...patch } : base;
|
|
408
423
|
const text = serializeProjectConfig(next);
|
|
409
424
|
|
|
410
425
|
// Nothing the file does not already say: no transaction, no write, and therefore no diff. The
|
|
@@ -417,7 +432,7 @@ export async function commitProjectConfig(
|
|
|
417
432
|
|
|
418
433
|
const before = extensionsKey(current);
|
|
419
434
|
transactDoc(tab, (t) => {
|
|
420
|
-
const doc = t.doc.document
|
|
435
|
+
const doc = t.doc.document;
|
|
421
436
|
if (rival) {
|
|
422
437
|
replaceContents(doc, rival);
|
|
423
438
|
}
|
|
@@ -429,7 +444,7 @@ export async function commitProjectConfig(
|
|
|
429
444
|
// Serialised from what the transaction actually LANDED, not from the `next` computed above: a
|
|
430
445
|
// Gate on `transactDoc` can refuse a mutation, and writing the value it refused would put the
|
|
431
446
|
// File and the document into the one disagreement this module exists to make impossible.
|
|
432
|
-
const config =
|
|
447
|
+
const config = configOf(tab.doc.document);
|
|
433
448
|
const output = serializeProjectConfig(config);
|
|
434
449
|
try {
|
|
435
450
|
await getPlatform().writeFile(PROJECT_CONFIG_PATH, output);
|
|
@@ -480,18 +495,14 @@ export async function commitProjectConfig(
|
|
|
480
495
|
* @returns {Promise<void>}
|
|
481
496
|
*/
|
|
482
497
|
export async function adoptProjectConfig(config: ProjectConfig, text: string): Promise<void> {
|
|
483
|
-
if (!
|
|
498
|
+
if (!projectState) {
|
|
484
499
|
// No project state is no configuration document either ({@link projectConfigDocument} reads
|
|
485
500
|
// One). The workspace copy is then the only thing there is to keep true.
|
|
486
501
|
setWorkspaceProject(workspace.projectRoot, config);
|
|
487
502
|
return;
|
|
488
503
|
}
|
|
489
504
|
const tab = projectConfigDocument();
|
|
490
|
-
transactDoc(
|
|
491
|
-
tab,
|
|
492
|
-
(t) => replaceContents(t.doc.document as unknown as Record<string, unknown>, config),
|
|
493
|
-
{ skipHistory: true },
|
|
494
|
-
);
|
|
505
|
+
transactDoc(tab, (t) => replaceContents(t.doc.document, config), { skipHistory: true });
|
|
495
506
|
tab.doc.dirty = false;
|
|
496
507
|
// Settle a read already in flight before saying what the file holds, or it would resolve after
|
|
497
508
|
// These lines with the PREVIOUS bytes and record, and make the next real commit look like a
|
package/src/tabs/selection.ts
CHANGED
|
@@ -42,6 +42,8 @@
|
|
|
42
42
|
* standing between a mixed selection and a half-applied, unrecorded delete.
|
|
43
43
|
*/
|
|
44
44
|
|
|
45
|
+
import { isNumber } from "@jxsuite/schema/guards";
|
|
46
|
+
|
|
45
47
|
import type { JxPath } from "../state";
|
|
46
48
|
import { isAncestor, pathsEqual } from "../state";
|
|
47
49
|
|
|
@@ -52,7 +54,7 @@ import { isAncestor, pathsEqual } from "../state";
|
|
|
52
54
|
* @returns {JxPath | null}
|
|
53
55
|
*/
|
|
54
56
|
export function primarySelection(selection: readonly JxPath[] | null | undefined): JxPath | null {
|
|
55
|
-
return selection
|
|
57
|
+
return selection?.at(-1) ?? null;
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
/**
|
|
@@ -62,7 +64,7 @@ export function primarySelection(selection: readonly JxPath[] | null | undefined
|
|
|
62
64
|
* @returns {JxPath | null}
|
|
63
65
|
*/
|
|
64
66
|
export function selectionAnchor(selection: readonly JxPath[] | null | undefined): JxPath | null {
|
|
65
|
-
return selection
|
|
67
|
+
return selection?.[0] ?? null;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
/**
|
|
@@ -187,7 +189,7 @@ export function comparePaths(a: JxPath, b: JxPath): number {
|
|
|
187
189
|
if (x === y) {
|
|
188
190
|
continue;
|
|
189
191
|
}
|
|
190
|
-
if (
|
|
192
|
+
if (isNumber(x) && isNumber(y)) {
|
|
191
193
|
return x - y;
|
|
192
194
|
}
|
|
193
195
|
return String(x) < String(y) ? -1 : 1;
|
|
@@ -231,7 +233,27 @@ export function topLevelSelection(selection: readonly JxPath[]): JxPath[] {
|
|
|
231
233
|
* @returns {boolean}
|
|
232
234
|
*/
|
|
233
235
|
export function isSpliceablePath(path: JxPath): boolean {
|
|
234
|
-
return
|
|
236
|
+
return spliceCoordinate(path) !== null;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Where a structural verb splices: the parent element's path and the index in its children. */
|
|
240
|
+
export interface SpliceCoordinate {
|
|
241
|
+
parentPath: JxPath;
|
|
242
|
+
index: number;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* The splice coordinate `path` names, or `null` for no path and for every path
|
|
247
|
+
* {@link isSpliceablePath} refuses.
|
|
248
|
+
*
|
|
249
|
+
* @param {JxPath | null | undefined} path
|
|
250
|
+
* @returns {SpliceCoordinate | null}
|
|
251
|
+
*/
|
|
252
|
+
export function spliceCoordinate(path: JxPath | null | undefined): SpliceCoordinate | null {
|
|
253
|
+
const index = path?.at(-1);
|
|
254
|
+
return path && path.at(-2) === "children" && isNumber(index)
|
|
255
|
+
? { index, parentPath: path.slice(0, -2) }
|
|
256
|
+
: null;
|
|
235
257
|
}
|
|
236
258
|
|
|
237
259
|
/**
|
|
@@ -289,7 +311,13 @@ export function selectionsEqual(
|
|
|
289
311
|
): boolean {
|
|
290
312
|
const x = a ?? [];
|
|
291
313
|
const y = b ?? [];
|
|
292
|
-
return x.length === y.length && x.every((p, i) => pathsEqual(p, y[i]
|
|
314
|
+
return x.length === y.length && x.every((p, i) => pathsEqual(p, y[i] ?? null));
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** One field's value read across the selection: `mixed` when the selected nodes disagree. */
|
|
318
|
+
export interface UnifiedValue<T> {
|
|
319
|
+
mixed: boolean;
|
|
320
|
+
value: T | undefined;
|
|
293
321
|
}
|
|
294
322
|
|
|
295
323
|
/**
|
|
@@ -306,13 +334,13 @@ export function selectionsEqual(
|
|
|
306
334
|
*
|
|
307
335
|
* @template T
|
|
308
336
|
* @param {readonly T[]} values One per selected node, in selection order.
|
|
309
|
-
* @returns {
|
|
337
|
+
* @returns {UnifiedValue<T>}
|
|
310
338
|
*/
|
|
311
|
-
export function unifyValues<T>(values: readonly T[]):
|
|
339
|
+
export function unifyValues<T>(values: readonly T[]): UnifiedValue<T> {
|
|
312
340
|
if (values.length === 0) {
|
|
313
341
|
return { mixed: false, value: undefined };
|
|
314
342
|
}
|
|
315
|
-
const first = values
|
|
343
|
+
const [first] = values;
|
|
316
344
|
const key = JSON.stringify(first ?? null);
|
|
317
345
|
for (let i = 1; i < values.length; i++) {
|
|
318
346
|
if (JSON.stringify(values[i] ?? null) !== key) {
|