@jxsuite/studio 6.1.1 → 6.1.2
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/dist/chunks/{2020-va2wwra4.js → 2020-f2gkpy8d.js} +3 -3
- package/dist/chunks/{action-group-2mqby73c.js → action-group-4aan7g6g.js} +3 -3
- package/dist/chunks/adapter-4912g339.js +4 -0
- package/dist/chunks/cf-account-picker-wccaenh6.js +4 -0
- package/dist/chunks/cf-settings-br6105tr.js +4 -0
- package/dist/chunks/color-28ksk2qm.js +4 -0
- package/dist/chunks/color-area-0fj8a4ga.js +4 -0
- package/dist/chunks/color-field-xch8kx2g.js +4 -0
- package/dist/chunks/color-slider-jxd8v350.js +4 -0
- package/dist/chunks/combobox-p0efwjke.js +4 -0
- package/dist/chunks/components-db68vsn7.js +4 -0
- package/dist/chunks/content-source-1449qesq.js +4 -0
- package/dist/chunks/convert-to-repeater-5h457egj.js +4 -0
- package/dist/chunks/dialog-c4x05vyx.js +4 -0
- package/dist/chunks/editor-x9jn86a7.js +4 -0
- package/dist/chunks/entry-commands-may24cpt.js +4 -0
- package/dist/chunks/extension-sections-pvr14vxr.js +4 -0
- package/dist/chunks/file-ops-x9v54pcj.js +4 -0
- package/dist/chunks/files-j3knqf0s.js +4 -0
- package/dist/chunks/format-host-tyre2trb.js +4 -0
- package/dist/chunks/fs-events-64ma9htc.js +4 -0
- package/dist/chunks/git-panel-84ps5dex.js +4 -0
- package/dist/chunks/grid-view-d2wq9ezg.js +51 -0
- package/dist/chunks/icons-pnfz478q.js +4 -0
- package/dist/chunks/iframe-entry-fvbk89gm.js +5 -0
- package/dist/chunks/iframe-entry-jdcktez8.js +5 -0
- package/dist/chunks/iframe-entry-x0ygf2yr.js +5 -0
- package/dist/chunks/iframe-entry-zap785cw.js +5 -0
- package/dist/chunks/iframe-host-ck6vejt5.js +4 -0
- package/dist/chunks/index-b8xw3vy9.js +4 -0
- package/dist/chunks/{index-2veqmnhr.js → index-zpjmzqfk.js} +3 -3
- package/dist/chunks/{javascript-8nbvs12s.js → javascript-m54mnwp6.js} +3 -3
- package/dist/chunks/{jsonMode-s8kt9dsj.js → jsonMode-w15cmrcm.js} +8 -8
- package/dist/chunks/jx-validate-at3zn8wa.js +4 -0
- package/dist/chunks/layers-h4xp1pss.js +4 -0
- package/dist/chunks/layers-panel-m5hw1d7g.js +4 -0
- package/dist/chunks/listbox-e74qjyq6.js +4 -0
- package/dist/chunks/lit-html-8t8t3dnr.js +4 -0
- package/dist/chunks/media-picker-2cweexc5.js +4 -0
- package/dist/chunks/menu-n6yzswmy.js +4 -0
- package/dist/chunks/menu-ynw13y0s.js +4 -0
- package/dist/chunks/monaco-binding-7gx83x3r.js +4 -0
- package/dist/chunks/monaco-buffer-qzxn567r.js +4 -0
- package/dist/chunks/monaco-setup-gxf6656g.js +4 -0
- package/dist/chunks/notify-cj5zbrs2.js +4 -0
- package/dist/chunks/number-field-y62xq0ty.js +4 -0
- package/dist/chunks/parse-b7ddhr8m.js +4 -0
- package/dist/chunks/platform-3dfws9js.js +4 -0
- package/dist/chunks/popover-jt2gxmzs.js +4 -0
- package/dist/chunks/publish-panel-1gvxbj21.js +4 -0
- package/dist/chunks/quick-search-0dajrwqg.js +4 -0
- package/dist/chunks/references-49qgt404.js +4 -0
- package/dist/chunks/right-panel-jm1bwe53.js +4 -0
- package/dist/chunks/section-registry-6kwc4fky.js +4 -0
- package/dist/chunks/select-rzds841e.js +4 -0
- package/dist/chunks/split-n2gfpm5m.js +4 -0
- package/dist/chunks/{studio-1q1sh2ax.js → studio-0q988f9w.js} +3 -3
- package/dist/chunks/studio-0rt52vpq.js +5 -0
- package/dist/chunks/studio-18vgbhs5.js +5 -0
- package/dist/chunks/{studio-h46vtzk8.js → studio-1fxkaaea.js} +4 -4
- package/dist/chunks/studio-24mccdrj.js +5 -0
- package/dist/chunks/studio-2eh507zk.js +9 -0
- package/dist/chunks/studio-2hcbccfv.js +5 -0
- package/dist/chunks/studio-2j1cb95x.js +5 -0
- package/dist/chunks/studio-2jbs3rxv.js +5 -0
- package/dist/chunks/{studio-rv11kfwa.js → studio-485046te.js} +7 -7
- package/dist/chunks/studio-4h8k4dw9.js +5 -0
- package/dist/chunks/studio-5f6n18kx.js +5 -0
- package/dist/chunks/studio-5gthpky6.js +5 -0
- package/dist/chunks/studio-5ve6bbep.js +5 -0
- package/dist/chunks/studio-6ep3js6b.js +9 -0
- package/dist/chunks/studio-6wkmf3wz.js +9 -0
- package/dist/chunks/studio-841rf3cg.js +5 -0
- package/dist/chunks/studio-8gmwgheg.js +5 -0
- package/dist/chunks/studio-8qm0ep50.js +5 -0
- package/dist/chunks/{studio-8grwxtqk.js → studio-90pq9km1.js} +4 -4
- package/dist/chunks/studio-924p1tm1.js +6 -0
- package/dist/chunks/{studio-pre0skq6.js → studio-a3g98wjr.js} +4 -4
- package/dist/chunks/studio-a3shpz9y.js +5 -0
- package/dist/chunks/studio-amsbaaar.js +6 -0
- package/dist/chunks/studio-at5spjbc.js +7 -0
- package/dist/chunks/studio-b2xv945e.js +5 -0
- package/dist/chunks/studio-bn5nkafw.js +5 -0
- package/dist/chunks/studio-bw6q5xjf.js +9 -0
- package/dist/chunks/studio-c7q0t9x1.js +5 -0
- package/dist/chunks/studio-camnhc96.js +6 -0
- package/dist/chunks/studio-cffqvnzd.js +5 -0
- package/dist/chunks/studio-d81xfh1g.js +5 -0
- package/dist/chunks/studio-dgz8d0c1.js +5 -0
- package/dist/chunks/studio-efvfrsf8.js +5 -0
- package/dist/chunks/studio-er30bpcx.js +5 -0
- package/dist/chunks/studio-ezscgr64.js +5 -0
- package/dist/chunks/studio-ffrrncvz.js +5 -0
- package/dist/chunks/studio-fpphgn8y.js +10 -0
- package/dist/chunks/studio-j1kvhdjk.js +4 -0
- package/dist/chunks/{studio-vrmcjf9g.js → studio-j430n16g.js} +5 -5
- package/dist/chunks/studio-jjkg84nj.js +5 -0
- package/dist/chunks/studio-m0q32ars.js +4 -0
- package/dist/chunks/studio-m6bdst11.js +5 -0
- package/dist/chunks/studio-nv2cptd4.js +64 -0
- package/dist/chunks/studio-nwfrc98n.js +5 -0
- package/dist/chunks/studio-p1wgvp7r.js +5 -0
- package/dist/chunks/studio-pag2wncm.js +5 -0
- package/dist/chunks/studio-qvanvzfd.js +5 -0
- package/dist/chunks/studio-qwa64kt7.js +5 -0
- package/dist/chunks/studio-rk1zc4x3.js +928 -0
- package/dist/chunks/studio-se2r3ptc.js +5 -0
- package/dist/chunks/studio-sg2a0dh0.js +5 -0
- package/dist/chunks/studio-tjzjhe68.js +5 -0
- package/dist/chunks/{studio-wszjyh0j.js → studio-tq0rtfwj.js} +4 -4
- package/dist/chunks/{studio-kggey1jt.js → studio-v0jzqdjm.js} +4 -4
- package/dist/chunks/studio-v2w7q8r1.js +7 -0
- package/dist/chunks/studio-v5vjq1h0.js +4 -0
- package/dist/chunks/studio-v8aga3vp.js +14 -0
- package/dist/chunks/studio-vfcdrfmv.js +5 -0
- package/dist/chunks/studio-vmfkgdjf.js +5 -0
- package/dist/chunks/studio-wt1816jj.js +5 -0
- package/dist/chunks/studio-wz73q5kq.js +4 -0
- package/dist/chunks/studio-y04qtxvp.js +7 -0
- package/dist/chunks/studio-y21g8zzg.js +5 -0
- package/dist/chunks/{studio-zey7zsdw.js → studio-y64hrt8p.js} +7 -7
- package/dist/chunks/studio-ynn90f58.js +16 -0
- package/dist/chunks/studio-yxz682sx.js +5 -0
- package/dist/chunks/studio-zp7snvkq.js +5 -0
- package/dist/chunks/studio-zq4z6tm6.js +5 -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-c9fn075p.js +4 -0
- package/dist/chunks/toast-host-ke5z4ng7.js +4 -0
- package/dist/chunks/{toolbar-2nnzqhrj.js → toolbar-44cm5cta.js} +3 -3
- package/dist/chunks/tooltip-5v8ngwj2.js +4 -0
- package/dist/chunks/tree-mdq3v5cw.js +4 -0
- package/dist/chunks/{tsMode-2frah6h1.js → tsMode-sf49ee9x.js} +7 -7
- package/dist/chunks/workspace-jtfahpee.js +4 -0
- package/dist/chunks/ws-client-nze0k6mv.js +4 -0
- package/dist/iframe-entry.js +16 -16
- package/dist/manifest.json +63 -63
- package/dist/studio.js +97 -97
- package/package.json +6 -6
- 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/library-layouts.ts +8 -5
- package/src/browse/library-model.ts +18 -6
- package/src/browse/library-pane.ts +37 -21
- package/src/browse/library-preview.ts +14 -9
- package/src/browse/library-source.ts +1 -1
- package/src/canvas/asset-refs.ts +24 -9
- package/src/canvas/asset-resolve.ts +19 -23
- package/src/canvas/canvas-helpers.ts +7 -6
- package/src/canvas/canvas-live-render.ts +44 -53
- package/src/canvas/canvas-patcher.ts +30 -30
- package/src/canvas/canvas-perf.ts +11 -5
- package/src/canvas/canvas-render.ts +62 -41
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +90 -49
- 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 +13 -12
- package/src/canvas/iframe-editable-root.ts +29 -16
- package/src/canvas/iframe-entry.ts +80 -63
- package/src/canvas/iframe-eval.ts +73 -49
- package/src/canvas/iframe-host.ts +135 -96
- 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-overlay.ts +1 -1
- package/src/canvas/iframe-patch.ts +18 -15
- package/src/canvas/iframe-position.ts +12 -6
- package/src/canvas/iframe-protocol.ts +12 -16
- package/src/canvas/iframe-render.ts +36 -34
- package/src/canvas/iframe-slash.ts +24 -11
- package/src/canvas/iframe-subtree.ts +6 -2
- 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/serialize-scope.ts +13 -5
- package/src/canvas/stage-scrollbar.ts +2 -1
- package/src/canvas/surface-registry.ts +21 -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/budget.ts +3 -3
- package/src/commands/command-args.ts +103 -71
- package/src/commands/context.ts +22 -20
- package/src/commands/keymap.ts +47 -43
- package/src/commands/levels.ts +3 -3
- package/src/commands/live-context.ts +7 -7
- package/src/commands/reference.ts +2 -1
- package/src/commands/registry.ts +12 -10
- package/src/commands/run-reported.ts +15 -10
- package/src/component-props.ts +46 -30
- package/src/content/collection-match.ts +5 -4
- package/src/content/draft-state.ts +4 -3
- package/src/content/entry-commands.ts +3 -2
- package/src/content/entry-editor.ts +29 -17
- package/src/content/entry-fields.ts +12 -7
- package/src/content/entry-model.ts +21 -12
- 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 +11 -5
- package/src/editor/convert-to-repeater.ts +34 -22
- package/src/editor/editable-tags.ts +17 -2
- package/src/editor/file-drop-action.ts +21 -22
- package/src/editor/inline-edit-apply.ts +35 -17
- package/src/editor/inline-edit.ts +66 -50
- package/src/editor/inline-format.ts +59 -56
- package/src/editor/inline-link.ts +40 -15
- package/src/editor/insert-zone-action.ts +1 -1
- package/src/editor/merge-tags.ts +58 -19
- package/src/editor/repeater-scope.ts +39 -28
- package/src/editor/shortcuts.ts +32 -20
- package/src/editor/slash-menu.ts +1 -6
- package/src/files/asset-versions.ts +4 -4
- package/src/files/components.ts +15 -10
- package/src/files/elements.ts +5 -6
- package/src/files/file-ops.ts +77 -36
- package/src/files/files.ts +90 -95
- package/src/files/media-meta.ts +2 -1
- package/src/files/media-paths.ts +3 -0
- package/src/files/serialize-document.ts +2 -2
- 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 +76 -50
- package/src/github/github-auth-status.ts +27 -3
- package/src/github/github-auth.ts +19 -9
- package/src/github/github-publish.ts +24 -20
- 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 +20 -22
- package/src/grid/grid-layout.ts +21 -5
- package/src/grid/grid-open.ts +3 -6
- package/src/grid/grid-panel.ts +11 -4
- package/src/grid/grid-source.ts +8 -8
- package/src/grid/grid-view.ts +14 -17
- 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 +25 -24
- package/src/grid/sources/csv-file-source.ts +2 -2
- package/src/grid/tabulator-tables.d.ts +55 -34
- package/src/hosting/stage.ts +7 -7
- package/src/i18n/i18n-commands.ts +1 -2
- package/src/media/media-pane.ts +4 -1
- 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 +17 -9
- package/src/panels/ai-chat/attached-context.ts +13 -7
- 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 +46 -35
- package/src/panels/bottom-dock.ts +5 -3
- package/src/panels/canvas-dnd-bridge.ts +31 -24
- package/src/panels/data-explorer.ts +62 -25
- package/src/panels/data-grid.ts +14 -11
- package/src/panels/dnd.ts +108 -118
- package/src/panels/editors.ts +52 -21
- package/src/panels/elements-panel.ts +10 -3
- package/src/panels/events-panel.ts +84 -69
- package/src/panels/formula-workspace.ts +76 -51
- package/src/panels/frontmatter-fields.ts +24 -19
- package/src/panels/frontmatter-panel.ts +44 -34
- package/src/panels/git-diff-open.ts +4 -4
- package/src/panels/git-panel.ts +49 -61
- package/src/panels/head-panel.ts +131 -111
- package/src/panels/i18n-panel.ts +10 -3
- package/src/panels/imports-panel.ts +23 -47
- package/src/panels/jump-bar.ts +48 -29
- package/src/panels/layers-panel.ts +97 -74
- package/src/panels/left-panel.ts +3 -3
- package/src/panels/pane-context.ts +31 -22
- package/src/panels/pane-grid.ts +49 -20
- package/src/panels/panel-registry.ts +22 -37
- package/src/panels/properties-panel.ts +175 -121
- package/src/panels/quick-search.ts +53 -31
- package/src/panels/right-panel.ts +3 -3
- package/src/panels/seo-modal.ts +13 -17
- package/src/panels/settings-menu.ts +15 -15
- package/src/panels/signals-panel.ts +153 -131
- package/src/panels/statement-editor.ts +230 -140
- package/src/panels/style-panel.ts +218 -205
- package/src/panels/style-utils.ts +114 -51
- package/src/panels/stylebook-doc.ts +57 -54
- package/src/panels/stylebook-layers-panel.ts +9 -9
- package/src/panels/stylebook-panel.ts +13 -17
- package/src/panels/tab-drop.ts +27 -11
- package/src/panels/tab-strip.ts +36 -26
- package/src/platform-errors.ts +57 -43
- package/src/platform.ts +58 -30
- package/src/platforms/cloud.ts +345 -175
- package/src/platforms/default-platform.ts +10 -4
- package/src/platforms/devserver.ts +129 -117
- package/src/platforms/read-batcher.ts +16 -8
- package/src/project-list.ts +2 -1
- package/src/publish/deploy-checklist.ts +8 -2
- package/src/publish/pages-service.ts +28 -13
- package/src/publish/publish-commands.ts +5 -4
- package/src/publish/publish-panel.ts +10 -6
- 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 +58 -31
- package/src/services/cem-export.ts +149 -58
- package/src/services/clock.ts +6 -1
- package/src/services/code-services.ts +37 -31
- 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 +18 -12
- 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 +8 -7
- 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 +79 -60
- package/src/settings/css-vars-editor.ts +37 -16
- package/src/settings/defs-editor.ts +38 -35
- package/src/settings/extension-rows.ts +16 -8
- package/src/settings/extension-sections.ts +23 -13
- package/src/settings/extensions-section.ts +4 -1
- package/src/settings/general-settings.ts +11 -8
- package/src/settings/locales-section.ts +20 -12
- package/src/settings/preferences-dialog.ts +9 -6
- package/src/settings/preferences-keymap.ts +7 -5
- package/src/settings/preferences-sections.ts +11 -5
- package/src/settings/project-sections.ts +1 -1
- package/src/settings/schema-field-ui.ts +9 -0
- package/src/settings/settings-document.ts +5 -5
- package/src/shell/tree.ts +6 -5
- package/src/shell.ts +104 -81
- package/src/site-context.ts +37 -22
- package/src/state.ts +41 -49
- package/src/store.ts +54 -34
- package/src/studio.ts +25 -75
- package/src/style/live-preview.ts +1 -1
- package/src/style/project-styles.ts +6 -7
- package/src/style/token-ref.ts +5 -4
- package/src/surfaces/about.ts +18 -19
- package/src/surfaces/add-repo.ts +17 -19
- package/src/surfaces/ai-chat.ts +31 -36
- 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.ts +4 -5
- package/src/surfaces/bottom-dock.ts +9 -18
- package/src/surfaces/canvas-stage.ts +12 -11
- package/src/surfaces/cf-account-picker.ts +17 -18
- package/src/surfaces/commandbar.ts +14 -9
- 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/doc-header.ts +10 -19
- package/src/surfaces/empty-state.ts +7 -10
- package/src/surfaces/entry-editor.ts +14 -11
- 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/git-panel.ts +7 -15
- 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.ts +13 -12
- package/src/surfaces/jump-bar.ts +5 -6
- package/src/surfaces/jxsuite-update.ts +16 -22
- package/src/surfaces/library-pane.ts +19 -20
- package/src/surfaces/logic-panel.ts +17 -30
- package/src/surfaces/logic-workspace.ts +13 -15
- package/src/surfaces/media-browser.ts +11 -10
- package/src/surfaces/media-field.ts +4 -5
- package/src/surfaces/media-pane.ts +8 -7
- package/src/surfaces/menu.ts +29 -23
- package/src/surfaces/navigator-dock.ts +11 -12
- package/src/surfaces/new-project.ts +27 -26
- package/src/surfaces/pane-context.ts +20 -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.ts +5 -6
- 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.ts +11 -18
- package/src/surfaces/panel-problems.ts +5 -7
- package/src/surfaces/panel-signals.ts +20 -34
- package/src/surfaces/panel-stylebook-layers.ts +5 -8
- package/src/surfaces/preferences.ts +21 -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.ts +18 -18
- package/src/surfaces/push-plan.ts +7 -8
- package/src/surfaces/rail.ts +13 -13
- package/src/surfaces/reference-field.ts +11 -15
- package/src/surfaces/schema-builder.ts +16 -22
- package/src/surfaces/schema-form.ts +15 -25
- package/src/surfaces/secret-field.ts +9 -6
- package/src/surfaces/seo.ts +21 -15
- package/src/surfaces/settings-contexts.ts +9 -7
- package/src/surfaces/settings-contributed.ts +14 -10
- package/src/surfaces/settings-css-vars.ts +5 -12
- package/src/surfaces/settings-defs.json +2 -2
- package/src/surfaces/settings-defs.ts +17 -21
- package/src/surfaces/settings-deploy.ts +8 -15
- 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.ts +5 -6
- package/src/surfaces/settings-packages.ts +8 -7
- package/src/surfaces/settings-pane.ts +9 -18
- package/src/surfaces/settings-rawjson.ts +5 -6
- package/src/surfaces/shell.ts +1 -2
- package/src/surfaces/slash-menu.ts +19 -9
- package/src/surfaces/statements.ts +13 -18
- package/src/surfaces/statusbar.ts +17 -14
- package/src/surfaces/style-panel.ts +18 -31
- package/src/surfaces/stylebook-chrome.ts +3 -5
- package/src/surfaces/tab-strip.ts +14 -13
- package/src/surfaces/target-line.ts +6 -7
- package/src/surfaces/welcome.ts +5 -7
- 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 +52 -41
- package/src/tabs/transact.ts +98 -53
- package/src/types.ts +32 -17
- 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 +57 -48
- package/src/ui/formula-catalog.ts +239 -230
- package/src/ui/formula-chips.ts +33 -18
- package/src/ui/layers.ts +44 -31
- package/src/ui/media-picker.ts +18 -9
- package/src/ui/popover-surface.ts +20 -12
- package/src/ui/progress-modal.ts +13 -8
- package/src/ui/regions.ts +7 -6
- package/src/ui/schema-form.ts +113 -70
- 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 +3 -2
- package/src/utils/base64.ts +3 -1
- package/src/utils/edit-display.ts +73 -73
- 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/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 +10 -12
- package/src/workspace/session.ts +53 -43
- package/src/workspace/workspace.ts +40 -36
- 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/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-t6b6qe31.js +0 -5
- package/dist/chunks/studio-tdcprbqb.js +0 -5
- 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-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/workspace-zt81g1ms.js +0 -4
- package/dist/chunks/ws-client-n2bh4hkf.js +0 -4
|
@@ -22,6 +22,8 @@ import { componentRegistry } from "../files/components";
|
|
|
22
22
|
import { uploadAssets } from "../files/media-upload";
|
|
23
23
|
import { applyDropInstruction } from "../panels/dnd";
|
|
24
24
|
import { mutateUpdateAttribute, mutateUpdateProp, transactDoc } from "../tabs/transact";
|
|
25
|
+
import { isNumber } from "@jxsuite/schema/guards";
|
|
26
|
+
import type { ComponentEntry } from "../files/components";
|
|
25
27
|
import type { UploadedAsset } from "../files/media-upload";
|
|
26
28
|
import type { DropPreview, FileDropHit } from "../canvas/iframe-protocol";
|
|
27
29
|
import type { JxPath } from "../state";
|
|
@@ -30,12 +32,12 @@ import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
|
30
32
|
import { isMediaFormat } from "../utils/studio-utils";
|
|
31
33
|
|
|
32
34
|
/** Where an asset's URL goes when it replaces an existing element's picture. */
|
|
33
|
-
const REPLACE_ATTRS
|
|
34
|
-
img
|
|
35
|
-
source
|
|
35
|
+
const REPLACE_ATTRS = new Map<string, "src" | "poster">([
|
|
36
|
+
["img", "src"],
|
|
37
|
+
["source", "src"],
|
|
36
38
|
// A <video>'s own `src` is the movie; dropping an image on one sets its poster frame instead.
|
|
37
|
-
video
|
|
38
|
-
|
|
39
|
+
["video", "poster"],
|
|
40
|
+
]);
|
|
39
41
|
|
|
40
42
|
/** What a drop resolves to once the parent has applied its semantics. */
|
|
41
43
|
export type FileDropTarget =
|
|
@@ -43,11 +45,8 @@ export type FileDropTarget =
|
|
|
43
45
|
| { mode: "replace-prop"; path: JxPath; prop: string }
|
|
44
46
|
| { mode: "insert" };
|
|
45
47
|
|
|
46
|
-
/**
|
|
47
|
-
|
|
48
|
-
tagName: string;
|
|
49
|
-
props?: { name: string; format?: unknown; [k: string]: unknown }[];
|
|
50
|
-
}
|
|
48
|
+
/** The part of a registry entry {@link resolveFileDropTarget} reads: its tag and declared props. */
|
|
49
|
+
type RegistryEntry = Pick<ComponentEntry, "tagName" | "props">;
|
|
51
50
|
|
|
52
51
|
/**
|
|
53
52
|
* Decide whether a drop replaces an existing picture or inserts a new element.
|
|
@@ -66,15 +65,15 @@ export function resolveFileDropTarget(
|
|
|
66
65
|
if (!hit || kind !== "image") {
|
|
67
66
|
return { mode: "insert" };
|
|
68
67
|
}
|
|
69
|
-
const attr = REPLACE_ATTRS
|
|
68
|
+
const attr = REPLACE_ATTRS.get(hit.tagName);
|
|
70
69
|
if (attr) {
|
|
71
|
-
return { attr, mode: "replace-attr", path: hit.path
|
|
70
|
+
return { attr, mode: "replace-attr", path: hit.path };
|
|
72
71
|
}
|
|
73
72
|
if (hit.tagName.includes("-")) {
|
|
74
73
|
const entry = registry.find((c) => c.tagName === hit.tagName);
|
|
75
74
|
const imageProps = (entry?.props ?? []).filter((p) => isMediaFormat(p.format));
|
|
76
75
|
if (imageProps.length === 1) {
|
|
77
|
-
return { mode: "replace-prop", path: hit.path
|
|
76
|
+
return { mode: "replace-prop", path: hit.path, prop: imageProps[0]!.name };
|
|
78
77
|
}
|
|
79
78
|
}
|
|
80
79
|
return { mode: "insert" };
|
|
@@ -88,20 +87,20 @@ export function resolveFileDropTarget(
|
|
|
88
87
|
export function elementForAsset(asset: UploadedAsset): JxMutableNode {
|
|
89
88
|
switch (asset.kind) {
|
|
90
89
|
case "image": {
|
|
91
|
-
return { attributes: { alt: "", src: asset.ref }, tagName: "img" }
|
|
90
|
+
return { attributes: { alt: "", src: asset.ref }, tagName: "img" };
|
|
92
91
|
}
|
|
93
92
|
case "video": {
|
|
94
|
-
return { attributes: { controls: "", src: asset.ref }, tagName: "video" }
|
|
93
|
+
return { attributes: { controls: "", src: asset.ref }, tagName: "video" };
|
|
95
94
|
}
|
|
96
95
|
case "audio": {
|
|
97
|
-
return { attributes: { controls: "", src: asset.ref }, tagName: "audio" }
|
|
96
|
+
return { attributes: { controls: "", src: asset.ref }, tagName: "audio" };
|
|
98
97
|
}
|
|
99
98
|
default: {
|
|
100
99
|
return {
|
|
101
100
|
attributes: { href: asset.ref },
|
|
102
101
|
tagName: "a",
|
|
103
102
|
textContent: asset.name,
|
|
104
|
-
}
|
|
103
|
+
};
|
|
105
104
|
}
|
|
106
105
|
}
|
|
107
106
|
}
|
|
@@ -114,13 +113,13 @@ export function elementForAsset(asset: UploadedAsset): JxMutableNode {
|
|
|
114
113
|
* they were dropped. `make-child` appends, which is already ordered.
|
|
115
114
|
*/
|
|
116
115
|
export function nthDropPath(preview: DropPreview, n: number): JxPath {
|
|
117
|
-
const path = [...preview.targetPath];
|
|
116
|
+
const path: JxPath = [...preview.targetPath];
|
|
118
117
|
const tail = path.at(-1);
|
|
119
|
-
if (n === 0 ||
|
|
120
|
-
return path
|
|
118
|
+
if (n === 0 || !isNumber(tail)) {
|
|
119
|
+
return path;
|
|
121
120
|
}
|
|
122
121
|
path[path.length - 1] = tail + n;
|
|
123
|
-
return path
|
|
122
|
+
return path;
|
|
124
123
|
}
|
|
125
124
|
|
|
126
125
|
/**
|
|
@@ -160,7 +159,7 @@ export async function applyFileDrop(
|
|
|
160
159
|
if (preview) {
|
|
161
160
|
applyDropInstruction(tab, { type: preview.instruction }, srcData, nthDropPath(preview, i));
|
|
162
161
|
} else {
|
|
163
|
-
applyDropInstruction(tab, { type: "make-child" }, srcData, []
|
|
162
|
+
applyDropInstruction(tab, { type: "make-child" }, srcData, []);
|
|
164
163
|
}
|
|
165
164
|
}
|
|
166
165
|
}
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* boundary.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import {
|
|
10
|
+
import { getNodeAtPath } from "@jxsuite/schema/doc-ops";
|
|
11
|
+
import { isNonNullObject, isNumber, isString } from "@jxsuite/schema/guards";
|
|
12
|
+
import { childIndex, parentElementPath } from "../store";
|
|
11
13
|
import { isAncestor } from "../state";
|
|
12
14
|
import { isTabActive } from "../workspace/workspace";
|
|
13
15
|
import {
|
|
@@ -24,6 +26,7 @@ import type { JxContentResult, SlashCommand } from "./inline-edit";
|
|
|
24
26
|
import type { JxPath } from "../state";
|
|
25
27
|
import type { Tab } from "../tabs/tab";
|
|
26
28
|
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
29
|
+
import type { SpliceCoordinate } from "../tabs/selection";
|
|
27
30
|
|
|
28
31
|
/**
|
|
29
32
|
* Whether a committed inline-edit result is effectively empty (blank text / lone whitespace /
|
|
@@ -43,10 +46,21 @@ export function isEmptyContent(commitData?: JxContentResult): boolean {
|
|
|
43
46
|
if (kids.length === 0) {
|
|
44
47
|
return true;
|
|
45
48
|
}
|
|
46
|
-
|
|
49
|
+
const [only] = kids;
|
|
50
|
+
if (kids.length === 1 && isString(only) && only.trim() === "") {
|
|
47
51
|
return true;
|
|
48
52
|
}
|
|
49
|
-
|
|
53
|
+
// The result crossed the frame boundary as JSON, so a `null` child is excluded here explicitly.
|
|
54
|
+
return kids.length === 1 && isNonNullObject(only) && only.tagName === "br";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The slot of the block at `path`. */
|
|
58
|
+
function blockSlot(path: JxPath): SpliceCoordinate {
|
|
59
|
+
/* SAFETY: a block with a sibling position has an element path ending in `"children", <index>`, so
|
|
60
|
+
it has a parent element path and its last segment is the numeric child index. A repeater's
|
|
61
|
+
template root (`…, "map"`) is editable too; callers do not exclude that case yet, so it reaches
|
|
62
|
+
here with a string segment exactly as before this cast. */
|
|
63
|
+
return { index: childIndex(path) as number, parentPath: parentElementPath(path) as JxPath };
|
|
50
64
|
}
|
|
51
65
|
|
|
52
66
|
/**
|
|
@@ -126,7 +140,7 @@ export function applyInlinePropCommit(
|
|
|
126
140
|
if (!node) {
|
|
127
141
|
return false;
|
|
128
142
|
}
|
|
129
|
-
const current =
|
|
143
|
+
const current = node.$props?.[prop];
|
|
130
144
|
if (`${current ?? ""}` === value) {
|
|
131
145
|
return false;
|
|
132
146
|
}
|
|
@@ -155,8 +169,8 @@ export function applyBlockMerge(
|
|
|
155
169
|
if (!tab) {
|
|
156
170
|
return null;
|
|
157
171
|
}
|
|
158
|
-
const from = getNodeAtPath(tab.doc.document, fromPath)
|
|
159
|
-
const into = getNodeAtPath(tab.doc.document, intoPath)
|
|
172
|
+
const from = getNodeAtPath(tab.doc.document, fromPath);
|
|
173
|
+
const into = getNodeAtPath(tab.doc.document, intoPath);
|
|
160
174
|
if (!from || !into) {
|
|
161
175
|
return null;
|
|
162
176
|
}
|
|
@@ -184,8 +198,11 @@ export function applyBlockMerge(
|
|
|
184
198
|
mutateUpdateProperty(t, intoPath, "textContent", merged.textContent ?? "");
|
|
185
199
|
}
|
|
186
200
|
mutateRemoveNode(t, fromPath);
|
|
187
|
-
|
|
188
|
-
|
|
201
|
+
/* A container emptied by the removal (the `<ul>` behind a list's last item) would otherwise
|
|
202
|
+
linger as invisible structure that still occupies layout and shows up in the layers panel.
|
|
203
|
+
SAFETY: `fromPath` is not the root (the ancestor check above refuses `[]`), and any node below
|
|
204
|
+
the root is addressed by at least two segments (`"children", <index>`, `"cases", <name>`, or
|
|
205
|
+
`"map"` under its repeater), so parentElementPath returns a path. */
|
|
189
206
|
pruneEmptyAncestors(t, parentElementPath(fromPath) as JxPath);
|
|
190
207
|
if (isTabActive(tab)) {
|
|
191
208
|
t.session.selection = [intoPath];
|
|
@@ -202,12 +219,12 @@ export function applyBlockMerge(
|
|
|
202
219
|
function pruneEmptyAncestors(tab: Tab, path: JxPath): void {
|
|
203
220
|
let cur = path;
|
|
204
221
|
while (cur.length > 0) {
|
|
205
|
-
const node = getNodeAtPath(tab.doc.document, cur)
|
|
222
|
+
const node = getNodeAtPath(tab.doc.document, cur);
|
|
206
223
|
const kids = node?.children;
|
|
207
224
|
if (!node || !Array.isArray(kids) || kids.length > 0) {
|
|
208
225
|
return;
|
|
209
226
|
}
|
|
210
|
-
const parent = parentElementPath(cur)
|
|
227
|
+
const parent = parentElementPath(cur);
|
|
211
228
|
mutateRemoveNode(tab, cur);
|
|
212
229
|
if (!parent) {
|
|
213
230
|
return;
|
|
@@ -227,8 +244,7 @@ export function applyInlineSplit(
|
|
|
227
244
|
before: JxContentResult,
|
|
228
245
|
after: JxContentResult,
|
|
229
246
|
): JxPath {
|
|
230
|
-
const parentPath =
|
|
231
|
-
const idx = childIndex(path) as number;
|
|
247
|
+
const { parentPath, index: idx } = blockSlot(path);
|
|
232
248
|
const newPath = [...parentPath, "children", idx + 1];
|
|
233
249
|
if (!tab) {
|
|
234
250
|
return newPath;
|
|
@@ -291,8 +307,7 @@ export function applyInlineInsert(
|
|
|
291
307
|
return path;
|
|
292
308
|
}
|
|
293
309
|
|
|
294
|
-
const parentPath =
|
|
295
|
-
const idx = childIndex(path) as number;
|
|
310
|
+
const { parentPath, index: idx } = blockSlot(path);
|
|
296
311
|
const newPath = [...parentPath, "children", idx + 1];
|
|
297
312
|
if (!tab) {
|
|
298
313
|
return newPath;
|
|
@@ -336,8 +351,8 @@ export function applyRangeReplace(
|
|
|
336
351
|
if (!tab) {
|
|
337
352
|
return null;
|
|
338
353
|
}
|
|
339
|
-
const head = getNodeAtPath(tab.doc.document, from.path)
|
|
340
|
-
const tail = getNodeAtPath(tab.doc.document, to.path)
|
|
354
|
+
const head = getNodeAtPath(tab.doc.document, from.path);
|
|
355
|
+
const tail = getNodeAtPath(tab.doc.document, to.path);
|
|
341
356
|
if (!head || !tail) {
|
|
342
357
|
return null;
|
|
343
358
|
}
|
|
@@ -366,6 +381,9 @@ export function applyRangeReplace(
|
|
|
366
381
|
for (const path of removals) {
|
|
367
382
|
if (getNodeAtPath(t.doc.document, path)) {
|
|
368
383
|
mutateRemoveNode(t, path);
|
|
384
|
+
/* SAFETY: every removal is the range's tail or a rendered block the iframe named between its
|
|
385
|
+
ends; none is the root, which contains both ends, and any node below the root is
|
|
386
|
+
addressed by at least two segments, so parentElementPath returns a path. */
|
|
369
387
|
pruneEmptyAncestors(t, parentElementPath(path) as JxPath);
|
|
370
388
|
}
|
|
371
389
|
}
|
|
@@ -389,7 +407,7 @@ function comparePathsDescending(a: JxPath, b: JxPath): number {
|
|
|
389
407
|
if (av === bv) {
|
|
390
408
|
continue;
|
|
391
409
|
}
|
|
392
|
-
if (
|
|
410
|
+
if (isNumber(av) && isNumber(bv)) {
|
|
393
411
|
return bv - av;
|
|
394
412
|
}
|
|
395
413
|
return String(bv).localeCompare(String(av));
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
* text formatting, Enter for new paragraphs, and slash commands for inserting elements.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import
|
|
11
|
-
import { displayTagName } from "@jxsuite/schema/guards";
|
|
10
|
+
import { displayTagName, isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
12
11
|
import { normalizeInlineContent } from "./inline-format";
|
|
13
|
-
import {
|
|
12
|
+
import { execEditingCommand } from "./inline-link";
|
|
13
|
+
import { ELEMENT_DEFS, isEditableTag } from "./editable-tags";
|
|
14
14
|
import type { EditableVerdicts } from "./editable-tags";
|
|
15
15
|
import type { JxPath } from "../state";
|
|
16
|
-
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
16
|
+
import type { JsonPrimitive, JxMutableNode } from "@jxsuite/schema/types";
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* The slash-menu surface inline editing drives. Injected (rather than imported) so this module
|
|
@@ -21,12 +21,15 @@ import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
|
21
21
|
* real menu, the canvas iframe supplies its own (or a no-op) without bloating the slim iframe
|
|
22
22
|
* bundle.
|
|
23
23
|
*/
|
|
24
|
+
/** What a slash menu is opened with: the pick handler, and how the list is filtered and sourced. */
|
|
25
|
+
export interface SlashMenuOptions {
|
|
26
|
+
onSelect: (cmd: SlashCommand) => void;
|
|
27
|
+
showFilter?: boolean;
|
|
28
|
+
commands?: SlashCommand[];
|
|
29
|
+
}
|
|
30
|
+
|
|
24
31
|
export interface SlashController {
|
|
25
|
-
show: (
|
|
26
|
-
anchorEl: HTMLElement,
|
|
27
|
-
filter: string,
|
|
28
|
-
cbs: { onSelect: (cmd: SlashCommand) => void; showFilter?: boolean; commands?: SlashCommand[] },
|
|
29
|
-
) => void;
|
|
32
|
+
show: (anchorEl: HTMLElement, filter: string, cbs: SlashMenuOptions) => void;
|
|
30
33
|
dismiss: () => void;
|
|
31
34
|
isOpen: () => boolean;
|
|
32
35
|
}
|
|
@@ -74,11 +77,6 @@ export interface InlineAction {
|
|
|
74
77
|
shortcut?: string;
|
|
75
78
|
}
|
|
76
79
|
|
|
77
|
-
interface ElementDef {
|
|
78
|
-
$inlineChildren?: string[];
|
|
79
|
-
$inlineActions?: InlineAction[] | string;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
80
|
export interface SlashCommand {
|
|
83
81
|
label: string;
|
|
84
82
|
tag: string;
|
|
@@ -124,7 +122,7 @@ export function isInlineInContext(childTag: string, parentTag: string) {
|
|
|
124
122
|
if (!parentTag) {
|
|
125
123
|
return INLINE_TAGS.has(childTag);
|
|
126
124
|
}
|
|
127
|
-
const parentDef =
|
|
125
|
+
const parentDef = ELEMENT_DEFS[parentTag];
|
|
128
126
|
if (!parentDef || !parentDef.$inlineChildren) {
|
|
129
127
|
return false;
|
|
130
128
|
}
|
|
@@ -139,13 +137,13 @@ export function isInlineInContext(childTag: string, parentTag: string) {
|
|
|
139
137
|
* @returns {InlineAction[] | null}
|
|
140
138
|
*/
|
|
141
139
|
export function getInlineActions(tag: string) {
|
|
142
|
-
const def =
|
|
140
|
+
const def = ELEMENT_DEFS[tag];
|
|
143
141
|
if (!def) {
|
|
144
142
|
return null;
|
|
145
143
|
}
|
|
146
144
|
let actions = def.$inlineActions;
|
|
147
|
-
if (
|
|
148
|
-
const refDef =
|
|
145
|
+
if (isString(actions)) {
|
|
146
|
+
const refDef = ELEMENT_DEFS[actions];
|
|
149
147
|
actions = refDef?.$inlineActions ?? undefined;
|
|
150
148
|
}
|
|
151
149
|
if (!Array.isArray(actions)) {
|
|
@@ -233,12 +231,13 @@ export function isEditableBlock(el: HTMLElement) {
|
|
|
233
231
|
* Check if a node is an inline child. When parentNode is provided, uses context-aware scoping from
|
|
234
232
|
* metadata. Without parent, uses the fallback INLINE_TAGS set.
|
|
235
233
|
*
|
|
236
|
-
* @param {JxMutableNode} node
|
|
234
|
+
* @param {JxMutableNode | JsonPrimitive} node A document child entry; a text or other scalar child
|
|
235
|
+
* is never an inline element.
|
|
237
236
|
* @param {JxMutableNode} [parentNode]
|
|
238
237
|
* @returns {boolean}
|
|
239
238
|
*/
|
|
240
|
-
export function isInlineElement(node: JxMutableNode, parentNode?: JxMutableNode) {
|
|
241
|
-
if (!node
|
|
239
|
+
export function isInlineElement(node: JxMutableNode | JsonPrimitive, parentNode?: JxMutableNode) {
|
|
240
|
+
if (!isNonNullObject(node)) {
|
|
242
241
|
return false;
|
|
243
242
|
}
|
|
244
243
|
const childTag = (displayTagName(node.tagName) || "div").toLowerCase();
|
|
@@ -304,7 +303,7 @@ export function startEditing(
|
|
|
304
303
|
insertFn = callbacks.onInsert;
|
|
305
304
|
endFn = callbacks.onEnd;
|
|
306
305
|
_plainMode = opts?.plainText === true;
|
|
307
|
-
_plainOriginal = _plainMode ?
|
|
306
|
+
_plainOriginal = _plainMode ? el.textContent : "";
|
|
308
307
|
_plainPosted = false;
|
|
309
308
|
|
|
310
309
|
// Mark the caret's block so the empty-block slash hint can target it. The editing host itself is
|
|
@@ -495,7 +494,7 @@ function handlePaste(e: ClipboardEvent) {
|
|
|
495
494
|
e.preventDefault();
|
|
496
495
|
// Paste as plain text to avoid foreign HTML
|
|
497
496
|
const text = e.clipboardData?.getData("text/plain") ?? "";
|
|
498
|
-
|
|
497
|
+
execEditingCommand("insertText", text);
|
|
499
498
|
}
|
|
500
499
|
|
|
501
500
|
// ─── Enter: split the active block ─────────────────────────────────────────
|
|
@@ -594,7 +593,7 @@ function commitChanges(inPlace: boolean) {
|
|
|
594
593
|
if (_plainMode) {
|
|
595
594
|
// A prop value is a plain single-line string (a directive attribute) — flatten any newline
|
|
596
595
|
// That survived plaintext editing and skip the rich DOM→Jx serialization entirely.
|
|
597
|
-
const text =
|
|
596
|
+
const text = activeEl.textContent.replaceAll("\n", " ");
|
|
598
597
|
/*
|
|
599
598
|
* A SESSION THAT CHANGED NOTHING MUST WRITE NOTHING.
|
|
600
599
|
*
|
|
@@ -635,17 +634,18 @@ export function normalizeChildren(node: { children?: (JxMutableNode | string)[]
|
|
|
635
634
|
}
|
|
636
635
|
|
|
637
636
|
// Step 1: Merge adjacent text nodes
|
|
638
|
-
const merged = [];
|
|
637
|
+
const merged: (JxMutableNode | string)[] = [];
|
|
639
638
|
for (const child of node.children) {
|
|
640
|
-
|
|
641
|
-
|
|
639
|
+
const last = merged.at(-1);
|
|
640
|
+
if (isString(child) && isString(last)) {
|
|
641
|
+
merged[merged.length - 1] = last + child;
|
|
642
642
|
} else {
|
|
643
643
|
merged.push(child);
|
|
644
644
|
}
|
|
645
645
|
}
|
|
646
646
|
|
|
647
647
|
// Step 2: If all children are text, fold into textContent
|
|
648
|
-
if (merged.every((c
|
|
648
|
+
if (merged.every((c) => isString(c))) {
|
|
649
649
|
return { textContent: merged.join("") };
|
|
650
650
|
}
|
|
651
651
|
|
|
@@ -674,7 +674,7 @@ function elementToJx(el: HTMLElement): JxContentResult {
|
|
|
674
674
|
const children: (JxMutableNode | string)[] = [];
|
|
675
675
|
for (const child of nodes) {
|
|
676
676
|
const jsx = domNodeToJx(child);
|
|
677
|
-
if (jsx !== null
|
|
677
|
+
if (jsx !== null) {
|
|
678
678
|
children.push(jsx);
|
|
679
679
|
}
|
|
680
680
|
}
|
|
@@ -683,6 +683,23 @@ function elementToJx(el: HTMLElement): JxContentResult {
|
|
|
683
683
|
return normalizeChildren({ children });
|
|
684
684
|
}
|
|
685
685
|
|
|
686
|
+
/**
|
|
687
|
+
* Whether `node` is an element carrying `dataset` — an HTML, SVG or MathML element, which is every
|
|
688
|
+
* element an HTML editing host can hold. Decided by node type and feature, not `instanceof`, so it
|
|
689
|
+
* holds for a node of any realm.
|
|
690
|
+
*/
|
|
691
|
+
function isDatasetElementNode(node: Node): node is Element & HTMLOrSVGElement {
|
|
692
|
+
return node.nodeType === Node.ELEMENT_NODE && "dataset" in node;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/** Browser execCommand output tags, mapped to the tags Jx documents use for the same formatting. */
|
|
696
|
+
const BROWSER_TAG_CONVENTIONS = new Map([
|
|
697
|
+
["b", "strong"],
|
|
698
|
+
["i", "em"],
|
|
699
|
+
["s", "del"],
|
|
700
|
+
["strike", "del"],
|
|
701
|
+
]);
|
|
702
|
+
|
|
686
703
|
/**
|
|
687
704
|
* Convert a DOM node to a Jx element definition.
|
|
688
705
|
*
|
|
@@ -698,23 +715,17 @@ function domNodeToJx(node: Node) {
|
|
|
698
715
|
return text; // Bare string — text node child
|
|
699
716
|
}
|
|
700
717
|
|
|
701
|
-
if (node
|
|
718
|
+
if (!isDatasetElementNode(node)) {
|
|
702
719
|
return null;
|
|
703
720
|
}
|
|
704
721
|
|
|
705
|
-
const el = node
|
|
722
|
+
const el = node;
|
|
706
723
|
const tag = el.tagName.toLowerCase();
|
|
707
724
|
const result: JxMutableNode = { tagName: tag };
|
|
708
725
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
i: "em",
|
|
713
|
-
s: "del",
|
|
714
|
-
strike: "del",
|
|
715
|
-
};
|
|
716
|
-
if (tagMap[tag]) {
|
|
717
|
-
result.tagName = tagMap[tag];
|
|
726
|
+
const conventional = BROWSER_TAG_CONVENTIONS.get(tag);
|
|
727
|
+
if (conventional) {
|
|
728
|
+
result.tagName = conventional;
|
|
718
729
|
}
|
|
719
730
|
|
|
720
731
|
// Attributes
|
|
@@ -725,8 +736,9 @@ function domNodeToJx(node: Node) {
|
|
|
725
736
|
const href = el.dataset.jxHref ?? el.getAttribute("href");
|
|
726
737
|
if (tag === "a" && href != null) {
|
|
727
738
|
result.attributes = { href };
|
|
728
|
-
|
|
729
|
-
|
|
739
|
+
// `title` is an HTMLElement property: an HTML `<a>` reflects the attribute, an SVG `<a>` has none.
|
|
740
|
+
if ("title" in el && isString(el.title) && el.title) {
|
|
741
|
+
result.attributes.title = el.title;
|
|
730
742
|
}
|
|
731
743
|
}
|
|
732
744
|
if (tag === "code") {
|
|
@@ -776,13 +788,15 @@ function fragmentToJx(frag: DocumentFragment) {
|
|
|
776
788
|
}
|
|
777
789
|
}
|
|
778
790
|
|
|
791
|
+
const [only] = children;
|
|
779
792
|
if (
|
|
780
793
|
children.length === 1 &&
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
794
|
+
only !== undefined &&
|
|
795
|
+
!isString(only) &&
|
|
796
|
+
only.tagName === "span" &&
|
|
797
|
+
isString(only.textContent)
|
|
784
798
|
) {
|
|
785
|
-
return { textContent:
|
|
799
|
+
return { textContent: only.textContent };
|
|
786
800
|
}
|
|
787
801
|
|
|
788
802
|
return children.length > 0 ? { children } : { textContent: "" };
|
|
@@ -855,10 +869,11 @@ export function openSlashMenu(opts?: { anchored?: boolean }): void {
|
|
|
855
869
|
|
|
856
870
|
// An unanchored menu carries its own filter field: there is no "/…" run in the document for the
|
|
857
871
|
// Author to type into, so without one the list could only ever be filtered by scrolling it.
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
}
|
|
872
|
+
const menu: SlashMenuOptions = { onSelect: handleSlashSelect };
|
|
873
|
+
if (!_slashAnchored) {
|
|
874
|
+
menu.showFilter = true;
|
|
875
|
+
}
|
|
876
|
+
slash.show(activeEl, "", menu);
|
|
862
877
|
}
|
|
863
878
|
|
|
864
879
|
/**
|
|
@@ -935,6 +950,7 @@ function handleSlashSelect(cmd: SlashCommand) {
|
|
|
935
950
|
let slashNode: Text | null = null;
|
|
936
951
|
let slashOffset = 0;
|
|
937
952
|
while (walker.nextNode()) {
|
|
953
|
+
// SAFETY: the walker shows only text nodes (SHOW_TEXT), and nextNode() just landed on one.
|
|
938
954
|
const node = walker.currentNode as Text;
|
|
939
955
|
if (charCount + node.length > slashIdx) {
|
|
940
956
|
slashNode = node;
|