@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/tabs/tab.ts
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
2
|
import { effectScope, reactive } from "../reactivity";
|
|
3
3
|
import { formatByName, formatForPath } from "../format/format-host";
|
|
4
|
-
import {
|
|
4
|
+
import type { FormatFrontmatter } from "../format/format-host";
|
|
5
|
+
import { normalizeDocument } from "./bare-repeaters";
|
|
6
|
+
import type { BareRepeaters } from "./bare-repeaters";
|
|
5
7
|
import type { JxPath } from "../state";
|
|
6
8
|
import type { FormulaEditDef, FunctionEditDef, InlineEditDef, JsonValue } from "../types";
|
|
7
9
|
import { editorKindForMode } from "../commands/context";
|
|
8
10
|
import type { EditorKind } from "../commands/context";
|
|
9
|
-
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
11
|
+
import type { JsonObject, JxMutableNode } from "@jxsuite/schema/types";
|
|
10
12
|
import type { JxDocOp, JxFmOp } from "./patch-ops";
|
|
11
13
|
import type { JsonLayout } from "@jxsuite/schema/json-layout";
|
|
12
14
|
|
|
@@ -14,13 +16,20 @@ import type { JsonLayout } from "@jxsuite/schema/json-layout";
|
|
|
14
16
|
* The project's configuration file, project-relative.
|
|
15
17
|
*
|
|
16
18
|
* Named here rather than at the four places that used to spell it, because it is a DOCUMENT PATH —
|
|
17
|
-
* `inferModes` answers `["stylebook", "source"]` for it (
|
|
18
|
-
* `tabs/project-config.ts` binds the tab at
|
|
19
|
+
* `inferModes` answers `["stylebook", "tokens", "source"]` for it (the Styles workspace's Elements,
|
|
20
|
+
* Variables and Code views; editor kind `config`), and `tabs/project-config.ts` binds the tab at
|
|
21
|
+
* this path as the configuration document.
|
|
19
22
|
*/
|
|
20
23
|
export const PROJECT_CONFIG_PATH = "project.json";
|
|
21
24
|
|
|
22
25
|
export interface TabUi {
|
|
26
|
+
/** The Inspector leaf showing (`shell.ts`'s `INSPECTOR_TAB_IDS`); Page on a fresh tab (§6). */
|
|
23
27
|
rightTab: string;
|
|
28
|
+
/**
|
|
29
|
+
* The Element leaf last shown — Content, Style or Logic — so the selection-driven switch from
|
|
30
|
+
* Page returns to the view the author was using rather than always to Content (§6).
|
|
31
|
+
*/
|
|
32
|
+
elementTab: string;
|
|
24
33
|
canvasMode: string;
|
|
25
34
|
/** Preview toggle — composes with an edit/design canvasMode; the effective mode becomes "preview". */
|
|
26
35
|
preview: boolean;
|
|
@@ -125,7 +134,7 @@ export interface StoredLivePreview {
|
|
|
125
134
|
|
|
126
135
|
interface HistorySnapshot {
|
|
127
136
|
/** Full document at this state (checkpoint), or null when the ops describe the transition. */
|
|
128
|
-
document:
|
|
137
|
+
document: JxMutableNode | null;
|
|
129
138
|
/** Selection after this state's transaction — the whole set, so a batch undoes back to it. */
|
|
130
139
|
selection: (string | number)[][];
|
|
131
140
|
/** Selection before this state's transaction (restored on surgical undo). */
|
|
@@ -177,11 +186,10 @@ export interface Tab {
|
|
|
177
186
|
scope: {
|
|
178
187
|
stop: () => void;
|
|
179
188
|
run: <T>(fn: () => T) => T | undefined;
|
|
180
|
-
[k: string]: unknown;
|
|
181
189
|
};
|
|
182
190
|
doc: {
|
|
183
191
|
document: JxMutableNode;
|
|
184
|
-
content: { frontmatter:
|
|
192
|
+
content: { frontmatter: FormatFrontmatter };
|
|
185
193
|
mode: string;
|
|
186
194
|
sourceFormat: string | null;
|
|
187
195
|
handlersSource: string | null;
|
|
@@ -198,6 +206,22 @@ export interface Tab {
|
|
|
198
206
|
* file.
|
|
199
207
|
*/
|
|
200
208
|
layout: JsonLayout | null;
|
|
209
|
+
/**
|
|
210
|
+
* The text a format-class file (Markdown) was read as, or null for a JSON document, a new
|
|
211
|
+
* document or a stub. The format's serializer is handed it on save
|
|
212
|
+
* (`files/serialize-document.ts`) so every frontmatter key the author did not edit keeps its
|
|
213
|
+
* own spelling and the body keeps its markers (`@jxsuite/parser` `source-style.ts`). The
|
|
214
|
+
* lifetime is `layout`'s: an edit leaves it alone, and a read from disk, a source-view commit,
|
|
215
|
+
* a peer's text or a save replaces it with the text just read or written.
|
|
216
|
+
*/
|
|
217
|
+
source: string | null;
|
|
218
|
+
/**
|
|
219
|
+
* The repeaters the file wrote as a node's whole `children`, which loading rewrote into the
|
|
220
|
+
* member form the editor works in (`tabs/bare-repeaters.ts`); null when it wrote none. A fact
|
|
221
|
+
* about the file with the lifetime `layout` has: a reload or a source-view commit replaces it,
|
|
222
|
+
* an edit or an undo leaves it alone, and a save writes those repeaters back as they were.
|
|
223
|
+
*/
|
|
224
|
+
bareRepeaters: BareRepeaters | null;
|
|
201
225
|
};
|
|
202
226
|
session: {
|
|
203
227
|
/**
|
|
@@ -230,7 +254,7 @@ export interface Tab {
|
|
|
230
254
|
// A serializable snapshot of the iframe's resolved `$defs` (data-source values), posted over
|
|
231
255
|
// The bridge as a `dataScope` message and read by the data-explorer panel. Plain data now —
|
|
232
256
|
// The old live `EffectScope` (with `.stop()`) moved into the iframe realm with buildScope.
|
|
233
|
-
scope:
|
|
257
|
+
scope: JsonObject | null;
|
|
234
258
|
// Latest live (iframe-evaluated) expression previews keyed by editing-target id, stored
|
|
235
259
|
// Beside `scope` the same way (services/live-preview.ts owns reads/writes).
|
|
236
260
|
livePreviews: Record<string, StoredLivePreview> | null;
|
|
@@ -249,7 +273,7 @@ export interface Tab {
|
|
|
249
273
|
* @param {boolean} preview — initial preview-toggle state
|
|
250
274
|
* @returns {TabUi}
|
|
251
275
|
*/
|
|
252
|
-
function createDefaultUi(canvasMode: string, preview = false) {
|
|
276
|
+
function createDefaultUi(canvasMode: string, preview = false): TabUi {
|
|
253
277
|
return {
|
|
254
278
|
activeMedia: null,
|
|
255
279
|
activeSelector: null,
|
|
@@ -264,10 +288,11 @@ function createDefaultUi(canvasMode: string, preview = false) {
|
|
|
264
288
|
pendingInlineEdit: null,
|
|
265
289
|
preview,
|
|
266
290
|
previewColorScheme: "auto" as const,
|
|
267
|
-
previewLocale: null
|
|
291
|
+
previewLocale: null,
|
|
268
292
|
previewParams: {},
|
|
269
293
|
previewProps: null,
|
|
270
|
-
rightTab: "
|
|
294
|
+
rightTab: "page",
|
|
295
|
+
elementTab: "properties",
|
|
271
296
|
showLayout: true,
|
|
272
297
|
styleFilter: "",
|
|
273
298
|
styleSections: {},
|
|
@@ -295,13 +320,14 @@ const ALL_MODES = ["edit", "design", "preview", "source", "stylebook", "git-diff
|
|
|
295
320
|
* id: string;
|
|
296
321
|
* documentPath?: string | null;
|
|
297
322
|
* fileHandle?: FileSystemFileHandle | null;
|
|
298
|
-
* document:
|
|
299
|
-
* frontmatter?:
|
|
323
|
+
* document: JxMutableNode;
|
|
324
|
+
* frontmatter?: FormatFrontmatter;
|
|
300
325
|
* sourceFormat?: string | null;
|
|
301
326
|
* capabilities?: { modes?: string[] };
|
|
302
327
|
* openedFrom?: TabOrigin | null;
|
|
303
328
|
* preview?: boolean;
|
|
304
329
|
* layout?: JsonLayout | null;
|
|
330
|
+
* source?: string | null;
|
|
305
331
|
* }} opts
|
|
306
332
|
* @returns {Tab}
|
|
307
333
|
*/
|
|
@@ -316,71 +342,93 @@ export function createTab({
|
|
|
316
342
|
openedFrom = null,
|
|
317
343
|
preview: previewTab = false,
|
|
318
344
|
layout = null,
|
|
345
|
+
source = null,
|
|
346
|
+
canvasMode,
|
|
319
347
|
}: {
|
|
320
348
|
id: string;
|
|
321
349
|
documentPath?: string | null;
|
|
322
350
|
fileHandle?: FileSystemFileHandle | null;
|
|
323
|
-
document:
|
|
324
|
-
frontmatter?:
|
|
351
|
+
document: JxMutableNode;
|
|
352
|
+
frontmatter?: FormatFrontmatter;
|
|
325
353
|
sourceFormat?: string | null;
|
|
326
354
|
capabilities?: { modes?: string[] };
|
|
327
355
|
openedFrom?: TabOrigin | null;
|
|
328
356
|
preview?: boolean;
|
|
329
357
|
layout?: JsonLayout | null;
|
|
358
|
+
/** The text a format-class file was read as (`doc.source`). */
|
|
359
|
+
source?: string | null;
|
|
360
|
+
/**
|
|
361
|
+
* The mode to open in instead of the first declared one: a comparison opens straight into
|
|
362
|
+
* `git-diff`, so the tab is never active in an edit mode that belongs to another workspace.
|
|
363
|
+
*/
|
|
364
|
+
canvasMode?: string | undefined;
|
|
330
365
|
}) {
|
|
331
366
|
const scope = effectScope();
|
|
332
367
|
|
|
333
368
|
// Normalize legacy whole-children repeaters to the canonical array-member form before the doc
|
|
334
369
|
// (and its first history checkpoint) are stored.
|
|
335
|
-
|
|
370
|
+
const bareRepeaters = normalizeDocument(document);
|
|
336
371
|
|
|
337
372
|
const resolvedModes = capabilities?.modes ?? inferModes(documentPath, sourceFormat);
|
|
338
373
|
// A tab opens in its first allowed mode — never one the toolbar would disable.
|
|
339
374
|
// Formats author mode order so the default comes first (edit, stylebook, etc.).
|
|
340
375
|
// "preview" is a per-tab toggle rather than a base mode: a preview-first format opens
|
|
341
376
|
// In its first non-preview mode with the toggle already on.
|
|
342
|
-
const initialCanvasMode = resolvedModes.find((m) => m !== "preview") ?? "edit";
|
|
377
|
+
const initialCanvasMode = canvasMode ?? resolvedModes.find((m) => m !== "preview") ?? "edit";
|
|
343
378
|
const initialPreview = resolvedModes[0] === "preview";
|
|
344
379
|
|
|
380
|
+
const doc: Tab["doc"] = {
|
|
381
|
+
bareRepeaters,
|
|
382
|
+
content: { frontmatter: frontmatter || {} },
|
|
383
|
+
dirty: false,
|
|
384
|
+
document,
|
|
385
|
+
handlersSource: null,
|
|
386
|
+
layout,
|
|
387
|
+
mode: inferDocumentMode(documentPath, sourceFormat),
|
|
388
|
+
source,
|
|
389
|
+
sourceFormat,
|
|
390
|
+
};
|
|
391
|
+
const history: Tab["history"] = {
|
|
392
|
+
index: 0,
|
|
393
|
+
snapshots: [{ document: structuredClone(document), selection: [] }],
|
|
394
|
+
};
|
|
395
|
+
const session: Tab["session"] = {
|
|
396
|
+
canvas: {
|
|
397
|
+
refreshing: false,
|
|
398
|
+
error: null,
|
|
399
|
+
livePreviews: null,
|
|
400
|
+
pendingInlineEdit: null,
|
|
401
|
+
scope: null,
|
|
402
|
+
status: "idle",
|
|
403
|
+
},
|
|
404
|
+
clipboard: null,
|
|
405
|
+
hover: null,
|
|
406
|
+
openedFrom,
|
|
407
|
+
selection: [],
|
|
408
|
+
ui: createDefaultUi(initialCanvasMode, initialPreview),
|
|
409
|
+
};
|
|
410
|
+
|
|
411
|
+
/* SAFETY: `reactive()` returns a deep proxy carrying its target's own members, and none of these
|
|
412
|
+
Three trees holds a ref for `UnwrapNestedRefs` to unwrap, so each proxy IS the shape it is cast
|
|
413
|
+
To. The type argument is pinned to `object` because `UnwrapNestedRefs<JxMutableNode>` recurses
|
|
414
|
+
Deeply enough for tsc to give up (TS2589); the proxies are deep either way. */
|
|
345
415
|
const tab = scope.run(() => ({
|
|
346
416
|
capabilities: { modes: resolvedModes },
|
|
347
|
-
doc: reactive(
|
|
348
|
-
content: { frontmatter: frontmatter || {} },
|
|
349
|
-
dirty: false,
|
|
350
|
-
document,
|
|
351
|
-
handlersSource: null,
|
|
352
|
-
layout,
|
|
353
|
-
mode: inferDocumentMode(documentPath, sourceFormat),
|
|
354
|
-
sourceFormat,
|
|
355
|
-
}),
|
|
417
|
+
doc: reactive<object>(doc) as Tab["doc"],
|
|
356
418
|
documentPath,
|
|
357
419
|
fileHandle,
|
|
358
|
-
history: reactive(
|
|
359
|
-
index: 0,
|
|
360
|
-
snapshots: [{ document: structuredClone(document), selection: [] }],
|
|
361
|
-
}),
|
|
420
|
+
history: reactive<object>(history) as Tab["history"],
|
|
362
421
|
id,
|
|
363
422
|
pinned: false,
|
|
364
423
|
preview: previewTab,
|
|
365
424
|
scope,
|
|
366
|
-
session: reactive(
|
|
367
|
-
|
|
368
|
-
refreshing: false,
|
|
369
|
-
error: null,
|
|
370
|
-
livePreviews: null,
|
|
371
|
-
pendingInlineEdit: null,
|
|
372
|
-
scope: null,
|
|
373
|
-
status: "idle",
|
|
374
|
-
},
|
|
375
|
-
clipboard: null,
|
|
376
|
-
hover: null,
|
|
377
|
-
openedFrom,
|
|
378
|
-
selection: [],
|
|
379
|
-
ui: createDefaultUi(initialCanvasMode, initialPreview),
|
|
380
|
-
}),
|
|
381
|
-
})) as unknown as Tab;
|
|
425
|
+
session: reactive<object>(session) as Tab["session"],
|
|
426
|
+
}));
|
|
382
427
|
|
|
383
|
-
|
|
428
|
+
/* SAFETY: `scope` was created at the top of this function and nothing has stopped it, and an
|
|
429
|
+
Active scope's `run` always returns its callback's value; `undefined` is only what an inactive
|
|
430
|
+
Scope answers. */
|
|
431
|
+
return tab as Tab;
|
|
384
432
|
}
|
|
385
433
|
|
|
386
434
|
/**
|
|
@@ -393,7 +441,10 @@ export function createTab({
|
|
|
393
441
|
*/
|
|
394
442
|
function inferModes(documentPath: string | null | undefined, sourceFormat: string | null) {
|
|
395
443
|
if (documentPath === PROJECT_CONFIG_PATH) {
|
|
396
|
-
|
|
444
|
+
/* Elements, Variables and Code: the Styles workspace's three views. Spelled here rather than
|
|
445
|
+
imported from `style/project-styles` (`STYLES_TAB_MODES`), whose imports reach `store`,
|
|
446
|
+
which imports this module; `tests/project-config.test.ts` holds the two lists equal. */
|
|
447
|
+
return ["stylebook", "tokens", "source"];
|
|
397
448
|
}
|
|
398
449
|
const format = formatByName(sourceFormat) ?? formatForPath(documentPath);
|
|
399
450
|
if (format) {
|
package/src/tabs/transact.ts
CHANGED
|
@@ -4,9 +4,9 @@ import { jsonClone } from "../utils/studio-utils";
|
|
|
4
4
|
import { childIndex, getNodeAtPath, parentElementPath, pathsEqual } from "../state";
|
|
5
5
|
import {
|
|
6
6
|
cloneSelection,
|
|
7
|
-
isSpliceablePath,
|
|
8
7
|
primarySelection,
|
|
9
8
|
pruneSelection,
|
|
9
|
+
spliceCoordinate,
|
|
10
10
|
structuralBatch,
|
|
11
11
|
} from "./selection";
|
|
12
12
|
import { applyDocOpToDoc, childArray, cloneValue, inverseOf } from "./doc-op-apply";
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
recordPatch,
|
|
20
20
|
} from "./patch-ops";
|
|
21
21
|
|
|
22
|
-
import type { JxDocOp, JxDocOpPair,
|
|
22
|
+
import type { JxDocOp, JxDocOpPair, TransactionRecord } from "./patch-ops";
|
|
23
23
|
|
|
24
24
|
import type { Tab } from "../tabs/tab";
|
|
25
25
|
import type { JxPath } from "../state";
|
|
@@ -27,12 +27,19 @@ import type { JxPath } from "../state";
|
|
|
27
27
|
import type { JsonValue } from "../types";
|
|
28
28
|
import type {
|
|
29
29
|
JxAttributeValue,
|
|
30
|
+
JxDocumentValue,
|
|
30
31
|
JxEventBinding,
|
|
31
32
|
JxMutableNode,
|
|
32
33
|
JxStateObject,
|
|
33
34
|
JxStyle,
|
|
34
35
|
} from "@jxsuite/schema/types";
|
|
35
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
ensureNestedStyle,
|
|
38
|
+
getNestedStyle,
|
|
39
|
+
isEventBinding,
|
|
40
|
+
isNonNullObject,
|
|
41
|
+
isNumber,
|
|
42
|
+
} from "@jxsuite/schema/guards";
|
|
36
43
|
|
|
37
44
|
const HISTORY_LIMIT = 100;
|
|
38
45
|
|
|
@@ -48,8 +55,26 @@ function patchHistoryEnabled() {
|
|
|
48
55
|
}
|
|
49
56
|
}
|
|
50
57
|
|
|
58
|
+
/**
|
|
59
|
+
* The node `path` names, for a mutation that cannot proceed without one. A path that no longer
|
|
60
|
+
* resolves throws a TypeError inside the transaction, which rolls the transaction back, exactly as
|
|
61
|
+
* dereferencing the missing node did before this check existed.
|
|
62
|
+
*/
|
|
63
|
+
function requireNodeAt(doc: JxMutableNode, path: JxPath): JxMutableNode {
|
|
64
|
+
const node = getNodeAtPath(doc, path);
|
|
65
|
+
if (!node) {
|
|
66
|
+
throw new TypeError(`No node at path [${path.join(", ")}]`);
|
|
67
|
+
}
|
|
68
|
+
return node;
|
|
69
|
+
}
|
|
70
|
+
|
|
51
71
|
/** Forward/inverse pair for a single-key change on the node at path. */
|
|
52
|
-
function setKeyPair(
|
|
72
|
+
function setKeyPair(
|
|
73
|
+
path: JxPath,
|
|
74
|
+
key: string,
|
|
75
|
+
before: JxDocumentValue | undefined,
|
|
76
|
+
after: JxDocumentValue | undefined,
|
|
77
|
+
): JxDocOpPair {
|
|
53
78
|
return {
|
|
54
79
|
forward: { key, op: "set-key", path, value: after },
|
|
55
80
|
inverse: { key, op: "set-key", path, value: before },
|
|
@@ -71,10 +96,10 @@ function shiftPrefixedIndex(
|
|
|
71
96
|
): JxPath {
|
|
72
97
|
const d = parentPath.length;
|
|
73
98
|
const isProperPrefix = d < path.length && parentPath.every((seg, i) => seg === path[i]);
|
|
74
|
-
|
|
99
|
+
const idx = path[d + 1];
|
|
100
|
+
if (!isProperPrefix || path[d] !== "children" || !isNumber(idx)) {
|
|
75
101
|
return path;
|
|
76
102
|
}
|
|
77
|
-
const idx = path[d + 1] as number;
|
|
78
103
|
if (inclusive ? idx < spliceIndex : idx <= spliceIndex) {
|
|
79
104
|
return path;
|
|
80
105
|
}
|
|
@@ -152,7 +177,7 @@ function rollbackFailedTransaction(
|
|
|
152
177
|
dirtyBefore: boolean,
|
|
153
178
|
) {
|
|
154
179
|
for (let i = record.docOps.length - 1; i >= 0; i--) {
|
|
155
|
-
applyDocOpToDoc(tab.doc.document, toRaw(record.docOps[i]!.inverse)
|
|
180
|
+
applyDocOpToDoc(tab.doc.document, toRaw(record.docOps[i]!.inverse));
|
|
156
181
|
}
|
|
157
182
|
for (let i = record.fmOps.length - 1; i >= 0; i--) {
|
|
158
183
|
const op = record.fmOps[i]!;
|
|
@@ -355,10 +380,11 @@ function materializeState(
|
|
|
355
380
|
while (base >= 0 && !snapshots[base]!.document) {
|
|
356
381
|
base -= 1;
|
|
357
382
|
}
|
|
358
|
-
|
|
383
|
+
const checkpoint = base < 0 ? null : snapshots[base]!.document;
|
|
384
|
+
if (!checkpoint) {
|
|
359
385
|
throw new Error("history-missing-checkpoint");
|
|
360
386
|
}
|
|
361
|
-
const doc = jsonClone(
|
|
387
|
+
const doc = jsonClone(checkpoint);
|
|
362
388
|
for (let i = base + 1; i <= target; i++) {
|
|
363
389
|
for (const op of snapshots[i]!.forwardOps ?? []) {
|
|
364
390
|
applyDocOpToDoc(doc, op);
|
|
@@ -418,8 +444,11 @@ const DOC_META_KEYS = new Set(["state", "$media", "$head", "$elements", "imports
|
|
|
418
444
|
* @param {JxDocOp} op
|
|
419
445
|
*/
|
|
420
446
|
function applyDocOp(tab: Tab, op: JxDocOp) {
|
|
421
|
-
|
|
422
|
-
|
|
447
|
+
let prev: JxDocumentValue | undefined | null = null;
|
|
448
|
+
if (op.op === "set-key") {
|
|
449
|
+
const node = getNodeAtPath(tab.doc.document, op.path);
|
|
450
|
+
prev = node?.[op.key];
|
|
451
|
+
}
|
|
423
452
|
applyDocOpToDoc(tab.doc.document, op);
|
|
424
453
|
// The canvas lives in an iframe and can only be patched from VALUE-CARRYING ops (`record.docOps`),
|
|
425
454
|
// Which is what crosses the bridge. Recording only the classification patch below left docOps
|
|
@@ -617,12 +646,12 @@ export function undo(tab: Tab) {
|
|
|
617
646
|
(t) => {
|
|
618
647
|
if (inverseOps) {
|
|
619
648
|
for (let i = inverseOps.length - 1; i >= 0; i--) {
|
|
620
|
-
applyDocOp(t, toRaw(inverseOps[i])
|
|
649
|
+
applyDocOp(t, toRaw(inverseOps[i]!));
|
|
621
650
|
}
|
|
622
651
|
}
|
|
623
652
|
if (fmOps) {
|
|
624
653
|
for (let i = fmOps.length - 1; i >= 0; i--) {
|
|
625
|
-
const op = toRaw(fmOps[i])
|
|
654
|
+
const op = toRaw(fmOps[i]!);
|
|
626
655
|
applyFmState(t, op.field, op.before);
|
|
627
656
|
}
|
|
628
657
|
}
|
|
@@ -666,12 +695,12 @@ export function redo(tab: Tab) {
|
|
|
666
695
|
(t) => {
|
|
667
696
|
if (forwardOps) {
|
|
668
697
|
for (const op of forwardOps) {
|
|
669
|
-
applyDocOp(t, toRaw(op)
|
|
698
|
+
applyDocOp(t, toRaw(op));
|
|
670
699
|
}
|
|
671
700
|
}
|
|
672
701
|
if (fmOps) {
|
|
673
702
|
for (const op of fmOps) {
|
|
674
|
-
const raw = toRaw(op)
|
|
703
|
+
const raw = toRaw(op);
|
|
675
704
|
applyFmState(t, raw.field, raw.after);
|
|
676
705
|
}
|
|
677
706
|
}
|
|
@@ -731,15 +760,20 @@ export function mutateInsertNode(
|
|
|
731
760
|
* @param {JxPath} path
|
|
732
761
|
*/
|
|
733
762
|
export function mutateRemoveNode(tab: Tab, path: JxPath) {
|
|
734
|
-
|
|
763
|
+
const at = spliceCoordinate(path);
|
|
764
|
+
if (!at) {
|
|
735
765
|
return;
|
|
736
766
|
}
|
|
737
|
-
const elemPath =
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
767
|
+
const { index: idx, parentPath: elemPath } = at;
|
|
768
|
+
/* SAFETY: a spliceable path addresses a member of its parent's children, and every document a
|
|
769
|
+
tab holds is in the static-array member form (`normalizeArrayChildren` runs on load), so the
|
|
770
|
+
parent resolves to a node whose children are an array. The paths that reach here are live ones
|
|
771
|
+
(the pruned selection, an inline edit's own block), so the index names a member and the splice
|
|
772
|
+
removes exactly one. A stale parent path throws (`requireNodeAt`), inside the transaction, which
|
|
773
|
+
rolls back. */
|
|
774
|
+
const [removed] = (
|
|
775
|
+
requireNodeAt(tab.doc.document, elemPath).children as (JxMutableNode | string)[]
|
|
776
|
+
).splice(idx, 1) as [JxMutableNode | string];
|
|
743
777
|
recordPatch({ op: "remove", path });
|
|
744
778
|
recordDocOp({
|
|
745
779
|
forward: { index: idx, op: "remove-child", parentPath: elemPath },
|
|
@@ -753,17 +787,19 @@ export function mutateRemoveNode(tab: Tab, path: JxPath) {
|
|
|
753
787
|
* @param {JxPath} path
|
|
754
788
|
*/
|
|
755
789
|
export function mutateDuplicateNode(tab: Tab, path: JxPath) {
|
|
756
|
-
|
|
790
|
+
const at = spliceCoordinate(path);
|
|
791
|
+
if (!at) {
|
|
757
792
|
return;
|
|
758
793
|
}
|
|
759
794
|
const node = getNodeAtPath(tab.doc.document, path);
|
|
760
795
|
if (!node) {
|
|
761
796
|
return;
|
|
762
797
|
}
|
|
763
|
-
const elemPath =
|
|
764
|
-
const idx = childIndex(path) as number;
|
|
798
|
+
const { index: idx, parentPath: elemPath } = at;
|
|
765
799
|
const clone = structuredClone(toRaw(node));
|
|
766
|
-
|
|
800
|
+
/* SAFETY: `node` resolved above, so its parent does too, and every document a tab holds keeps
|
|
801
|
+
static children arrays (`normalizeArrayChildren` runs on load) — `node` is a member of one. */
|
|
802
|
+
(requireNodeAt(tab.doc.document, elemPath).children as JxMutableNode[]).splice(idx + 1, 0, clone);
|
|
767
803
|
recordPatch({ index: idx + 1, op: "insert", parentPath: elemPath });
|
|
768
804
|
recordDocOp({
|
|
769
805
|
forward: { index: idx + 1, node: cloneValue(clone), op: "insert-child", parentPath: elemPath },
|
|
@@ -813,17 +849,16 @@ export function mutateDuplicateNodes(tab: Tab, paths: readonly JxPath[]) {
|
|
|
813
849
|
const before = tab.session.selection;
|
|
814
850
|
mutateDuplicateNode(tab, path);
|
|
815
851
|
const made = primarySelection(tab.session.selection);
|
|
852
|
+
const at = spliceCoordinate(made);
|
|
816
853
|
// `mutateDuplicateNode` refuses a path that addresses nothing and leaves the selection alone;
|
|
817
|
-
// Only a real insertion contributes a clone.
|
|
818
|
-
if (!made || tab.session.selection === before) {
|
|
854
|
+
// Only a real insertion contributes a clone, and it selects the clone at a splice coordinate.
|
|
855
|
+
if (!made || !at || tab.session.selection === before) {
|
|
819
856
|
continue;
|
|
820
857
|
}
|
|
821
858
|
// Descending order keeps the ORIGINALS valid, but not the clones already made: this insertion
|
|
822
859
|
// Sits before them, so every one of their coordinates moved up by one. Translating them here
|
|
823
860
|
// Is the difference between "the copies are selected" and "two of the originals are".
|
|
824
|
-
|
|
825
|
-
const spliceIndex = childIndex(made) as number;
|
|
826
|
-
clones = clones.map((clone) => shiftPrefixedIndex(parentPath, clone, spliceIndex, 1, true));
|
|
861
|
+
clones = clones.map((clone) => shiftPrefixedIndex(at.parentPath, clone, at.index, 1, true));
|
|
827
862
|
clones.unshift(made);
|
|
828
863
|
}
|
|
829
864
|
if (clones.length > 0) {
|
|
@@ -837,21 +872,23 @@ export function mutateDuplicateNodes(tab: Tab, paths: readonly JxPath[]) {
|
|
|
837
872
|
* @param {string} wrapperTag
|
|
838
873
|
*/
|
|
839
874
|
export function mutateWrapNode(tab: Tab, path: JxPath, wrapperTag = "div") {
|
|
840
|
-
|
|
875
|
+
const at = spliceCoordinate(path);
|
|
876
|
+
if (!at) {
|
|
841
877
|
return;
|
|
842
878
|
}
|
|
843
879
|
const node = getNodeAtPath(tab.doc.document, path);
|
|
844
880
|
if (!node) {
|
|
845
881
|
return;
|
|
846
882
|
}
|
|
847
|
-
const elemPath =
|
|
848
|
-
const idx = childIndex(path) as number;
|
|
883
|
+
const { index: idx, parentPath: elemPath } = at;
|
|
849
884
|
const wrapper = {
|
|
850
885
|
children: [structuredClone(toRaw(node))],
|
|
851
886
|
tagName: wrapperTag,
|
|
852
887
|
};
|
|
853
888
|
const original = cloneValue(node);
|
|
854
|
-
|
|
889
|
+
/* SAFETY: `node` resolved above, so its parent does too, and every document a tab holds keeps
|
|
890
|
+
static children arrays (`normalizeArrayChildren` runs on load) — `node` is a member of one. */
|
|
891
|
+
(requireNodeAt(tab.doc.document, elemPath).children as JxMutableNode[]).splice(idx, 1, wrapper);
|
|
855
892
|
recordPatch({ op: "replace", path });
|
|
856
893
|
recordDocOp({
|
|
857
894
|
forward: { index: idx, node: cloneValue(wrapper), op: "set-child", parentPath: elemPath },
|
|
@@ -868,9 +905,9 @@ export function mutateWrapNode(tab: Tab, path: JxPath, wrapperTag = "div") {
|
|
|
868
905
|
*/
|
|
869
906
|
export function mutateMoveNode(tab: Tab, fromPath: JxPath, toParentPath: JxPath, toIndex: number) {
|
|
870
907
|
const doc = tab.doc.document;
|
|
871
|
-
const fromParentPath = parentElementPath(fromPath)
|
|
872
|
-
const fromIdx = childIndex(fromPath)
|
|
873
|
-
if (!fromParentPath ||
|
|
908
|
+
const fromParentPath = parentElementPath(fromPath);
|
|
909
|
+
const fromIdx = childIndex(fromPath);
|
|
910
|
+
if (!fromParentPath || !isNumber(fromIdx)) {
|
|
874
911
|
return;
|
|
875
912
|
}
|
|
876
913
|
const fromParent = getNodeAtPath(doc, fromParentPath);
|
|
@@ -967,7 +1004,7 @@ export function mutateUpdateProperty(tab: Tab, path: JxPath, key: string, value?
|
|
|
967
1004
|
* @param {string | undefined} value
|
|
968
1005
|
*/
|
|
969
1006
|
export function mutateUpdateStyle(tab: Tab, path: JxPath, prop: string, value: string | undefined) {
|
|
970
|
-
const node =
|
|
1007
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
971
1008
|
const styleBefore = cloneValue(node.style);
|
|
972
1009
|
if (!node.style) {
|
|
973
1010
|
node.style = {};
|
|
@@ -996,7 +1033,7 @@ export function mutateUpdateAttribute(
|
|
|
996
1033
|
attr: string,
|
|
997
1034
|
value?: JxAttributeValue | undefined,
|
|
998
1035
|
) {
|
|
999
|
-
const node =
|
|
1036
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1000
1037
|
const attrsBefore = cloneValue(node.attributes);
|
|
1001
1038
|
if (!node.attributes) {
|
|
1002
1039
|
node.attributes = {};
|
|
@@ -1030,7 +1067,7 @@ export function mutateUpdateMediaStyle(
|
|
|
1030
1067
|
if (!mediaName) {
|
|
1031
1068
|
return mutateUpdateStyle(tab, path, prop, value);
|
|
1032
1069
|
}
|
|
1033
|
-
const node =
|
|
1070
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1034
1071
|
const styleBefore = cloneValue(node.style);
|
|
1035
1072
|
if (!node.style) {
|
|
1036
1073
|
node.style = {};
|
|
@@ -1066,7 +1103,7 @@ export function mutateUpdateNestedStyle(
|
|
|
1066
1103
|
prop: string,
|
|
1067
1104
|
value: string | undefined,
|
|
1068
1105
|
) {
|
|
1069
|
-
const node =
|
|
1106
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1070
1107
|
const styleBefore = cloneValue(node.style);
|
|
1071
1108
|
if (!node.style) {
|
|
1072
1109
|
node.style = {};
|
|
@@ -1103,7 +1140,7 @@ export function mutateUpdateMediaNestedStyle(
|
|
|
1103
1140
|
prop: string,
|
|
1104
1141
|
value: string | undefined,
|
|
1105
1142
|
) {
|
|
1106
|
-
const node =
|
|
1143
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1107
1144
|
const styleBefore = cloneValue(node.style);
|
|
1108
1145
|
if (!node.style) {
|
|
1109
1146
|
node.style = {};
|
|
@@ -1186,7 +1223,7 @@ export function mutateUpdateNestedStylePath(
|
|
|
1186
1223
|
prop: string,
|
|
1187
1224
|
value: string | undefined,
|
|
1188
1225
|
) {
|
|
1189
|
-
const node =
|
|
1226
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1190
1227
|
const styleBefore = cloneValue(node.style);
|
|
1191
1228
|
if (!node.style) {
|
|
1192
1229
|
node.style = {};
|
|
@@ -1226,7 +1263,7 @@ export function mutateUpdateMediaNestedStylePath(
|
|
|
1226
1263
|
prop: string,
|
|
1227
1264
|
value: string | undefined,
|
|
1228
1265
|
) {
|
|
1229
|
-
const node =
|
|
1266
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1230
1267
|
const styleBefore = cloneValue(node.style);
|
|
1231
1268
|
if (!node.style) {
|
|
1232
1269
|
node.style = {};
|
|
@@ -1259,7 +1296,7 @@ export function mutateUpdateMediaNestedStylePath(
|
|
|
1259
1296
|
* @param {Record<string, string | undefined> | undefined} style
|
|
1260
1297
|
*/
|
|
1261
1298
|
export function mutateReplaceStyle(tab: Tab, path: JxPath, style: JxStyle | undefined) {
|
|
1262
|
-
const node =
|
|
1299
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1263
1300
|
const styleBefore = cloneValue(node.style);
|
|
1264
1301
|
if (style && Object.keys(style).length > 0) {
|
|
1265
1302
|
node.style = style;
|
|
@@ -1308,17 +1345,25 @@ export function mutateRemoveDef(tab: Tab, name: string) {
|
|
|
1308
1345
|
* @param {string} name
|
|
1309
1346
|
* @param {Record<string, JsonValue>} updates
|
|
1310
1347
|
*/
|
|
1311
|
-
export function mutateUpdateDef(
|
|
1348
|
+
export function mutateUpdateDef(
|
|
1349
|
+
tab: Tab,
|
|
1350
|
+
name: string,
|
|
1351
|
+
updates: Record<string, JxDocumentValue | undefined>,
|
|
1352
|
+
) {
|
|
1312
1353
|
const doc = tab.doc.document;
|
|
1313
1354
|
const stateBefore = cloneValue(doc.state);
|
|
1314
1355
|
if (!doc.state) {
|
|
1315
1356
|
doc.state = {};
|
|
1316
1357
|
}
|
|
1317
1358
|
const existing = doc.state[name];
|
|
1359
|
+
/* SAFETY: what is left after null, primitives and arrays is one of the object entry forms (an
|
|
1360
|
+
expanded signal, or a function, prototype, expression or server-function def). Each is a plain
|
|
1361
|
+
record whose keys the loop below edits one by one, and JxStateObject is the open record that
|
|
1362
|
+
edit needs; nothing here relies on a member that only one of the forms carries. */
|
|
1318
1363
|
const entry: JxStateObject =
|
|
1319
1364
|
existing == null
|
|
1320
1365
|
? {}
|
|
1321
|
-
:
|
|
1366
|
+
: !isNonNullObject(existing) || Array.isArray(existing)
|
|
1322
1367
|
? { default: existing }
|
|
1323
1368
|
: (existing as JxStateObject);
|
|
1324
1369
|
doc.state[name] = entry;
|
|
@@ -1379,7 +1424,7 @@ export function mutateUpdateMedia(tab: Tab, name: string, query?: string | undef
|
|
|
1379
1424
|
* @param {JsonValue} value
|
|
1380
1425
|
*/
|
|
1381
1426
|
export function mutateUpdateProp(tab: Tab, path: JxPath, propName: string, value: JsonValue) {
|
|
1382
|
-
const node =
|
|
1427
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1383
1428
|
const propsBefore = cloneValue(node.$props);
|
|
1384
1429
|
if (!node.$props) {
|
|
1385
1430
|
node.$props = {};
|
|
@@ -1408,7 +1453,7 @@ export function mutateAddSwitchCase(
|
|
|
1408
1453
|
caseName: string,
|
|
1409
1454
|
caseDef?: JxMutableNode,
|
|
1410
1455
|
) {
|
|
1411
|
-
const node =
|
|
1456
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1412
1457
|
const before = cloneValue(node.cases);
|
|
1413
1458
|
if (!node.cases) {
|
|
1414
1459
|
node.cases = {};
|
|
@@ -1424,7 +1469,7 @@ export function mutateAddSwitchCase(
|
|
|
1424
1469
|
* @param {string} caseName
|
|
1425
1470
|
*/
|
|
1426
1471
|
export function mutateRemoveSwitchCase(tab: Tab, path: JxPath, caseName: string) {
|
|
1427
|
-
const node =
|
|
1472
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1428
1473
|
if (node.cases) {
|
|
1429
1474
|
const before = cloneValue(node.cases);
|
|
1430
1475
|
delete node.cases[caseName];
|
|
@@ -1440,7 +1485,7 @@ export function mutateRemoveSwitchCase(tab: Tab, path: JxPath, caseName: string)
|
|
|
1440
1485
|
* @param {string} newName
|
|
1441
1486
|
*/
|
|
1442
1487
|
export function mutateRenameSwitchCase(tab: Tab, path: JxPath, oldName: string, newName: string) {
|
|
1443
|
-
const node =
|
|
1488
|
+
const node = requireNodeAt(tab.doc.document, path);
|
|
1444
1489
|
if (!node.cases || !node.cases[oldName]) {
|
|
1445
1490
|
return;
|
|
1446
1491
|
}
|
|
@@ -1479,7 +1524,7 @@ export function mutateUpdateFrontmatter(tab: Tab, field: string, value?: JsonVal
|
|
|
1479
1524
|
* Unlike `mutateUpdateFrontmatter`, values like `""`/`false`/`null` are written verbatim (source
|
|
1480
1525
|
* round-trips can put them there) and no fm op is recorded — history replay must not re-record.
|
|
1481
1526
|
*/
|
|
1482
|
-
function applyFmState(tab: Tab, field: string, value:
|
|
1527
|
+
function applyFmState(tab: Tab, field: string, value: JxDocumentValue | undefined) {
|
|
1483
1528
|
if (value === undefined) {
|
|
1484
1529
|
delete tab.doc.content.frontmatter[field];
|
|
1485
1530
|
} else {
|