@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
|
@@ -51,11 +51,21 @@ import type {
|
|
|
51
51
|
SerializableRect,
|
|
52
52
|
} from "./iframe-protocol";
|
|
53
53
|
import type { DocPos } from "./iframe-position";
|
|
54
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
54
55
|
import type { JxPath } from "../state";
|
|
55
56
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
56
57
|
|
|
58
|
+
/** The commit a block session posts when its text reaches the document. */
|
|
59
|
+
type EditCommitMsg = Extract<IframeToParent, { kind: "editCommit" }>;
|
|
60
|
+
|
|
61
|
+
/** The commit a prop-bound session posts for its instance's `$props` value. */
|
|
62
|
+
type EditCommitPropMsg = Extract<IframeToParent, { kind: "editCommitProp" }>;
|
|
63
|
+
|
|
64
|
+
/** The toolbar commands that toggle an inline tag (every intent but `link` and `insertData`). */
|
|
65
|
+
type InlineFormatCommand = Exclude<ApplyFormatIntent["command"], "link" | "insertData">;
|
|
66
|
+
|
|
57
67
|
/** Toolbar command → inline tag (mirrors the parent's old `cmdToTag`, now iframe-side). */
|
|
58
|
-
const CMD_TO_TAG
|
|
68
|
+
const CMD_TO_TAG = {
|
|
59
69
|
bold: "strong",
|
|
60
70
|
code: "code",
|
|
61
71
|
italic: "em",
|
|
@@ -63,7 +73,19 @@ const CMD_TO_TAG: Record<string, string> = {
|
|
|
63
73
|
subscript: "sub",
|
|
64
74
|
superscript: "sup",
|
|
65
75
|
underline: "u",
|
|
66
|
-
}
|
|
76
|
+
} satisfies Record<InlineFormatCommand, string>;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* The CSS Custom Highlight API as this realm may or may not provide it. lib.dom declares both
|
|
80
|
+
* members unconditionally, but happy-dom and non-Chromium engines ship neither.
|
|
81
|
+
*/
|
|
82
|
+
interface HighlightRealm {
|
|
83
|
+
Highlight?: typeof Highlight;
|
|
84
|
+
CSS?: { highlights?: HighlightRegistry };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** The global object, read through the optional shape above so the feature probes stay honest. */
|
|
88
|
+
const highlightRealm: HighlightRealm = globalThis;
|
|
67
89
|
|
|
68
90
|
/** Inline tags whose active state the snapshot reports (everything except `a`, handled via link). */
|
|
69
91
|
const ACTIVE_TAG_PROBES = ["strong", "em", "u", "del", "sub", "sup", "code"];
|
|
@@ -125,19 +147,19 @@ function deliveredOutsideProps(node: JxMutableNode | undefined, prop: string): b
|
|
|
125
147
|
if (!node) {
|
|
126
148
|
return false;
|
|
127
149
|
}
|
|
128
|
-
const attrs = node.attributes
|
|
150
|
+
const attrs = node.attributes;
|
|
129
151
|
if (attrs) {
|
|
130
152
|
if (attrs[`props.${prop}`] !== undefined) {
|
|
131
153
|
return true;
|
|
132
154
|
}
|
|
133
155
|
const reflected = new Set([prop.toLowerCase(), camelToKebab(prop).toLowerCase()]);
|
|
134
|
-
for (const
|
|
135
|
-
if (
|
|
156
|
+
for (const name of Object.keys(attrs)) {
|
|
157
|
+
if (attrs[name] !== undefined && reflected.has(name.toLowerCase())) {
|
|
136
158
|
return true;
|
|
137
159
|
}
|
|
138
160
|
}
|
|
139
161
|
const payload = attrs["data-jx-props"];
|
|
140
|
-
if (
|
|
162
|
+
if (isString(payload) && payloadNames(payload, prop)) {
|
|
141
163
|
return true;
|
|
142
164
|
}
|
|
143
165
|
}
|
|
@@ -145,14 +167,14 @@ function deliveredOutsideProps(node: JxMutableNode | undefined, prop: string): b
|
|
|
145
167
|
if (RESERVED_KEYS.has(prop) || prop.startsWith("$")) {
|
|
146
168
|
return false;
|
|
147
169
|
}
|
|
148
|
-
return
|
|
170
|
+
return node[prop] !== undefined;
|
|
149
171
|
}
|
|
150
172
|
|
|
151
173
|
/** Whether a `data-jx-props` JSON payload carries `prop`. Unparseable payloads deliver nothing. */
|
|
152
174
|
function payloadNames(payload: string, prop: string): boolean {
|
|
153
175
|
try {
|
|
154
176
|
const parsed: unknown = JSON.parse(payload);
|
|
155
|
-
return
|
|
177
|
+
return isNonNullObject(parsed) && prop in parsed;
|
|
156
178
|
} catch {
|
|
157
179
|
return false;
|
|
158
180
|
}
|
|
@@ -238,11 +260,8 @@ export function startIframeInlineEdit(
|
|
|
238
260
|
* `Highlight`/`CSS.highlights`, so this is a silent no-op there (and in non-Chromium engines).
|
|
239
261
|
*/
|
|
240
262
|
const updateHighlight = () => {
|
|
241
|
-
const HighlightCtor =
|
|
242
|
-
|
|
243
|
-
| undefined;
|
|
244
|
-
const highlights = (globalThis.CSS as unknown as { highlights?: Map<string, unknown> })
|
|
245
|
-
?.highlights;
|
|
263
|
+
const HighlightCtor = highlightRealm.Highlight;
|
|
264
|
+
const highlights = highlightRealm.CSS?.highlights;
|
|
246
265
|
if (!HighlightCtor || !highlights) {
|
|
247
266
|
return;
|
|
248
267
|
}
|
|
@@ -256,9 +275,7 @@ export function startIframeInlineEdit(
|
|
|
256
275
|
|
|
257
276
|
/** Tear down the Custom Highlight (on teardown / real editEnd). */
|
|
258
277
|
const clearHighlight = () => {
|
|
259
|
-
|
|
260
|
-
?.highlights;
|
|
261
|
-
highlights?.delete(HIGHLIGHT_NAME);
|
|
278
|
+
highlightRealm.CSS?.highlights?.delete(HIGHLIGHT_NAME);
|
|
262
279
|
};
|
|
263
280
|
|
|
264
281
|
/**
|
|
@@ -321,13 +338,11 @@ export function startIframeInlineEdit(
|
|
|
321
338
|
// Optional, so omitting it keeps the message shape unchanged for every non-tick commit.
|
|
322
339
|
onCommit: (p, children, textContent, inPlace) => {
|
|
323
340
|
inputAnnounced = false;
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
...(inPlace ? { inPlace: true } : {}),
|
|
330
|
-
});
|
|
341
|
+
const commit: EditCommitMsg = { children, kind: "editCommit", path: p, textContent };
|
|
342
|
+
if (inPlace) {
|
|
343
|
+
commit.inPlace = true;
|
|
344
|
+
}
|
|
345
|
+
channel.post(commit);
|
|
331
346
|
},
|
|
332
347
|
onEnd: () => {
|
|
333
348
|
clearHighlight();
|
|
@@ -356,11 +371,11 @@ export function startIframeInlineEdit(
|
|
|
356
371
|
if (!shadowDoc) {
|
|
357
372
|
return true;
|
|
358
373
|
}
|
|
359
|
-
const node = getNodeAtPath(shadowDoc, hostPath)
|
|
374
|
+
const node = getNodeAtPath(shadowDoc, hostPath);
|
|
360
375
|
if (deliveredOutsideProps(node, prop)) {
|
|
361
376
|
return false;
|
|
362
377
|
}
|
|
363
|
-
const raw =
|
|
378
|
+
const raw = node?.$props?.[prop];
|
|
364
379
|
if (raw == null) {
|
|
365
380
|
return true; // Unset — editing ADDS the prop, overriding the definition default.
|
|
366
381
|
}
|
|
@@ -371,7 +386,7 @@ export function startIframeInlineEdit(
|
|
|
371
386
|
* Objects were already excluded; the scalar cases were not, and are the ones a component
|
|
372
387
|
* actually declares. They stay editable in the properties panel, which knows their type.
|
|
373
388
|
*/
|
|
374
|
-
if (
|
|
389
|
+
if (!isString(raw)) {
|
|
375
390
|
return false;
|
|
376
391
|
}
|
|
377
392
|
return !raw.includes("${");
|
|
@@ -390,13 +405,16 @@ export function startIframeInlineEdit(
|
|
|
390
405
|
{
|
|
391
406
|
onCommit: (p, _children, textContent, inPlace) => {
|
|
392
407
|
inputAnnounced = false;
|
|
393
|
-
|
|
408
|
+
const commit: EditCommitPropMsg = {
|
|
394
409
|
kind: "editCommitProp",
|
|
395
410
|
path: p,
|
|
396
411
|
prop,
|
|
397
412
|
value: textContent ?? "",
|
|
398
|
-
|
|
399
|
-
|
|
413
|
+
};
|
|
414
|
+
if (inPlace) {
|
|
415
|
+
commit.inPlace = true;
|
|
416
|
+
}
|
|
417
|
+
channel.post(commit);
|
|
400
418
|
},
|
|
401
419
|
onEnd: () => {
|
|
402
420
|
clearHighlight();
|
|
@@ -519,6 +537,7 @@ export function startIframeInlineEdit(
|
|
|
519
537
|
if (start === -1 || end === -1 || end <= start) {
|
|
520
538
|
return false;
|
|
521
539
|
}
|
|
540
|
+
// SAFETY: `blocksInOrder` selects `[data-jx-path]`, so every block it returns carries the key.
|
|
522
541
|
const between = blocks
|
|
523
542
|
.slice(start + 1, end)
|
|
524
543
|
.map((el) => parseJxPath(el.dataset.jxPath as string));
|
|
@@ -573,7 +592,7 @@ export function startIframeInlineEdit(
|
|
|
573
592
|
owns what a slash MEANS (start of a block or after a space; anywhere else it is punctuation).
|
|
574
593
|
The matching `input` half re-filters the open menu, for the same reason: a contenteditable's
|
|
575
594
|
`input` targets its host, not the block the caret happens to be in. */
|
|
576
|
-
const onSlashKey = (e:
|
|
595
|
+
const onSlashKey = (e: KeyboardEvent) => handleSlashTrigger(e);
|
|
577
596
|
const onSlashInput = () => {
|
|
578
597
|
if (isSlashActive()) {
|
|
579
598
|
refreshSlashMenu();
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* (happy-dom's `elementFromPoint` returns null) and lives in iframe-interaction.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
import { isNumber } from "@jxsuite/schema/guards";
|
|
20
21
|
import { parseJxPath } from "./path-mapping";
|
|
21
22
|
import { rectOf } from "../utils/geometry";
|
|
22
23
|
import { childIndex, parentElementPath } from "../state";
|
|
@@ -48,7 +49,7 @@ function isRowLayout(parent: HTMLElement): boolean {
|
|
|
48
49
|
const isGrid = display === "grid" || display === "inline-grid";
|
|
49
50
|
return (
|
|
50
51
|
(isFlex && style.flexDirection.startsWith("row")) ||
|
|
51
|
-
(isGrid &&
|
|
52
|
+
(isGrid && style.gridAutoFlow.startsWith("column"))
|
|
52
53
|
);
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -78,11 +79,11 @@ export function computeInsertZones(
|
|
|
78
79
|
shadowDoc: JxMutableNode,
|
|
79
80
|
): InsertZone[] | null {
|
|
80
81
|
void shadowDoc;
|
|
81
|
-
const serialized = targetEl.dataset
|
|
82
|
+
const serialized = targetEl.dataset.jxPath;
|
|
82
83
|
if (serialized == null) {
|
|
83
84
|
return null;
|
|
84
85
|
}
|
|
85
|
-
const targetPath = parseJxPath(serialized)
|
|
86
|
+
const targetPath = parseJxPath(serialized);
|
|
86
87
|
|
|
87
88
|
// Empty container: one centered "+" that inserts as the container's first child.
|
|
88
89
|
if (targetEl.classList.contains(EMPTY_CONTAINER_CLASS)) {
|
|
@@ -99,7 +100,7 @@ export function computeInsertZones(
|
|
|
99
100
|
return null;
|
|
100
101
|
}
|
|
101
102
|
const childIdx = childIndex(targetPath);
|
|
102
|
-
if (
|
|
103
|
+
if (!isNumber(childIdx)) {
|
|
103
104
|
return null;
|
|
104
105
|
}
|
|
105
106
|
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { jxPathSelector, parseJxPath, serializeJxPath } from "./path-mapping";
|
|
10
|
+
import { isFunction } from "@jxsuite/schema/guards";
|
|
10
11
|
import { rectOf } from "../utils/geometry";
|
|
11
12
|
import { computeInsertZones, insertZonesKey } from "./iframe-insert";
|
|
12
13
|
import { getActiveElement, isEditing } from "../editor/inline-edit";
|
|
@@ -32,9 +33,10 @@ function isCanvasLeave(e: Event, doc: Document): boolean {
|
|
|
32
33
|
|
|
33
34
|
/** Walk up from an element to the nearest ancestor carrying a `data-jx-path`; null if none. */
|
|
34
35
|
function nearestPathEl(start: Element | null): HTMLElement | null {
|
|
35
|
-
let el = start instanceof Element ?
|
|
36
|
+
let el = start instanceof Element ? start : null;
|
|
36
37
|
while (el) {
|
|
37
|
-
|
|
38
|
+
// Only HTML elements are stamped (`makeStamper` skips everything else), so only they can match.
|
|
39
|
+
if (el instanceof HTMLElement && el.dataset.jxPath) {
|
|
38
40
|
return el;
|
|
39
41
|
}
|
|
40
42
|
el = el.parentElement;
|
|
@@ -57,6 +59,7 @@ export function nearestHit(target: EventTarget | null): NodeHit | null {
|
|
|
57
59
|
if (!el) {
|
|
58
60
|
return null;
|
|
59
61
|
}
|
|
62
|
+
// SAFETY: nearestPathEl returns only an element whose `data-jx-path` is a non-empty string.
|
|
60
63
|
return measureHit(el, el.dataset.jxPath as string);
|
|
61
64
|
}
|
|
62
65
|
|
|
@@ -75,8 +78,9 @@ export function nearestHit(target: EventTarget | null): NodeHit | null {
|
|
|
75
78
|
* from a node that is on screen is a worse failure than drawing one for a node that is not.
|
|
76
79
|
*/
|
|
77
80
|
function isRendered(el: Element): boolean {
|
|
78
|
-
|
|
79
|
-
|
|
81
|
+
// Absent on engines that predate it, whatever lib.dom says.
|
|
82
|
+
const check: Element["checkVisibility"] | undefined = el.checkVisibility;
|
|
83
|
+
return isFunction(check) ? check.call(el, { checkVisibilityCSS: true }) : true;
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
/**
|
|
@@ -92,10 +96,7 @@ function isRendered(el: Element): boolean {
|
|
|
92
96
|
* The serialized path is the same string the renderer stamps, so a stored selection path
|
|
93
97
|
* round-trips back to its element.
|
|
94
98
|
*/
|
|
95
|
-
export function measureHits(
|
|
96
|
-
paths: (string | number)[][],
|
|
97
|
-
doc: Document = document,
|
|
98
|
-
): { hits: NodeHit[]; hidden: (string | number)[][] } {
|
|
99
|
+
export function measureHits(paths: (string | number)[][], doc: Document = document) {
|
|
99
100
|
const hits: NodeHit[] = [];
|
|
100
101
|
const hidden: (string | number)[][] = [];
|
|
101
102
|
for (const path of paths) {
|
|
@@ -119,8 +120,15 @@ export function measureHits(
|
|
|
119
120
|
* {@link file://./iframe-drop.ts}'s `startGrabDetector` receives its deps rather than reaching for
|
|
120
121
|
* module state.
|
|
121
122
|
*/
|
|
123
|
+
type InvokerAction = Extract<IframeToParent, { kind: "popoverTargetClick" }>["action"];
|
|
124
|
+
|
|
122
125
|
/** The three `popovertargetaction` keywords. Anything else falls back to the HTML default. */
|
|
123
|
-
const INVOKER_ACTIONS = new Set(["toggle", "show", "hide"]);
|
|
126
|
+
const INVOKER_ACTIONS = new Set<string>(["toggle", "show", "hide"] satisfies InvokerAction[]);
|
|
127
|
+
|
|
128
|
+
/** Whether an attribute value is one of the {@link INVOKER_ACTIONS} keywords. */
|
|
129
|
+
function isInvokerAction(value: string): value is InvokerAction {
|
|
130
|
+
return INVOKER_ACTIONS.has(value);
|
|
131
|
+
}
|
|
124
132
|
|
|
125
133
|
/**
|
|
126
134
|
* Report an invoker click, when the click landed on one and it names an addressable popover.
|
|
@@ -152,14 +160,14 @@ function postPopoverInvoke(
|
|
|
152
160
|
need escaping — a rule this file already keeps in exactly one place (`jxPathSelector`) and
|
|
153
161
|
should not gain a second spelling of. The set scanned is the addressable POPOVERS, which is
|
|
154
162
|
also the set the answer has to come from, so the scan is the test. */
|
|
155
|
-
const panels = invoker.ownerDocument.querySelectorAll("[data-jx-popover]");
|
|
156
|
-
const panel = [...panels].find((el) => el.id === id)
|
|
163
|
+
const panels = invoker.ownerDocument.querySelectorAll<HTMLElement>("[data-jx-popover]");
|
|
164
|
+
const panel = [...panels].find((el) => el.id === id);
|
|
157
165
|
const serialized = panel?.dataset.jxPath;
|
|
158
166
|
if (!serialized) {
|
|
159
167
|
return;
|
|
160
168
|
}
|
|
161
169
|
const raw = invoker.getAttribute("popovertargetaction") ?? "toggle";
|
|
162
|
-
const action =
|
|
170
|
+
const action = isInvokerAction(raw) ? raw : "toggle";
|
|
163
171
|
channel.post({ action, kind: "popoverTargetClick", targetPath: parseJxPath(serialized) });
|
|
164
172
|
}
|
|
165
173
|
|
|
@@ -190,10 +198,10 @@ function postCommandInvoke(
|
|
|
190
198
|
}
|
|
191
199
|
// Scanned, not selected, for the reason `postPopoverInvoke` gives; the addressable overlays are
|
|
192
200
|
// The de-popovered panels and the stamped dialogs.
|
|
193
|
-
const overlays = invoker.ownerDocument.querySelectorAll(
|
|
201
|
+
const overlays = invoker.ownerDocument.querySelectorAll<HTMLElement>(
|
|
194
202
|
"[data-jx-popover], dialog[data-jx-path]",
|
|
195
203
|
);
|
|
196
|
-
const overlay = [...overlays].find((el) => el.id === id)
|
|
204
|
+
const overlay = [...overlays].find((el) => el.id === id);
|
|
197
205
|
const serialized = overlay?.dataset.jxPath;
|
|
198
206
|
if (!serialized) {
|
|
199
207
|
return;
|
|
@@ -270,7 +278,7 @@ export function startInteraction(
|
|
|
270
278
|
channel.post({ kind: "paneFocus" });
|
|
271
279
|
};
|
|
272
280
|
|
|
273
|
-
const onClick = (e:
|
|
281
|
+
const onClick = (e: MouseEvent) => {
|
|
274
282
|
/*
|
|
275
283
|
* Preview keeps anchors live, so a click would navigate this iframe and destroy the render (and
|
|
276
284
|
* the editing session with it). Report the intent so the parent can open the real page in a real
|
|
@@ -303,9 +311,8 @@ export function startInteraction(
|
|
|
303
311
|
// Ctrl/Cmd is the accumulate gesture (studio-ui-guidelines.md §8.1). The iframe reports the
|
|
304
312
|
// Modifier and nothing else — it holds no selection state, so what a modified click MEANS is
|
|
305
313
|
// The parent's to decide, exactly as the unmodified click already was.
|
|
306
|
-
const mouse = e as MouseEvent;
|
|
307
314
|
channel.post({
|
|
308
|
-
additive:
|
|
315
|
+
additive: e.ctrlKey === true || e.metaKey === true,
|
|
309
316
|
hit,
|
|
310
317
|
kind: "hit",
|
|
311
318
|
});
|
|
@@ -394,11 +401,10 @@ export function startInteraction(
|
|
|
394
401
|
reportInsertZones(target, { x: moveX, y: moveY });
|
|
395
402
|
};
|
|
396
403
|
|
|
397
|
-
const onMove = (e:
|
|
398
|
-
const pe = e as PointerEvent;
|
|
404
|
+
const onMove = (e: PointerEvent) => {
|
|
399
405
|
moveTarget = e.target;
|
|
400
|
-
moveX =
|
|
401
|
-
moveY =
|
|
406
|
+
moveX = e.clientX;
|
|
407
|
+
moveY = e.clientY;
|
|
402
408
|
if (movePending) {
|
|
403
409
|
return;
|
|
404
410
|
}
|
|
@@ -415,8 +421,7 @@ export function startInteraction(
|
|
|
415
421
|
}
|
|
416
422
|
};
|
|
417
423
|
|
|
418
|
-
const onContextMenu = (e:
|
|
419
|
-
const me = e as MouseEvent;
|
|
424
|
+
const onContextMenu = (e: MouseEvent) => {
|
|
420
425
|
// Preview keeps the NATIVE menu: the Jx element menu's verbs (duplicate, delete, paste, wrap)
|
|
421
426
|
// Are document edits, and preview does not edit. Copy Link Address does what it says instead.
|
|
422
427
|
if (isPreview()) {
|
|
@@ -447,8 +452,8 @@ export function startInteraction(
|
|
|
447
452
|
channel.post({
|
|
448
453
|
kind: "contextMenu",
|
|
449
454
|
path: hit.path,
|
|
450
|
-
x:
|
|
451
|
-
y:
|
|
455
|
+
x: e.clientX,
|
|
456
|
+
y: e.clientY,
|
|
452
457
|
});
|
|
453
458
|
};
|
|
454
459
|
|
|
@@ -56,6 +56,17 @@ import type { IframeToParent, ParentToIframe, SerializedKey, SyncedChord } from
|
|
|
56
56
|
*/
|
|
57
57
|
export const FRAME_KEY_SCOPES = ["caret", "canvas", "global"] as const;
|
|
58
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Commands whose chords the frame never forwards, though their scope is on its stack.
|
|
61
|
+
*
|
|
62
|
+
* `pane.backToHome` holds bare Escape in the global scope, and it applies only to a view opened
|
|
63
|
+
* beside a strip-less workspace's home (a media viewer, a comparison, `project.json` as Code), none
|
|
64
|
+
* of which is a canvas frame. Projected into the table, it made every frame cancel Escape in
|
|
65
|
+
* Preview and mid-sentence too, where nothing else claims it, so an author's own `<dialog>` or
|
|
66
|
+
* popover in the rendered page could no longer be dismissed with it.
|
|
67
|
+
*/
|
|
68
|
+
export const HOST_ONLY_COMMANDS: ReadonlySet<string> = new Set(["pane.backToHome"]);
|
|
69
|
+
|
|
59
70
|
/** The scope stack a caret session is in — app chords still fire, element-level ones do not. */
|
|
60
71
|
const CARET_STACK = ["caret", "global"] as const;
|
|
61
72
|
/** The stack with a selection but no caret: structural verbs are live. */
|
|
@@ -47,7 +47,7 @@ export function parentCursorToIframe(
|
|
|
47
47
|
cursor: { x: number; y: number },
|
|
48
48
|
iframeRect: { left: number; top: number },
|
|
49
49
|
scale = 1,
|
|
50
|
-
)
|
|
50
|
+
) {
|
|
51
51
|
return {
|
|
52
52
|
x: (cursor.x - iframeRect.left) / scale,
|
|
53
53
|
y: (cursor.y - iframeRect.top) / scale,
|
|
@@ -15,17 +15,19 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { reapplyStyle } from "@jxsuite/runtime";
|
|
18
|
-
import {
|
|
18
|
+
import { isNonNullObject, isNumber, isString } from "@jxsuite/schema/guards";
|
|
19
|
+
import { getNodeAtPath } from "@jxsuite/schema/doc-ops";
|
|
19
20
|
import { applyDocOpToDoc } from "../tabs/doc-op-apply";
|
|
20
21
|
import { parseJxPath, serializeJxPath } from "./path-mapping";
|
|
21
22
|
import { disposeSubtree, renderSubtreeIframe } from "./iframe-subtree";
|
|
22
23
|
import {
|
|
23
24
|
computeEmptyPlaceholderClass,
|
|
24
25
|
EMPTY_PLACEHOLDER_CLASSES,
|
|
26
|
+
isRowBound,
|
|
25
27
|
templateToEditDisplay,
|
|
26
28
|
} from "../utils/edit-display";
|
|
27
29
|
import type { IframeRenderCtx } from "./iframe-render";
|
|
28
|
-
import type {
|
|
30
|
+
import type { JxDocOp } from "../tabs/patch-ops";
|
|
29
31
|
import type { JxPath } from "../state";
|
|
30
32
|
import type { JxMutableNode, JxStyle } from "@jxsuite/schema/types";
|
|
31
33
|
|
|
@@ -36,7 +38,7 @@ import type { JxMutableNode, JxStyle } from "@jxsuite/schema/types";
|
|
|
36
38
|
*/
|
|
37
39
|
export function applyIframePatch(
|
|
38
40
|
shadowDoc: JxMutableNode,
|
|
39
|
-
forwardOps:
|
|
41
|
+
forwardOps: JxDocOp[],
|
|
40
42
|
container: HTMLElement,
|
|
41
43
|
ctx?: IframeRenderCtx,
|
|
42
44
|
echoPaths?: JxPath[],
|
|
@@ -98,7 +100,7 @@ function requireCtx(ctx: IframeRenderCtx | undefined): IframeRenderCtx {
|
|
|
98
100
|
|
|
99
101
|
function applyOpToDom(
|
|
100
102
|
doc: JxMutableNode,
|
|
101
|
-
op:
|
|
103
|
+
op: JxDocOp,
|
|
102
104
|
container: HTMLElement,
|
|
103
105
|
ctx: IframeRenderCtx | undefined,
|
|
104
106
|
): void {
|
|
@@ -138,7 +140,7 @@ function applyOpToDom(
|
|
|
138
140
|
return;
|
|
139
141
|
}
|
|
140
142
|
default: {
|
|
141
|
-
// The
|
|
143
|
+
// The JxDocOp union is exhaustively handled above; this guards a future op kind.
|
|
142
144
|
throw new Error(`iframe-patch-unsupported-op:${JSON.stringify(op)}`);
|
|
143
145
|
}
|
|
144
146
|
}
|
|
@@ -292,7 +294,7 @@ function remapChildPaths(
|
|
|
292
294
|
continue;
|
|
293
295
|
}
|
|
294
296
|
const idx = p[depth + 1];
|
|
295
|
-
if (
|
|
297
|
+
if (!isNumber(idx) || idx < fromIndex) {
|
|
296
298
|
continue;
|
|
297
299
|
}
|
|
298
300
|
if (!parentPath.every((seg, i) => p[i] === seg)) {
|
|
@@ -338,8 +340,10 @@ function patchStyle(
|
|
|
338
340
|
): void {
|
|
339
341
|
const el = requireElement(container, path);
|
|
340
342
|
const node = getNodeAtPath(doc, path);
|
|
341
|
-
|
|
342
|
-
|
|
343
|
+
/* SAFETY: buildScope writes `$media` only from the document's own `$media` map or the runtime's
|
|
344
|
+
* root media map, both Record<string, string>, and the host scope may not supply the key. */
|
|
345
|
+
const mediaQueries = (ctx?.defs["$media"] as Record<string, string> | undefined) ?? {};
|
|
346
|
+
reapplyStyle(el, editModeStyle(node?.style), mediaQueries, ctx?.defs ?? {});
|
|
343
347
|
}
|
|
344
348
|
|
|
345
349
|
/** Write the node's display text, syncing the empty-placeholder class like the full render. */
|
|
@@ -368,24 +372,24 @@ function findElement(container: HTMLElement, path: (string | number)[]): HTMLEle
|
|
|
368
372
|
}
|
|
369
373
|
|
|
370
374
|
/**
|
|
371
|
-
* Edit-mode style transform — mirrors prepareForEditMode
|
|
372
|
-
*
|
|
375
|
+
* Edit-mode style transform — mirrors prepareForEditMode: bindings are live and resolve against the
|
|
376
|
+
* render's scope, except a declaration that reads the repeater row, which the perimeter cannot
|
|
377
|
+
* supply and so is omitted.
|
|
373
378
|
*/
|
|
374
379
|
function editModeStyle(style: JxStyle | undefined): JxStyle | undefined {
|
|
375
|
-
if (!style ||
|
|
380
|
+
if (!style || !isNonNullObject(style)) {
|
|
376
381
|
return undefined;
|
|
377
382
|
}
|
|
378
|
-
const out:
|
|
383
|
+
const out: JxStyle = {};
|
|
379
384
|
for (const [k, v] of Object.entries(style)) {
|
|
380
|
-
/* OMITTED, not blanked
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
if (typeof v === "string" && v.includes("${")) {
|
|
385
|
+
/* OMITTED, not blanked: `color: ` is a malformed declaration in a rule, and an absent one lets
|
|
386
|
+
the cascade answer, which is what blanking always meant. */
|
|
387
|
+
if (isRowBound(v)) {
|
|
384
388
|
continue;
|
|
385
389
|
}
|
|
386
390
|
out[k] = v;
|
|
387
391
|
}
|
|
388
|
-
return out
|
|
392
|
+
return out;
|
|
389
393
|
}
|
|
390
394
|
|
|
391
395
|
/**
|
|
@@ -393,15 +397,15 @@ function editModeStyle(style: JxStyle | undefined): JxStyle | undefined {
|
|
|
393
397
|
* template-string and $ref display rules (and the legacy patcher's textDisplayValue).
|
|
394
398
|
*/
|
|
395
399
|
function textDisplayValue(node: JxMutableNode | undefined): string {
|
|
396
|
-
const v =
|
|
400
|
+
const v = node?.textContent;
|
|
397
401
|
if (v == null) {
|
|
398
402
|
return "";
|
|
399
403
|
}
|
|
400
|
-
if (
|
|
404
|
+
if (isString(v)) {
|
|
401
405
|
return v.includes("${") ? templateToEditDisplay(v) : v;
|
|
402
406
|
}
|
|
403
|
-
if (
|
|
404
|
-
const ref = String(
|
|
407
|
+
if (isNonNullObject(v) && v.$ref) {
|
|
408
|
+
const ref = String(v.$ref);
|
|
405
409
|
const label = ref.startsWith("#/state/") ? ref.slice(8) : ref;
|
|
406
410
|
return `{${label}}`;
|
|
407
411
|
}
|
|
@@ -33,6 +33,12 @@ export interface DocRange {
|
|
|
33
33
|
head: DocPos;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/** A live DOM caret position: a node and an offset into it, as a Selection endpoint carries. */
|
|
37
|
+
export interface DomPosition {
|
|
38
|
+
node: Node;
|
|
39
|
+
offset: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
36
42
|
/** Whether an element is a block the caret may live inside. Injected so the editable set is policy. */
|
|
37
43
|
export type EditablePredicate = (el: HTMLElement) => boolean;
|
|
38
44
|
|
|
@@ -91,7 +97,7 @@ export function elementForPath(container: HTMLElement, path: JxPath): HTMLElemen
|
|
|
91
97
|
|
|
92
98
|
/** The block's rendered text length — the maximum valid offset within it. */
|
|
93
99
|
export function blockTextLength(block: HTMLElement): number {
|
|
94
|
-
return block.textContent
|
|
100
|
+
return block.textContent.length;
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
/**
|
|
@@ -126,11 +132,12 @@ export function offsetOf(block: HTMLElement, node: Node, offset: number): number
|
|
|
126
132
|
* every offset-based editor carries at a line break, and it is invisible for the paths that use
|
|
127
133
|
* this (caret restore after a patch, and block-boundary edits, which clamp to 0 / length anyway).
|
|
128
134
|
*/
|
|
129
|
-
export function domPositionAt(block: HTMLElement, offset: number):
|
|
135
|
+
export function domPositionAt(block: HTMLElement, offset: number): DomPosition {
|
|
130
136
|
const target = Math.max(0, Math.min(offset, blockTextLength(block)));
|
|
131
137
|
const walker = block.ownerDocument.createTreeWalker(block, NodeFilter.SHOW_TEXT);
|
|
132
138
|
let seen = 0;
|
|
133
139
|
let last: Text | null = null;
|
|
140
|
+
// SAFETY: the walker was created with NodeFilter.SHOW_TEXT, so every node it yields is a Text.
|
|
134
141
|
let current = walker.nextNode() as Text | null;
|
|
135
142
|
while (current) {
|
|
136
143
|
const len = current.length;
|
|
@@ -139,6 +146,7 @@ export function domPositionAt(block: HTMLElement, offset: number): { node: Node;
|
|
|
139
146
|
}
|
|
140
147
|
seen += len;
|
|
141
148
|
last = current;
|
|
149
|
+
// SAFETY: the same SHOW_TEXT walker as above, so the next node is a Text or the walk's end.
|
|
142
150
|
current = walker.nextNode() as Text | null;
|
|
143
151
|
}
|
|
144
152
|
// No text node reaches the target: either the block has no text at all (caret goes to the element
|
|
@@ -169,10 +177,7 @@ export function toDocPos(
|
|
|
169
177
|
* block whose text shrank under a remote edit lands at the block's new end instead of being
|
|
170
178
|
* dropped.
|
|
171
179
|
*/
|
|
172
|
-
export function toDomPosition(
|
|
173
|
-
container: HTMLElement,
|
|
174
|
-
pos: DocPos,
|
|
175
|
-
): { node: Node; offset: number } | null {
|
|
180
|
+
export function toDomPosition(container: HTMLElement, pos: DocPos): DomPosition | null {
|
|
176
181
|
const el = elementForPath(container, pos.path);
|
|
177
182
|
return el ? domPositionAt(el, pos.offset) : null;
|
|
178
183
|
}
|
|
@@ -246,6 +251,7 @@ export function adjacentBlock(
|
|
|
246
251
|
const key = serializeJxPath(path);
|
|
247
252
|
const index = blocks.findIndex((el) => el.dataset.jxPath === key);
|
|
248
253
|
const neighbour = index === -1 ? undefined : blocks[index + direction];
|
|
254
|
+
// SAFETY: blocksInOrder collects only elements matching `[data-jx-path]`, so the attribute is set.
|
|
249
255
|
return neighbour
|
|
250
256
|
? { el: neighbour, path: parseJxPath(neighbour.dataset.jxPath as string) }
|
|
251
257
|
: null;
|