@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
|
@@ -12,16 +12,7 @@
|
|
|
12
12
|
import type { AssetContext } from "./asset-resolve";
|
|
13
13
|
import type { JxDocOp } from "../tabs/patch-ops";
|
|
14
14
|
import type { JxContentResult, SlashCommand } from "../editor/inline-edit";
|
|
15
|
-
import type { JxExpressionNode, JxMutableNode } from "@jxsuite/schema/types";
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* The wire form of a value-carrying document op (the `forward` half of a recorded
|
|
19
|
-
* {@link JxDocOpPair} — see {@link file://../tabs/patch-ops.ts}). It is structurally a
|
|
20
|
-
* {@link JxDocOp}: it carries the inserted/replaced `node` and the set `value`, NOT just a path, so
|
|
21
|
-
* the iframe can fold it into its shadow doc and re-render subtrees without ever reading the
|
|
22
|
-
* parent's reactive document.
|
|
23
|
-
*/
|
|
24
|
-
export type WireDocOp = JxDocOp;
|
|
15
|
+
import type { JsonObject, JxExpressionNode, JxMutableNode, JxStyle } from "@jxsuite/schema/types";
|
|
25
16
|
|
|
26
17
|
export const CANVAS_MODES = ["preview", "design", "edit", "stylebook", "git-diff"] as const;
|
|
27
18
|
|
|
@@ -37,7 +28,7 @@ export const CANVAS_MODES = ["preview", "design", "edit", "stylebook", "git-diff
|
|
|
37
28
|
export type CanvasMode = (typeof CANVAS_MODES)[number];
|
|
38
29
|
|
|
39
30
|
export function isCanvasMode(value: unknown): value is CanvasMode {
|
|
40
|
-
return typeof value === "string" && (
|
|
31
|
+
return typeof value === "string" && CANVAS_MODES.some((mode) => mode === value);
|
|
41
32
|
}
|
|
42
33
|
|
|
43
34
|
/**
|
|
@@ -86,6 +77,12 @@ export interface WireDiffMark {
|
|
|
86
77
|
/** An artboard's whole mark set. Each side receives only its own; `[]` clears. */
|
|
87
78
|
export type WireDiffMarks = readonly WireDiffMark[];
|
|
88
79
|
|
|
80
|
+
/** A language as the frame applies it: the BCP 47 tag for `lang`, and its direction for `dir`. */
|
|
81
|
+
export interface WireLocale {
|
|
82
|
+
locale: string;
|
|
83
|
+
dir: "ltr" | "rtl";
|
|
84
|
+
}
|
|
85
|
+
|
|
89
86
|
/** Messages the editor (parent) sends into the canvas iframe. */
|
|
90
87
|
export type ParentToIframe =
|
|
91
88
|
| { kind: "init"; gen: number }
|
|
@@ -121,7 +118,7 @@ export type ParentToIframe =
|
|
|
121
118
|
*/
|
|
122
119
|
assets?: AssetContext | null;
|
|
123
120
|
mapperCtx: WireMapperCtx;
|
|
124
|
-
siteStyle:
|
|
121
|
+
siteStyle: JxStyle | null;
|
|
125
122
|
// Forced color-scheme preview (spec.md §9.5): "light"/"dark" sets data-color-scheme on the
|
|
126
123
|
// Iframe root, null clears it (auto — follow the OS).
|
|
127
124
|
colorScheme: "light" | "dark" | null;
|
|
@@ -144,6 +141,13 @@ export type ParentToIframe =
|
|
|
144
141
|
* every re-render would close the panel the author is editing.
|
|
145
142
|
*/
|
|
146
143
|
popoverOpen?: (string | number)[] | null;
|
|
144
|
+
/**
|
|
145
|
+
* The language the artboard is drawn in, carried on `render` for `colorScheme`'s reason: a
|
|
146
|
+
* frame that boots after the pane's locale was posted (a new host, a reload) would otherwise
|
|
147
|
+
* draw an Arabic document left to right until the locale next CHANGED. Absent or null clears
|
|
148
|
+
* `lang` and `dir`.
|
|
149
|
+
*/
|
|
150
|
+
locale?: WireLocale | null;
|
|
147
151
|
/** The dialog to draw open after this render, for the same reason. */
|
|
148
152
|
dialogOpen?: (string | number)[] | null;
|
|
149
153
|
gen: number;
|
|
@@ -197,8 +201,10 @@ export type ParentToIframe =
|
|
|
197
201
|
* the frame — `localeDirection` is CLDR's answer via `Intl.Locale`, and the frame has no reason
|
|
198
202
|
* to hold a second copy of the RTL script list.
|
|
199
203
|
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
204
|
+
* The host posts the language the pane DRAWS, not only an override: the preview choice, else the
|
|
205
|
+
* file's own, else the site default (`canvasLocaleOf`). `null` is a project that declares no
|
|
206
|
+
* locales: both attributes come off, and the frame falls back to whatever the rendered document
|
|
207
|
+
* declares.
|
|
202
208
|
*/
|
|
203
209
|
| { kind: "setLocale"; locale: string | null; dir: "ltr" | "rtl" }
|
|
204
210
|
/**
|
|
@@ -239,7 +245,7 @@ export type ParentToIframe =
|
|
|
239
245
|
// Render-free; the superseding render carries the same style via its own siteStyle.
|
|
240
246
|
| {
|
|
241
247
|
kind: "siteStyleUpdate";
|
|
242
|
-
siteStyle:
|
|
248
|
+
siteStyle: JxStyle | null;
|
|
243
249
|
media: Record<string, string>;
|
|
244
250
|
}
|
|
245
251
|
// Ask the iframe to measure the given document paths and post their current rects back. Used to
|
|
@@ -255,7 +261,12 @@ export type ParentToIframe =
|
|
|
255
261
|
// In place. `gen` matches the last render so the iframe drops patches superseded by a re-render.
|
|
256
262
|
| {
|
|
257
263
|
kind: "patch";
|
|
258
|
-
|
|
264
|
+
/**
|
|
265
|
+
* The `forward` halves of the recorded {@link JxDocOp} pairs (tabs/patch-ops.ts). Each carries
|
|
266
|
+
* the inserted/replaced `node` and the set `value`, not just a path, so the iframe folds it
|
|
267
|
+
* into its shadow doc without ever reading the parent's reactive document.
|
|
268
|
+
*/
|
|
269
|
+
forwardOps: JxDocOp[];
|
|
259
270
|
gen: number;
|
|
260
271
|
/**
|
|
261
272
|
* Paths whose DOM the RECIPIENT already has correct, because this patch is the echo of an
|
|
@@ -273,7 +284,7 @@ export type ParentToIframe =
|
|
|
273
284
|
// Regenerates the whole scoped-CSS cascade (real @media included) without a re-render. `style` is
|
|
274
285
|
// Already transposed parent-side (transposeStylebookStyle); `gen` must equal the iframe's
|
|
275
286
|
// RenderedGen — a stale update is dropped (the superseding render carries the same style).
|
|
276
|
-
| { kind: "styleUpdate"; style:
|
|
287
|
+
| { kind: "styleUpdate"; style: JxStyle; gen: number }
|
|
277
288
|
// Enter inline editing on the node at `path` (used to re-enter after a split/insert re-renders).
|
|
278
289
|
| {
|
|
279
290
|
kind: "enterEdit";
|
|
@@ -381,10 +392,14 @@ export type DropInstructionType = "reorder-above" | "reorder-below" | "make-chil
|
|
|
381
392
|
|
|
382
393
|
/**
|
|
383
394
|
* The kind of thing being dragged. `tree-node` carries the source's existing document path (a
|
|
384
|
-
* move); `block` carries
|
|
385
|
-
* retained PARENT-SIDE keyed by `dragSeq` and never crosses the boundary.
|
|
395
|
+
* move); `block` carries only its fragment's tag on the wire — its full `fragment` (a
|
|
396
|
+
* {@link JxMutableNode}) is retained PARENT-SIDE keyed by `dragSeq` and never crosses the boundary.
|
|
397
|
+
* The tag is what lets the iframe keep a block out of a paragraph (`iframe-drop.ts`); an OS file
|
|
398
|
+
* drag has none, and is placed as a block.
|
|
386
399
|
*/
|
|
387
|
-
export type DragSrcKind =
|
|
400
|
+
export type DragSrcKind =
|
|
401
|
+
| { type: "tree-node"; path: (string | number)[] }
|
|
402
|
+
| { type: "block"; tag?: string };
|
|
388
403
|
|
|
389
404
|
/**
|
|
390
405
|
* A display-only drop preview the iframe posts on `dragOver`: where the drop indicator should draw
|
|
@@ -490,7 +505,7 @@ export type IframeToParent =
|
|
|
490
505
|
// `S.canvas.scope` so the data-explorer panel shows live data instead of "pending" (the iframe,
|
|
491
506
|
// Not the parent, now resolves the scope). `gen` lets the parent drop a snapshot from a superseded
|
|
492
507
|
// Render. Posted right after `renderComplete`; values are JSON-safe deep clones (see serialize-scope).
|
|
493
|
-
| { kind: "dataScope"; gen: number; scope:
|
|
508
|
+
| { kind: "dataScope"; gen: number; scope: JsonObject }
|
|
494
509
|
// The frame's own quiescence, ANSWERED rather than polled (studio.md §13.5).
|
|
495
510
|
// Nothing in the parent realm can see inside a cross-origin frame, so a parent that wanted to
|
|
496
511
|
// Know whether the canvas had settled could only sleep. The frame samples itself at its own rAF
|
|
@@ -37,8 +37,9 @@ import { classifyRenderNode, jxPathSelector, serializeJxPath } from "./path-mapp
|
|
|
37
37
|
import { elementForPath } from "./iframe-position";
|
|
38
38
|
import type { AssetContext } from "./asset-resolve";
|
|
39
39
|
import { SITE_STYLE_ID, buildSiteStyleCSS } from "@jxsuite/site/site-style";
|
|
40
|
-
import type { CanvasMode, WireDiffMarks } from "./iframe-protocol";
|
|
41
|
-
import
|
|
40
|
+
import type { CanvasMode, WireDiffMarks, WireLocale } from "./iframe-protocol";
|
|
41
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
42
|
+
import type { JxDocument, JxElement, JxStyle } from "@jxsuite/schema/types";
|
|
42
43
|
import type { PathMapCtx } from "./path-mapping";
|
|
43
44
|
|
|
44
45
|
/**
|
|
@@ -61,18 +62,12 @@ export interface RenderHandle {
|
|
|
61
62
|
ctx: IframeRenderCtx;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
interface HeadEntry {
|
|
65
|
-
tagName?: string;
|
|
66
|
-
attributes?: Record<string, unknown>;
|
|
67
|
-
textContent?: string;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
65
|
/**
|
|
71
66
|
* Register the document's `$elements` (components) in this iframe realm so the runtime can render
|
|
72
67
|
* them.
|
|
73
68
|
*/
|
|
74
69
|
export async function registerElements(doc: JxDocument, docBase: string): Promise<void> {
|
|
75
|
-
const elements =
|
|
70
|
+
const elements = doc.$elements;
|
|
76
71
|
if (!Array.isArray(elements)) {
|
|
77
72
|
return;
|
|
78
73
|
}
|
|
@@ -81,13 +76,16 @@ export async function registerElements(doc: JxDocument, docBase: string): Promis
|
|
|
81
76
|
await Promise.all(
|
|
82
77
|
elements.map(async (entry) => {
|
|
83
78
|
const task = (async () => {
|
|
84
|
-
if (
|
|
79
|
+
if (isString(entry)) {
|
|
85
80
|
const specifier =
|
|
86
81
|
entry.startsWith("/") || entry.startsWith(".") ? entry : `/node_modules/${entry}`;
|
|
87
82
|
await import(specifier);
|
|
88
|
-
} else if (entry &&
|
|
89
|
-
await defineElement(new URL(String(
|
|
90
|
-
} else if (entry
|
|
83
|
+
} else if (isNonNullObject(entry) && "$ref" in entry) {
|
|
84
|
+
await defineElement(new URL(String(entry.$ref), docBase).href);
|
|
85
|
+
} else if (isNonNullObject(entry)) {
|
|
86
|
+
/* SAFETY: an `$elements` entry that is neither a specifier nor a `$ref` is an inline
|
|
87
|
+
* component definition by the schema (JxDocument is JxElement with a literal tagName).
|
|
88
|
+
* A malformed one throws inside this task, which the race below catches and logs. */
|
|
91
89
|
await defineElement(entry as JxDocument, docBase);
|
|
92
90
|
}
|
|
93
91
|
})();
|
|
@@ -633,6 +631,10 @@ export const STYLEBOOK_CSS = `
|
|
|
633
631
|
.element-card-preview > * {
|
|
634
632
|
max-width: 100%;
|
|
635
633
|
margin: 0;
|
|
634
|
+
}
|
|
635
|
+
/* A list keeps its inline-start padding: its markers are drawn in it, and with none they are
|
|
636
|
+
clipped by the card ("1." shows as "."). Every other specimen sits flush in its card. */
|
|
637
|
+
.element-card-preview > :not(ol, ul, menu) {
|
|
636
638
|
padding: 0;
|
|
637
639
|
}
|
|
638
640
|
.element-card-preview > hr {
|
|
@@ -696,11 +698,11 @@ export function syncStylebookCss(doc: Document, mode: CanvasMode): void {
|
|
|
696
698
|
* selectors can win (spec.md §9.5), and so removed tokens can't linger on reused iframes.
|
|
697
699
|
*/
|
|
698
700
|
export function applySiteStyle(
|
|
699
|
-
siteStyle:
|
|
701
|
+
siteStyle: JxStyle | null | undefined,
|
|
700
702
|
mediaQueries: Record<string, string> = {},
|
|
701
703
|
): void {
|
|
702
704
|
const existing = document.head.querySelector(`#${SITE_STYLE_ID}`);
|
|
703
|
-
if (!siteStyle ||
|
|
705
|
+
if (!siteStyle || !isNonNullObject(siteStyle)) {
|
|
704
706
|
existing?.remove();
|
|
705
707
|
return;
|
|
706
708
|
}
|
|
@@ -730,6 +732,49 @@ export function applyPreviewColorScheme(doc: Document, scheme: "light" | "dark"
|
|
|
730
732
|
}
|
|
731
733
|
}
|
|
732
734
|
|
|
735
|
+
/** The `lang` and `dir` a frame's root booted with, which a frame with no language goes back to. */
|
|
736
|
+
export interface LocaleBaseline {
|
|
737
|
+
lang: string | null;
|
|
738
|
+
dir: string | null;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/** Read the root's `lang` and `dir` as the frame booted them (`canvas.html` is `lang="en"`). */
|
|
742
|
+
export function captureLocaleBaseline(doc: Document): LocaleBaseline {
|
|
743
|
+
const root = doc.documentElement;
|
|
744
|
+
return { dir: root.getAttribute("dir"), lang: root.getAttribute("lang") };
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
/** Write one root attribute, or remove it for null. */
|
|
748
|
+
function setRootAttribute(root: Element, name: string, value: string | null): void {
|
|
749
|
+
if (value === null) {
|
|
750
|
+
root.removeAttribute(name);
|
|
751
|
+
} else {
|
|
752
|
+
root.setAttribute(name, value);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Set the artboard's language (studio.md §20.2): `lang` and `dir` on the frame's root, the only
|
|
758
|
+
* writer of either. `dir` is what makes an RTL document actually mirror, and `lang` is what CSS's
|
|
759
|
+
* `:lang()` and the font stack select on. The root survives a render, which replaces only the
|
|
760
|
+
* container's children, so the value holds until the next one arrives.
|
|
761
|
+
*
|
|
762
|
+
* `null`, a project that declares no locales, restores the language the frame booted with rather
|
|
763
|
+
* than removing it, so applying the value on every render does not strip `canvas.html`'s
|
|
764
|
+
* `lang="en"` from every canvas of a monolingual project. A left-to-right language writes no
|
|
765
|
+
* `dir="ltr"`, as the built page never does (`site-architecture.md` §13.4): it restores the booted
|
|
766
|
+
* `dir`.
|
|
767
|
+
*/
|
|
768
|
+
export function applyPreviewLocale(
|
|
769
|
+
doc: Document,
|
|
770
|
+
locale: WireLocale | null,
|
|
771
|
+
baseline: LocaleBaseline,
|
|
772
|
+
): void {
|
|
773
|
+
const root = doc.documentElement;
|
|
774
|
+
setRootAttribute(root, "lang", locale?.locale ?? baseline.lang);
|
|
775
|
+
setRootAttribute(root, "dir", locale?.dir === "rtl" ? "rtl" : baseline.dir);
|
|
776
|
+
}
|
|
777
|
+
|
|
733
778
|
/**
|
|
734
779
|
* Draw the popover at `path` open, and every other one closed.
|
|
735
780
|
*
|
|
@@ -746,15 +791,15 @@ export function applyPreviewColorScheme(doc: Document, scheme: "light" | "dark"
|
|
|
746
791
|
* @docs studio/interface/canvas
|
|
747
792
|
*/
|
|
748
793
|
export function applyCanvasPopoverOpen(root: ParentNode, path: string | null): void {
|
|
749
|
-
for (const el of root.querySelectorAll("[data-jx-popover-open]")) {
|
|
750
|
-
delete
|
|
794
|
+
for (const el of root.querySelectorAll<HTMLElement>("[data-jx-popover-open]")) {
|
|
795
|
+
delete el.dataset.jxPopoverOpen;
|
|
751
796
|
}
|
|
752
797
|
if (path === null) {
|
|
753
798
|
return;
|
|
754
799
|
}
|
|
755
|
-
const target = root.querySelector(`[data-jx-popover]${jxPathSelector(path)}`);
|
|
800
|
+
const target = root.querySelector<HTMLElement>(`[data-jx-popover]${jxPathSelector(path)}`);
|
|
756
801
|
if (target) {
|
|
757
|
-
|
|
802
|
+
target.dataset.jxPopoverOpen = "";
|
|
758
803
|
}
|
|
759
804
|
}
|
|
760
805
|
|
|
@@ -783,26 +828,27 @@ export function applyCanvasPopoverOpen(root: ParentNode, path: string | null): v
|
|
|
783
828
|
* backdrop and all.
|
|
784
829
|
*/
|
|
785
830
|
export function applyCanvasDialogOpen(root: ParentNode, path: string | null): void {
|
|
786
|
-
for (const el of root.querySelectorAll("[data-jx-dialog-open]")) {
|
|
787
|
-
delete
|
|
831
|
+
for (const el of root.querySelectorAll<HTMLElement>("[data-jx-dialog-open]")) {
|
|
832
|
+
delete el.dataset.jxDialogOpen;
|
|
788
833
|
}
|
|
789
834
|
if (path === null) {
|
|
790
835
|
return;
|
|
791
836
|
}
|
|
792
|
-
const target = root.querySelector(`dialog${jxPathSelector(path)}`);
|
|
837
|
+
const target = root.querySelector<HTMLElement>(`dialog${jxPathSelector(path)}`);
|
|
793
838
|
if (target) {
|
|
794
|
-
|
|
839
|
+
target.dataset.jxDialogOpen = "";
|
|
795
840
|
}
|
|
796
841
|
}
|
|
797
842
|
|
|
798
843
|
/** Inject the document's `$head` (link/meta/script) into the iframe's <head>, de-duped by href/src. */
|
|
799
844
|
export function injectHead(doc: JxDocument, assets: AssetContext | null = null): void {
|
|
800
|
-
const head =
|
|
845
|
+
const head = doc.$head;
|
|
801
846
|
if (!Array.isArray(head)) {
|
|
802
847
|
return;
|
|
803
848
|
}
|
|
804
849
|
for (const entry of head) {
|
|
805
|
-
|
|
850
|
+
// A `$head` array read off disk can hold a null or a tagless entry; neither emits anything.
|
|
851
|
+
if (!isNonNullObject(entry) || !entry.tagName) {
|
|
806
852
|
continue;
|
|
807
853
|
}
|
|
808
854
|
const tag = String(entry.tagName).toLowerCase();
|
|
@@ -810,10 +856,10 @@ export function injectHead(doc: JxDocument, assets: AssetContext | null = null):
|
|
|
810
856
|
if (tag === "script" && !entry.attributes?.src) {
|
|
811
857
|
continue;
|
|
812
858
|
}
|
|
813
|
-
const attrs = { ...entry.attributes }
|
|
859
|
+
const attrs = { ...entry.attributes };
|
|
814
860
|
for (const key of ["href", "src"]) {
|
|
815
861
|
const val = attrs[key];
|
|
816
|
-
if (
|
|
862
|
+
if (!isString(val) || val === "") {
|
|
817
863
|
continue;
|
|
818
864
|
}
|
|
819
865
|
if (!val.startsWith("/") && !val.startsWith(".") && !val.startsWith("http")) {
|
|
@@ -833,7 +879,7 @@ export function injectHead(doc: JxDocument, assets: AssetContext | null = null):
|
|
|
833
879
|
el.setAttribute(k, String(v));
|
|
834
880
|
}
|
|
835
881
|
if (entry.textContent) {
|
|
836
|
-
el.textContent = entry.textContent;
|
|
882
|
+
el.textContent = String(entry.textContent);
|
|
837
883
|
}
|
|
838
884
|
document.head.append(el);
|
|
839
885
|
}
|
|
@@ -856,7 +902,7 @@ export function makeStamper(ctx: PathMapCtx) {
|
|
|
856
902
|
(island) => path.length > island.length && island.every((seg, i) => path[i] === seg),
|
|
857
903
|
);
|
|
858
904
|
|
|
859
|
-
return (created: Node, path: (string | number)[], def:
|
|
905
|
+
return (created: Node, path: (string | number)[], def: JxElement | string) => {
|
|
860
906
|
if (!(created instanceof HTMLElement)) {
|
|
861
907
|
return;
|
|
862
908
|
}
|
|
@@ -866,7 +912,10 @@ export function makeStamper(ctx: PathMapCtx) {
|
|
|
866
912
|
// Editable tree and re-render a live instance with default state. Mark the root so the
|
|
867
913
|
// Runtime's element class leaves it alone (see defineElement's connectedCallback guard).
|
|
868
914
|
const isDefinitionRoot =
|
|
869
|
-
path.length === 0 &&
|
|
915
|
+
path.length === 0 &&
|
|
916
|
+
isNonNullObject(def) &&
|
|
917
|
+
isString(def.tagName) &&
|
|
918
|
+
def.tagName.includes("-");
|
|
870
919
|
if (isDefinitionRoot) {
|
|
871
920
|
created.dataset.jxDefinitionRoot = "";
|
|
872
921
|
}
|
|
@@ -984,7 +1033,7 @@ export async function renderResolvedDocument(opts: {
|
|
|
984
1033
|
docBase: string;
|
|
985
1034
|
mode: CanvasMode;
|
|
986
1035
|
mapperCtx: PathMapCtx;
|
|
987
|
-
siteStyle?:
|
|
1036
|
+
siteStyle?: JxStyle | null;
|
|
988
1037
|
/**
|
|
989
1038
|
* How this host addresses project media, or null when the canvas origin serves the site's own URL
|
|
990
1039
|
* space (desktop, `jx dev`) and references need no resolution at all.
|
|
@@ -1037,7 +1086,7 @@ export async function renderResolvedDocument(opts: {
|
|
|
1037
1086
|
// Iframe clears it (page-level templates are inert in design/edit via prepareForEditMode, so only
|
|
1038
1087
|
// Component internals get stamped).
|
|
1039
1088
|
setStampPropBindings(opts.mode === "design" || opts.mode === "edit");
|
|
1040
|
-
applySiteStyle(opts.siteStyle,
|
|
1089
|
+
applySiteStyle(opts.siteStyle, opts.doc.$media ?? {});
|
|
1041
1090
|
injectHead(opts.doc, assets);
|
|
1042
1091
|
syncEditModeCss(opts.container.ownerDocument, opts.mode);
|
|
1043
1092
|
// The substitute rules for the attributes the de-link above renamed. Same predicate as the
|
|
@@ -1052,7 +1101,7 @@ export async function renderResolvedDocument(opts: {
|
|
|
1052
1101
|
// But no own `$media` resolves the breakpoint to its real query (the iframe path calls buildScope
|
|
1053
1102
|
// Directly and never the runtime's `Jx()` entry, which is the only other place _rootMedia is set).
|
|
1054
1103
|
// Set it every render (even to `{}`) so a stale map from a previous document cannot leak.
|
|
1055
|
-
setRootMedia(
|
|
1104
|
+
setRootMedia(opts.doc.$media ?? {});
|
|
1056
1105
|
// Register components BEFORE renderNode. The runtime only applies a custom element's `$props` when
|
|
1057
1106
|
// That element is ALREADY defined (renderNode gates renderCustomElementWithProps on a truthy
|
|
1058
1107
|
// `customElements.get(tagName)`); if we register after render, every component paints with its
|
|
@@ -1066,8 +1115,8 @@ export async function renderResolvedDocument(opts: {
|
|
|
1066
1115
|
// The scope MUST be the runtime's (runScoped): renderNode creates its binding effects with the
|
|
1067
1116
|
// Runtime's copy of @vue/reactivity, and scope collection is per module instance — a studio
|
|
1068
1117
|
// EffectScope here collects nothing and dispose() would leak every effect of this render.
|
|
1069
|
-
const { result: el, stop } = runScoped(
|
|
1070
|
-
|
|
1118
|
+
const { result: el, stop } = runScoped(() =>
|
|
1119
|
+
renderNode(opts.doc, $defs, { _path: [], onNodeCreated }),
|
|
1071
1120
|
);
|
|
1072
1121
|
opts.container.replaceChildren(el);
|
|
1073
1122
|
applyCanvasPopoverOpen(opts.container, opts.popoverOpen ?? null);
|
|
@@ -21,7 +21,17 @@ import type { IframeToParent, ParentToIframe } from "./iframe-protocol";
|
|
|
21
21
|
|
|
22
22
|
type SlashNavKey = Extract<IframeToParent, { kind: "slashNav" }>["key"];
|
|
23
23
|
|
|
24
|
-
const NAV_KEYS = new Set([
|
|
24
|
+
const NAV_KEYS = new Set<string>([
|
|
25
|
+
"ArrowUp",
|
|
26
|
+
"ArrowDown",
|
|
27
|
+
"Enter",
|
|
28
|
+
"Escape",
|
|
29
|
+
] satisfies SlashNavKey[]);
|
|
30
|
+
|
|
31
|
+
/** Whether `key` is one of the four keys the parent menu navigates by. */
|
|
32
|
+
function isNavKey(key: string): key is SlashNavKey {
|
|
33
|
+
return NAV_KEYS.has(key);
|
|
34
|
+
}
|
|
25
35
|
|
|
26
36
|
/**
|
|
27
37
|
* Register the bridge SlashController for this iframe realm and wire its keyboard/dismissal
|
|
@@ -55,28 +65,31 @@ export function startIframeSlashBridge(
|
|
|
55
65
|
open = true;
|
|
56
66
|
lastPostedFilter = filter;
|
|
57
67
|
const r = rectOf(anchorEl);
|
|
58
|
-
|
|
68
|
+
const message: Extract<IframeToParent, { kind: "slashShow" }> = {
|
|
59
69
|
filter,
|
|
60
70
|
kind: "slashShow",
|
|
61
71
|
rect: { height: r.height, width: r.width, x: r.left, y: r.top },
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
};
|
|
73
|
+
/* Carried, because the parent draws the menu and only the FRAME knows why it opened. A
|
|
74
|
+
menu opened by name has no "/…" run in the document to filter with, so it needs its own
|
|
75
|
+
field; the "/" gesture needs none, because the author types into the block. This option
|
|
76
|
+
was dropped at this boundary and the loss was invisible — the menu still appeared, just
|
|
77
|
+
with no way past fifteen items but scrolling. */
|
|
78
|
+
if (cbs.showFilter === true) {
|
|
79
|
+
message.showFilter = true;
|
|
80
|
+
}
|
|
81
|
+
channel.post(message);
|
|
69
82
|
},
|
|
70
83
|
};
|
|
71
84
|
setSlashController(controller);
|
|
72
85
|
|
|
73
86
|
const onKeyDown = (e: KeyboardEvent) => {
|
|
74
|
-
if (!open || !
|
|
87
|
+
if (!open || !isNavKey(e.key)) {
|
|
75
88
|
return;
|
|
76
89
|
}
|
|
77
90
|
e.preventDefault();
|
|
78
91
|
e.stopPropagation();
|
|
79
|
-
channel.post({ key: e.key
|
|
92
|
+
channel.post({ key: e.key, kind: "slashNav" });
|
|
80
93
|
};
|
|
81
94
|
const onMouseDown = () => {
|
|
82
95
|
// The parent menu's outside-click listener can't see iframe clicks — any in-iframe press while
|
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import { releaseElementStyles, renderNode, runScoped } from "@jxsuite/runtime";
|
|
15
|
+
import { isNumber, isString } from "@jxsuite/schema/guards";
|
|
15
16
|
import { getNodeAtPath } from "../state";
|
|
16
17
|
import { makeStamper } from "./iframe-render";
|
|
17
|
-
import { prepareForEditMode } from "../utils/edit-display";
|
|
18
|
+
import { prepareForEditMode, sampleRowAt } from "../utils/edit-display";
|
|
18
19
|
import { stripEventHandlers } from "../utils/strip-events";
|
|
19
20
|
import type { IframeRenderCtx } from "./iframe-render";
|
|
20
21
|
import type { JxPath } from "../state";
|
|
@@ -39,11 +40,17 @@ export function renderSubtreeIframe(
|
|
|
39
40
|
docPath: JxPath,
|
|
40
41
|
ctx: IframeRenderCtx,
|
|
41
42
|
): HTMLElement | Text {
|
|
43
|
+
/* SAFETY: a widening of getNodeAtPath's declared return. A patch path addresses an entry of a
|
|
44
|
+
* `children` array, which the schema types as `JxMutableNode | string`, and a missing step
|
|
45
|
+
* answers undefined, so those three cases are the whole range. */
|
|
42
46
|
const node = getNodeAtPath(shadowDoc, docPath) as JxMutableNode | string | undefined;
|
|
43
47
|
if (node === undefined) {
|
|
44
48
|
throw new Error(`iframe-patch-node-not-found:${docPath.join("/")}`);
|
|
45
49
|
}
|
|
46
|
-
|
|
50
|
+
// Inside a repeater, the template is drawn with the sample row the full render used.
|
|
51
|
+
const def = isString(node)
|
|
52
|
+
? node
|
|
53
|
+
: prepareForEditMode(stripEventHandlers(node), sampleRowAt(shadowDoc, docPath));
|
|
47
54
|
const { result: rendered, stop } = runScoped(() =>
|
|
48
55
|
renderNode(def, ctx.defs, {
|
|
49
56
|
_path: docPathToRenderPath(docPath, ctx),
|
|
@@ -98,7 +105,7 @@ function docPathToRenderPath(docPath: JxPath, ctx: IframeRenderCtx): (string | n
|
|
|
98
105
|
const { mapperCtx } = ctx;
|
|
99
106
|
if (mapperCtx.layoutWrapped && mapperCtx.pageContentPrefix && docPath[0] === "children") {
|
|
100
107
|
const [, idx] = docPath;
|
|
101
|
-
return
|
|
108
|
+
return isNumber(idx)
|
|
102
109
|
? [
|
|
103
110
|
...mapperCtx.pageContentPrefix,
|
|
104
111
|
idx + (mapperCtx.pageContentOffset ?? 0),
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a live render imports an `npm:` package from (spec.md §5.3, 4c).
|
|
3
|
+
*
|
|
4
|
+
* The dev server answers `/node_modules/<package>/<subpath>` by resolving the package's `exports`
|
|
5
|
+
* and bundling the entry on demand (`@jxsuite/server`), the same URL space a bare `$elements`
|
|
6
|
+
* specifier and a bare `$head` asset are already fetched from. Both realms that render a project
|
|
7
|
+
* live install it into the runtime (`setNpmModuleResolver`): the canvas frame against its own
|
|
8
|
+
* address, and the editor window, which draws the Site panel's and the Content home's previews,
|
|
9
|
+
* against the project's asset origin.
|
|
10
|
+
*
|
|
11
|
+
* Dependency-free so it rides in the slim canvas bundle.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The URL a package specifier is imported from, under `base`.
|
|
16
|
+
*
|
|
17
|
+
* @param specifier - `@scope/pkg/subpath`, as the document wrote it after `npm:`
|
|
18
|
+
* @param base - The origin (or any URL on it) that serves the project
|
|
19
|
+
*/
|
|
20
|
+
export function npmModuleUrl(specifier: string, base: string): string {
|
|
21
|
+
return new URL(`/node_modules/${specifier}`, base).href;
|
|
22
|
+
}
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
* result for the `data-jx-path` attribute.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import { isJsonObject, isNonNullObject, isNumber, isString } from "@jxsuite/schema/guards";
|
|
15
|
+
import type { JxElement } from "@jxsuite/schema/types";
|
|
14
16
|
import type { JxPath } from "../state";
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -83,22 +85,27 @@ export function wrapsPageContent(path: JxPath, prefix: JxPath | null): boolean {
|
|
|
83
85
|
* Resolve a runtime render path to a document path (or flag it as layout-originated). Pure — the
|
|
84
86
|
* caller decides whether to record the result in a WeakMap or `data-jx-*` attributes.
|
|
85
87
|
*/
|
|
86
|
-
export function classifyRenderNode(
|
|
88
|
+
export function classifyRenderNode(
|
|
89
|
+
path: JxPath,
|
|
90
|
+
def: JxElement | string,
|
|
91
|
+
ctx: PathMapCtx,
|
|
92
|
+
): RenderNodeClass {
|
|
87
93
|
// Layout-originated nodes have no page-document path; the caller stamps their origin instead
|
|
88
94
|
// (data-jx-layout-path / data-jx-layout-file).
|
|
89
|
-
const marker =
|
|
90
|
-
ctx.layoutWrapped && typeof def === "object"
|
|
91
|
-
? (def as { $__layout?: unknown } | null)?.$__layout
|
|
92
|
-
: undefined;
|
|
95
|
+
const marker = ctx.layoutWrapped && isNonNullObject(def) ? def["$__layout"] : undefined;
|
|
93
96
|
if (marker) {
|
|
94
|
-
|
|
97
|
+
// A legacy bare `true` marker carries no origin, so it reads as an empty one.
|
|
98
|
+
const origin = isJsonObject(marker) ? marker : {};
|
|
99
|
+
const { file, path: originPath } = origin;
|
|
95
100
|
return {
|
|
96
101
|
// The root is never chrome even when the layout distributed nothing: it IS the render, and a
|
|
97
102
|
// Dimmed, frozen root would be a canvas nobody can touch.
|
|
98
103
|
chrome: path.length > 0 && !wrapsPageContent(path, ctx.pageContentPrefix),
|
|
99
104
|
kind: "layout",
|
|
100
|
-
layoutFile:
|
|
101
|
-
|
|
105
|
+
layoutFile: isString(file) ? file : "",
|
|
106
|
+
/* SAFETY: markLayoutNodes (canvas-live-render.ts) is the only writer of `$__layout`, and the
|
|
107
|
+
* `path` it stamps is a LayoutMarker's JxPath. */
|
|
108
|
+
layoutPath: Array.isArray(originPath) ? (originPath as JxPath) : [],
|
|
102
109
|
};
|
|
103
110
|
}
|
|
104
111
|
|
|
@@ -112,10 +119,9 @@ export function classifyRenderNode(path: JxPath, def: unknown, ctx: PathMapCtx):
|
|
|
112
119
|
if (path.length >= pfx.length && pfx.every((seg, i) => path[i] === seg)) {
|
|
113
120
|
const rest = path.slice(pfx.length);
|
|
114
121
|
const [containerIdx] = rest;
|
|
115
|
-
mappedPath =
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
: ["children", ...rest];
|
|
122
|
+
mappedPath = isNumber(containerIdx)
|
|
123
|
+
? ["children", containerIdx - (ctx.pageContentOffset ?? 0), ...rest.slice(1)]
|
|
124
|
+
: ["children", ...rest];
|
|
119
125
|
}
|
|
120
126
|
}
|
|
121
127
|
|
|
@@ -154,5 +160,6 @@ export function serializeJxPath(path: JxPath): string {
|
|
|
154
160
|
|
|
155
161
|
/** Decode a `data-jx-path` attribute back into a document path. */
|
|
156
162
|
export function parseJxPath(serialized: string): JxPath {
|
|
163
|
+
// SAFETY: only serializeJxPath writes `data-jx-path`, and it is JSON.stringify of a JxPath.
|
|
157
164
|
return JSON.parse(serialized) as JxPath;
|
|
158
165
|
}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { activeTab } from "../workspace/workspace";
|
|
15
15
|
import { getNodeAtPath } from "../state";
|
|
16
16
|
import { documentHasPopover, isPopover } from "@jxsuite/schema/overlays";
|
|
17
|
+
import { isNonNullObject } from "@jxsuite/schema/guards";
|
|
17
18
|
import { INVOKER_TAGS, POPOVER_TAGS } from "@jxsuite/ui";
|
|
18
19
|
import { primarySelection } from "../tabs/selection";
|
|
19
20
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
@@ -49,7 +50,7 @@ export function ancestorPopoverPath(
|
|
|
49
50
|
for (let end = path.length; end >= 0; end -= 1) {
|
|
50
51
|
const prefix = path.slice(0, end);
|
|
51
52
|
const node = getNodeAtPath(doc, prefix);
|
|
52
|
-
if (node &&
|
|
53
|
+
if (isNonNullObject(node) && isPopover(node, KIT_SCOPE)) {
|
|
53
54
|
return prefix;
|
|
54
55
|
}
|
|
55
56
|
}
|
|
@@ -72,13 +73,16 @@ export function ancestorPopoverPath(
|
|
|
72
73
|
* @returns The popover's path, or null.
|
|
73
74
|
*/
|
|
74
75
|
export function popoverPathFor(tab: Tab, explicit?: JxPath): JxPath | null {
|
|
76
|
+
/* SAFETY: a widening, not a narrowing. A tab built by createTab always carries a document, but
|
|
77
|
+
* the command is a public entry point and the contract (pinned in popover-state.test.ts) is that
|
|
78
|
+
* a tab record without one answers null rather than throwing inside getNodeAtPath. */
|
|
75
79
|
const doc = tab.doc.document as JxMutableNode | undefined;
|
|
76
80
|
if (!doc) {
|
|
77
81
|
return null;
|
|
78
82
|
}
|
|
79
83
|
if (explicit) {
|
|
80
84
|
const node = getNodeAtPath(doc, explicit);
|
|
81
|
-
return node &&
|
|
85
|
+
return isNonNullObject(node) && isPopover(node, KIT_SCOPE) ? explicit : null;
|
|
82
86
|
}
|
|
83
87
|
return ancestorPopoverPath(doc, primarySelection(tab.session.selection));
|
|
84
88
|
}
|
|
@@ -101,6 +105,6 @@ export function popoverPathFor(tab: Tab, explicit?: JxPath): JxPath | null {
|
|
|
101
105
|
* @returns True when the focused document declares at least one popover.
|
|
102
106
|
*/
|
|
103
107
|
export function activeDocumentHasPopover(): boolean {
|
|
104
|
-
const doc = activeTab.value?.doc.document
|
|
108
|
+
const doc = activeTab.value?.doc.document;
|
|
105
109
|
return doc ? documentHasPopover(doc, KIT_SCOPE) : false;
|
|
106
110
|
}
|
|
@@ -31,7 +31,6 @@ import { effect, pauseTracking, resetTracking } from "../reactivity";
|
|
|
31
31
|
import { postPopoverOpen, revealCanvasPath } from "./iframe-host";
|
|
32
32
|
import { primarySelection } from "../tabs/selection";
|
|
33
33
|
import { updateSession } from "../store";
|
|
34
|
-
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
35
34
|
import type { JxPath } from "../state";
|
|
36
35
|
import type { Tab } from "../tabs/tab";
|
|
37
36
|
|
|
@@ -59,7 +58,7 @@ export function setOpenPopover(tab: Tab, path: JxPath | null): void {
|
|
|
59
58
|
|
|
60
59
|
/** Open the popover containing `path`, if any. Returns whether anything changed. */
|
|
61
60
|
function openPopoverFor(tab: Tab, path: JxPath | null): boolean {
|
|
62
|
-
const target = ancestorPopoverPath(tab.doc.document
|
|
61
|
+
const target = ancestorPopoverPath(tab.doc.document, path);
|
|
63
62
|
if (target === null || samePath(tab.session.ui.openPopover, target)) {
|
|
64
63
|
return false;
|
|
65
64
|
}
|