@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
package/src/editor/shortcuts.ts
CHANGED
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
* to the code that runs, so a chord and its behaviour cannot drift apart again.
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
|
+
import { isFunction, isNonNullObject } from "@jxsuite/schema/guards";
|
|
33
34
|
import { childIndex, childList, getNodeAtPath, parentElementPath, projectState } from "../store";
|
|
34
35
|
import { activeTab, workspace } from "../workspace/workspace";
|
|
35
36
|
import {
|
|
@@ -45,8 +46,8 @@ import {
|
|
|
45
46
|
mutateDuplicateNodes,
|
|
46
47
|
mutateInsertNode,
|
|
47
48
|
mutateRemoveNodes,
|
|
48
|
-
redo
|
|
49
|
-
undo
|
|
49
|
+
redo,
|
|
50
|
+
undo,
|
|
50
51
|
transactDoc,
|
|
51
52
|
} from "../tabs/transact";
|
|
52
53
|
import {
|
|
@@ -81,6 +82,7 @@ import { runReported } from "../commands/run-reported";
|
|
|
81
82
|
import { pointerAnchor } from "../canvas/iframe-host";
|
|
82
83
|
import type { PointerAnchor } from "../canvas/iframe-host";
|
|
83
84
|
import type { CommandContext } from "../commands/context";
|
|
85
|
+
import type { CommandArgValues } from "../commands/command-args";
|
|
84
86
|
import type { DockId as CommandDockId } from "../commands/defaults";
|
|
85
87
|
import type { AnyCommand, CommandRegistry } from "../commands/registry";
|
|
86
88
|
import type { DockId, FocusRegion } from "../shell";
|
|
@@ -165,11 +167,14 @@ function navigateSelection(direction: -1 | 1): void {
|
|
|
165
167
|
tab.session.selection = [[]];
|
|
166
168
|
return;
|
|
167
169
|
}
|
|
168
|
-
|
|
170
|
+
// `parentElementPath` is null exactly when the path is the document element (length < 2).
|
|
171
|
+
const parentPath = parentElementPath(selected);
|
|
172
|
+
if (!parentPath) {
|
|
169
173
|
return;
|
|
170
174
|
}
|
|
171
|
-
const parentPath = parentElementPath(selected) as JxPath;
|
|
172
175
|
const parent = getNodeAtPath(tab.doc.document, parentPath);
|
|
176
|
+
// SAFETY: a selection path of length >= 2 addresses a child as `[..., "children", n]`, so its
|
|
177
|
+
// Last segment is the numeric index `n` (the same invariant `insertSiblingParagraph` relies on).
|
|
173
178
|
const newIndex = (childIndex(selected) as number) + direction;
|
|
174
179
|
if (newIndex >= 0 && newIndex < childList(parent).length) {
|
|
175
180
|
tab.session.selection = [[...parentPath, "children", newIndex]];
|
|
@@ -190,14 +195,10 @@ function selectSiblings(): void {
|
|
|
190
195
|
return;
|
|
191
196
|
}
|
|
192
197
|
const selected = primarySelection(tab.session.selection);
|
|
193
|
-
const parentPath = (
|
|
194
|
-
selected && selected.length >= 2 ? parentElementPath(selected) : []
|
|
195
|
-
) as JxPath;
|
|
198
|
+
const parentPath: JxPath = (selected ? parentElementPath(selected) : null) ?? [];
|
|
196
199
|
const parent = getNodeAtPath(tab.doc.document, parentPath);
|
|
197
200
|
const paths = childList(parent).flatMap((child, index) =>
|
|
198
|
-
|
|
199
|
-
? [[...parentPath, "children", index] as JxPath]
|
|
200
|
-
: [],
|
|
201
|
+
isNonNullObject(child) ? [[...parentPath, "children", index]] : [],
|
|
201
202
|
);
|
|
202
203
|
if (paths.length > 0) {
|
|
203
204
|
tab.session.selection = paths;
|
|
@@ -242,10 +243,16 @@ function selectParent(): void {
|
|
|
242
243
|
function insertSiblingParagraph(): void {
|
|
243
244
|
const tab = activeTab.value;
|
|
244
245
|
const selected = primarySelection(tab?.session.selection);
|
|
245
|
-
if (!tab || !selected
|
|
246
|
+
if (!tab || !selected) {
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
// Null exactly when the selection is the document element, which has no sibling slot.
|
|
250
|
+
const parentPath = parentElementPath(selected);
|
|
251
|
+
if (!parentPath) {
|
|
246
252
|
return;
|
|
247
253
|
}
|
|
248
|
-
|
|
254
|
+
// SAFETY: a selection path of length >= 2 addresses a child as `[..., "children", n]`, so its
|
|
255
|
+
// Last segment is the numeric child index `n`.
|
|
249
256
|
const index = childIndex(selected) as number;
|
|
250
257
|
const newPath = [...parentPath, "children", index + 1];
|
|
251
258
|
transactDoc(tab, (t) => {
|
|
@@ -303,14 +310,14 @@ function closeDocument(): void {
|
|
|
303
310
|
function undoDocument(): void {
|
|
304
311
|
const tab = activeTab.value;
|
|
305
312
|
if (tab) {
|
|
306
|
-
|
|
313
|
+
undo(tab);
|
|
307
314
|
}
|
|
308
315
|
}
|
|
309
316
|
|
|
310
317
|
function redoDocument(): void {
|
|
311
318
|
const tab = activeTab.value;
|
|
312
319
|
if (tab) {
|
|
313
|
-
|
|
320
|
+
redo(tab);
|
|
314
321
|
}
|
|
315
322
|
}
|
|
316
323
|
|
|
@@ -349,7 +356,7 @@ function zoomBy(ctx: CommandContext, factor: number, redraw: () => void): void {
|
|
|
349
356
|
return;
|
|
350
357
|
}
|
|
351
358
|
if (isContentZoom(ctx)) {
|
|
352
|
-
setEditZoom(
|
|
359
|
+
setEditZoom(tab.session.ui.editZoom * factor);
|
|
353
360
|
return;
|
|
354
361
|
}
|
|
355
362
|
// Around the stage's middle, like the zoom pod's buttons.
|
|
@@ -397,7 +404,7 @@ function toggleShellDock(registry: CommandRegistry, dock: CommandDockId): void {
|
|
|
397
404
|
* a missing id must be inert rather than an exception thrown out of a keydown handler. A present
|
|
398
405
|
* one that refuses its arguments is not inert: `commands/run-reported.ts` files it in Problems.
|
|
399
406
|
*/
|
|
400
|
-
function runIfPresent(registry: CommandRegistry, id: string, args:
|
|
407
|
+
function runIfPresent(registry: CommandRegistry, id: string, args: CommandArgValues): void {
|
|
401
408
|
if (registry.get(id) && registry.isEnabled(id)) {
|
|
402
409
|
void runReported(registry, id, args, "Keyboard");
|
|
403
410
|
}
|
|
@@ -647,8 +654,9 @@ function askWhereToOpen(openName: string): Promise<ProjectOpenTarget | "cancel">
|
|
|
647
654
|
export async function openProjectFlow(hooks: StudioCommandHooks): Promise<void> {
|
|
648
655
|
const platform = hasPlatform() ? getPlatform() : null;
|
|
649
656
|
const canOpenElsewhere =
|
|
650
|
-
|
|
651
|
-
|
|
657
|
+
platform !== null &&
|
|
658
|
+
isFunction(platform.openProjectInNewWindow) &&
|
|
659
|
+
isFunction(platform.pickProject);
|
|
652
660
|
if (!projectState || !canOpenElsewhere) {
|
|
653
661
|
await hooks.openProject("thisWindow");
|
|
654
662
|
return;
|
|
@@ -959,7 +967,11 @@ export function initShortcuts(registry: CommandRegistry, stageContext: StageCont
|
|
|
959
967
|
document.addEventListener(
|
|
960
968
|
"wheel",
|
|
961
969
|
(e: WheelEvent) => {
|
|
962
|
-
|
|
970
|
+
const { target } = e;
|
|
971
|
+
if (
|
|
972
|
+
(e.ctrlKey || e.metaKey) &&
|
|
973
|
+
!(target instanceof Element && target.closest(STAGE_SELECTOR))
|
|
974
|
+
) {
|
|
963
975
|
e.preventDefault();
|
|
964
976
|
}
|
|
965
977
|
},
|
|
@@ -1022,7 +1034,7 @@ function wheelBelongsInside(
|
|
|
1022
1034
|
): boolean {
|
|
1023
1035
|
const { target } = e;
|
|
1024
1036
|
let el: Element | null =
|
|
1025
|
-
target instanceof Element ? target :
|
|
1037
|
+
target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
|
|
1026
1038
|
while (el && el !== stage) {
|
|
1027
1039
|
if (el instanceof HTMLElement && el !== pageScroller && canScrollBy(el, e.deltaX, e.deltaY)) {
|
|
1028
1040
|
return true;
|
package/src/editor/slash-menu.ts
CHANGED
|
@@ -29,12 +29,7 @@
|
|
|
29
29
|
import { openSlashMenuSurface } from "../surfaces/slash-menu";
|
|
30
30
|
import { rectOf } from "../utils/geometry";
|
|
31
31
|
import type { SlashMenuRow, SlashMenuSurface, SlashMenuView } from "../surfaces/slash-menu";
|
|
32
|
-
|
|
33
|
-
interface SlashCommand {
|
|
34
|
-
label: string;
|
|
35
|
-
tag: string;
|
|
36
|
-
description: string;
|
|
37
|
-
}
|
|
32
|
+
import type { SlashCommand } from "./inline-edit";
|
|
38
33
|
|
|
39
34
|
// ─── Commands ─────────────────────────────────────────────────────────────────
|
|
40
35
|
|
|
@@ -30,13 +30,14 @@
|
|
|
30
30
|
* paths only — a `.json` or `.md` file is never loaded by URL from the canvas, and leaving them out
|
|
31
31
|
* keeps that message as small as the media set.
|
|
32
32
|
*
|
|
33
|
-
* Pure module state — it imports nothing but path normalization
|
|
34
|
-
* the canvas host can import it without dragging in the file layer.
|
|
33
|
+
* Pure module state — it imports nothing but path normalization, the primitive guards and the
|
|
34
|
+
* reactivity re-export — so the canvas host can import it without dragging in the file layer.
|
|
35
35
|
*
|
|
36
36
|
* @docs extending/embedding/platform-adapter
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
39
|
import { normalizeProjectPath } from "@jxsuite/schema/asset-paths";
|
|
40
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
40
41
|
import { shallowRef } from "../reactivity";
|
|
41
42
|
import type { DirEntry } from "../types";
|
|
42
43
|
|
|
@@ -161,8 +162,7 @@ export function noteListing(entries: readonly DirEntry[], since: number): void {
|
|
|
161
162
|
if (path === "" || dirtiedSince(path, since)) {
|
|
162
163
|
continue;
|
|
163
164
|
}
|
|
164
|
-
const version =
|
|
165
|
-
typeof entry.version === "string" && entry.version !== "" ? entry.version : null;
|
|
165
|
+
const version = isString(entry.version) && entry.version !== "" ? entry.version : null;
|
|
166
166
|
const held = versions.get(path);
|
|
167
167
|
if (version === null) {
|
|
168
168
|
if (held === undefined) {
|
package/src/files/components.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { getPlatform } from "../platform";
|
|
|
4
4
|
import { projectState } from "../store";
|
|
5
5
|
import type { ComponentMeta } from "../types";
|
|
6
6
|
import { componentMetaFrom } from "@jxsuite/schema/component-meta";
|
|
7
|
-
import
|
|
7
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
8
|
+
import type { JsonValue, JxMutableNode } from "@jxsuite/schema/types";
|
|
8
9
|
|
|
9
10
|
/** A discovered component: project components carry a file path; package components may not. */
|
|
10
11
|
export interface ComponentEntry extends Omit<ComponentMeta, "path"> {
|
|
@@ -40,15 +41,17 @@ export async function loadComponentRegistry() {
|
|
|
40
41
|
*
|
|
41
42
|
* @param {string | null} path - The saved document's project-relative path; `null` for an unsaved
|
|
42
43
|
* draft, which no scan would have seen either.
|
|
43
|
-
* @param {
|
|
44
|
+
* @param {JxMutableNode} doc - The saved document.
|
|
44
45
|
* @returns {boolean} Whether the registry changed, so a caller knows to repaint what reads it.
|
|
45
46
|
*/
|
|
46
|
-
export function noteComponentSaved(path: string | null, doc:
|
|
47
|
+
export function noteComponentSaved(path: string | null, doc: JxMutableNode): boolean {
|
|
47
48
|
if (!path) {
|
|
48
49
|
return false;
|
|
49
50
|
}
|
|
50
51
|
const index = componentRegistry.findIndex((c) => c.path === path);
|
|
51
|
-
|
|
52
|
+
/* SAFETY: a saved tab's document was parsed from JSON and has just been written back as JSON
|
|
53
|
+
(`serializeDocument`), so every value it holds is a JSON value — the model the extractor reads. */
|
|
54
|
+
const meta = componentMetaFrom(doc as JsonValue, path);
|
|
52
55
|
if (!meta) {
|
|
53
56
|
if (index === -1) {
|
|
54
57
|
return false;
|
|
@@ -56,6 +59,8 @@ export function noteComponentSaved(path: string | null, doc: unknown): boolean {
|
|
|
56
59
|
componentRegistry.splice(index, 1);
|
|
57
60
|
return true;
|
|
58
61
|
}
|
|
62
|
+
/* SAFETY: `componentMetaFrom` is the extractor every backend's `discoverComponents` scan runs to
|
|
63
|
+
Produce the registry's entries, so its output has the shape the registry already holds. */
|
|
59
64
|
const entry = meta as ComponentEntry;
|
|
60
65
|
if (index === -1) {
|
|
61
66
|
componentRegistry.push(entry);
|
|
@@ -84,7 +89,7 @@ export function buildComponentInstance(comp: ComponentEntry): JxMutableNode {
|
|
|
84
89
|
for (const child of structuredClone(slot.fallback ?? [])) {
|
|
85
90
|
if (!slot.name) {
|
|
86
91
|
children.push(child);
|
|
87
|
-
} else if (
|
|
92
|
+
} else if (isNonNullObject(child) && isString(child.tagName)) {
|
|
88
93
|
// Preserve an author-set slot attribute (slot forwarding inside fallback).
|
|
89
94
|
child.attributes = { slot: slot.name, ...child.attributes };
|
|
90
95
|
children.push(child);
|
|
@@ -94,11 +99,11 @@ export function buildComponentInstance(comp: ComponentEntry): JxMutableNode {
|
|
|
94
99
|
}
|
|
95
100
|
}
|
|
96
101
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
+
const instance: JxMutableNode = { $props, tagName: comp.tagName };
|
|
103
|
+
if (children.length > 0) {
|
|
104
|
+
instance.children = children;
|
|
105
|
+
}
|
|
106
|
+
return instance;
|
|
102
107
|
}
|
|
103
108
|
|
|
104
109
|
/**
|
package/src/files/elements.ts
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* they must not differ on is WHICH entries the list should hold.
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
23
24
|
import { computeRelativePath } from "./components";
|
|
24
25
|
import type { ComponentEntry } from "./components";
|
|
25
26
|
import type { JxElement } from "@jxsuite/schema/types";
|
|
@@ -29,9 +30,7 @@ export type ElementsEntry = string | JxElement | { $ref: string };
|
|
|
29
30
|
|
|
30
31
|
/** The `$ref` of an entry, when it has one. */
|
|
31
32
|
function refOf(entry: ElementsEntry): string | null {
|
|
32
|
-
return
|
|
33
|
-
? entry.$ref
|
|
34
|
-
: null;
|
|
33
|
+
return isNonNullObject(entry) && isString(entry.$ref) ? entry.$ref : null;
|
|
35
34
|
}
|
|
36
35
|
|
|
37
36
|
/**
|
|
@@ -81,7 +80,7 @@ export function hasElement(
|
|
|
81
80
|
const specifier = npmSpecifier(comp);
|
|
82
81
|
if (specifier) {
|
|
83
82
|
return elements.some(
|
|
84
|
-
(entry) =>
|
|
83
|
+
(entry) => isString(entry) && (entry === specifier || entry === comp.package),
|
|
85
84
|
);
|
|
86
85
|
}
|
|
87
86
|
if (!comp.path) {
|
|
@@ -132,7 +131,7 @@ export function disableElement(
|
|
|
132
131
|
if (specifier) {
|
|
133
132
|
// Both spellings: a component ticked off must not stay imported through the package entry.
|
|
134
133
|
return elements.filter(
|
|
135
|
-
(entry) => !(
|
|
134
|
+
(entry) => !(isString(entry) && (entry === specifier || entry === comp.package)),
|
|
136
135
|
);
|
|
137
136
|
}
|
|
138
137
|
if (!comp.path) {
|
|
@@ -151,7 +150,7 @@ export function removePackageElements(
|
|
|
151
150
|
pkg: string,
|
|
152
151
|
): ElementsEntry[] {
|
|
153
152
|
return elements.filter(
|
|
154
|
-
(entry) =>
|
|
153
|
+
(entry) => !isString(entry) || !(entry === pkg || entry.startsWith(`${pkg}/`)),
|
|
155
154
|
);
|
|
156
155
|
}
|
|
157
156
|
|
package/src/files/file-ops.ts
CHANGED
|
@@ -28,6 +28,8 @@ import { showConfirmDialog } from "../ui/layers";
|
|
|
28
28
|
import { locateDocument } from "../services/code-services";
|
|
29
29
|
import { errorMessage } from "@jxsuite/schema/parse";
|
|
30
30
|
import { notify } from "../services/notify";
|
|
31
|
+
import type { NotifyOptions } from "../services/notify";
|
|
32
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
31
33
|
import { validateComponentSlots } from "../services/cem-export";
|
|
32
34
|
import { reportPopoverProblems } from "../services/popover-report";
|
|
33
35
|
import { getPlatform } from "../platform";
|
|
@@ -103,19 +105,66 @@ export async function parseSourceForPath(path: string, source: string) {
|
|
|
103
105
|
export const parseCollabSource: CollabParser = async (tab, text) => {
|
|
104
106
|
if (tab.documentPath && formatForPath(tab.documentPath)) {
|
|
105
107
|
const parsed = await parseSourceForPath(tab.documentPath, text);
|
|
106
|
-
return { document: parsed.document
|
|
108
|
+
return { document: parsed.document, frontmatter: parsed.frontmatter };
|
|
107
109
|
}
|
|
108
110
|
const parsed = parseJsonDocument(text);
|
|
109
111
|
tab.doc.layout = parsed.layout;
|
|
112
|
+
/* SAFETY: a co-edited path no format class claims is a `.json` Jx document (every other path
|
|
113
|
+
`ensureCollab` attaches to is a format file, handled above), and that file's schema makes its
|
|
114
|
+
Top-level object a node — the object `parseJsonDocument` already states it returns. */
|
|
110
115
|
return { document: parsed.document as JxMutableNode };
|
|
111
116
|
};
|
|
112
117
|
|
|
118
|
+
/** One `accept` group of a File System Access picker: media type → extensions, with a label. */
|
|
119
|
+
interface FilePickerAcceptType {
|
|
120
|
+
accept: Record<string, string[]>;
|
|
121
|
+
description: string;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The File System Access pickers (WICG), which TypeScript's DOM lib does not declare. Only what
|
|
126
|
+
* this module passes and reads is spelled out.
|
|
127
|
+
*/
|
|
128
|
+
interface FilePickerWindow {
|
|
129
|
+
showOpenFilePicker: (options: {
|
|
130
|
+
types: FilePickerAcceptType[];
|
|
131
|
+
}) => Promise<FileSystemFileHandle[]>;
|
|
132
|
+
/* Export's single extension is `format.extensions[0]`, absent for a format that declares none —
|
|
133
|
+
So the save picker is typed with the value it is actually handed. */
|
|
134
|
+
showSaveFilePicker: (options: {
|
|
135
|
+
suggestedName?: string | undefined;
|
|
136
|
+
types: { accept: Record<string, (string | undefined)[]>; description: string }[];
|
|
137
|
+
}) => Promise<FileSystemFileHandle>;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Whether this browser offers `showOpenFilePicker` (Chromium does; Firefox and Safari do not). */
|
|
141
|
+
function hasOpenFilePicker(
|
|
142
|
+
win: Window,
|
|
143
|
+
): win is Window & Pick<FilePickerWindow, "showOpenFilePicker"> {
|
|
144
|
+
return "showOpenFilePicker" in win;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** Whether this browser offers `showSaveFilePicker` (Chromium does; Firefox and Safari do not). */
|
|
148
|
+
function hasSaveFilePicker(
|
|
149
|
+
win: Window,
|
|
150
|
+
): win is Window & Pick<FilePickerWindow, "showSaveFilePicker"> {
|
|
151
|
+
return "showSaveFilePicker" in win;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** Attach the tab's file to a notification's options, when it has one. */
|
|
155
|
+
function atTabPath(tab: Tab, options: NotifyOptions): NotifyOptions {
|
|
156
|
+
if (tab.documentPath !== null) {
|
|
157
|
+
options.path = tab.documentPath;
|
|
158
|
+
}
|
|
159
|
+
return options;
|
|
160
|
+
}
|
|
161
|
+
|
|
113
162
|
/** Open a file via the File System Access API (or fallback input). */
|
|
114
163
|
export async function openFile() {
|
|
115
164
|
try {
|
|
116
165
|
await loadFormats();
|
|
117
166
|
const formats = getFormats();
|
|
118
|
-
const pickerTypes = [
|
|
167
|
+
const pickerTypes: FilePickerAcceptType[] = [
|
|
119
168
|
{
|
|
120
169
|
accept: { "application/json": [".json"] },
|
|
121
170
|
description: "Jx Component",
|
|
@@ -160,12 +209,8 @@ export async function openFile() {
|
|
|
160
209
|
// Trail; it does not need a message that erases itself.
|
|
161
210
|
};
|
|
162
211
|
|
|
163
|
-
if (
|
|
164
|
-
const [handle] = await (
|
|
165
|
-
window as unknown as {
|
|
166
|
-
showOpenFilePicker: (options?: unknown) => Promise<FileSystemFileHandle[]>;
|
|
167
|
-
}
|
|
168
|
-
).showOpenFilePicker({ types: pickerTypes });
|
|
212
|
+
if (hasOpenFilePicker(window)) {
|
|
213
|
+
const [handle] = await window.showOpenFilePicker({ types: pickerTypes });
|
|
169
214
|
const file = await handle!.getFile();
|
|
170
215
|
await handleSource(handle!.name, await file.text(), handle!);
|
|
171
216
|
} else {
|
|
@@ -230,16 +275,16 @@ function reportSaved(tab: Tab) {
|
|
|
230
275
|
const doc = tab.doc.document;
|
|
231
276
|
_onDocumentSaved(tab.documentPath, doc);
|
|
232
277
|
const warning =
|
|
233
|
-
|
|
234
|
-
? validateComponentSlots(doc)
|
|
235
|
-
: null;
|
|
278
|
+
isString(doc.tagName) && doc.tagName.includes("-") ? validateComponentSlots(doc) : null;
|
|
236
279
|
if (warning) {
|
|
237
|
-
notify.warn(
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
280
|
+
notify.warn(
|
|
281
|
+
warning,
|
|
282
|
+
atTabPath(tab, {
|
|
283
|
+
key: `slots:${tab.documentPath ?? tab.id}`,
|
|
284
|
+
source: "Components",
|
|
285
|
+
tier: "problem",
|
|
286
|
+
}),
|
|
287
|
+
);
|
|
243
288
|
}
|
|
244
289
|
/* Popover correctness, beside the slot check and for the same reason it is here: a successful
|
|
245
290
|
save is the one chokepoint every edit passes through, whichever surface made it. A render-time
|
|
@@ -311,12 +356,11 @@ export async function saveFile(tab: Tab | null = activeTab.value): Promise<boole
|
|
|
311
356
|
notify.warn(
|
|
312
357
|
`You have read access to this session — changes to ${tab.documentPath ?? "this document"} ` +
|
|
313
358
|
`stay in your browser and cannot be saved.`,
|
|
314
|
-
{
|
|
359
|
+
atTabPath(tab, {
|
|
315
360
|
action: "file.save",
|
|
316
361
|
key: `save.readOnly:${tab.documentPath ?? tab.id}`,
|
|
317
|
-
...(tab.documentPath === null ? {} : { path: tab.documentPath }),
|
|
318
362
|
source: "Collaboration",
|
|
319
|
-
},
|
|
363
|
+
}),
|
|
320
364
|
);
|
|
321
365
|
return false;
|
|
322
366
|
}
|
|
@@ -327,11 +371,10 @@ export async function saveFile(tab: Tab | null = activeTab.value): Promise<boole
|
|
|
327
371
|
if (!hasSerializableDocument(tab)) {
|
|
328
372
|
notify.warn(
|
|
329
373
|
`${tab.documentPath ?? "This file"} is a media file, so there is no document for Save to write.`,
|
|
330
|
-
{
|
|
374
|
+
atTabPath(tab, {
|
|
331
375
|
key: `save.notADocument:${tab.documentPath ?? tab.id}`,
|
|
332
|
-
...(tab.documentPath === null ? {} : { path: tab.documentPath }),
|
|
333
376
|
source: "Save",
|
|
334
|
-
},
|
|
377
|
+
}),
|
|
335
378
|
);
|
|
336
379
|
return false;
|
|
337
380
|
}
|
|
@@ -381,13 +424,15 @@ export async function saveFile(tab: Tab | null = activeTab.value): Promise<boole
|
|
|
381
424
|
notify.warn("This document has no save target — use Export.", { key: "save.noTarget" });
|
|
382
425
|
} catch (error) {
|
|
383
426
|
if (!(error instanceof Error && error.name === "AbortError")) {
|
|
384
|
-
notify.error(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
427
|
+
notify.error(
|
|
428
|
+
`Could not save ${tab.documentPath ?? tab.id}.`,
|
|
429
|
+
atTabPath(tab, {
|
|
430
|
+
action: "file.save",
|
|
431
|
+
detail: errorMessage(error),
|
|
432
|
+
key: `save:${tab.documentPath ?? tab.id}`,
|
|
433
|
+
source: "Save",
|
|
434
|
+
}),
|
|
435
|
+
);
|
|
391
436
|
}
|
|
392
437
|
}
|
|
393
438
|
return false;
|
|
@@ -418,13 +463,9 @@ export async function exportFile() {
|
|
|
418
463
|
const description = format ? format.name : "Jx Component";
|
|
419
464
|
const fallbackName = format ? `content${ext}` : "component.json";
|
|
420
465
|
|
|
421
|
-
if (
|
|
466
|
+
if (hasSaveFilePicker(window)) {
|
|
422
467
|
const suggestedName = tab.documentPath ? tab.documentPath.split("/").pop() : fallbackName;
|
|
423
|
-
const handle = await (
|
|
424
|
-
window as unknown as {
|
|
425
|
-
showSaveFilePicker: (options?: unknown) => Promise<FileSystemFileHandle>;
|
|
426
|
-
}
|
|
427
|
-
).showSaveFilePicker({
|
|
468
|
+
const handle = await window.showSaveFilePicker({
|
|
428
469
|
suggestedName,
|
|
429
470
|
types: [{ accept: { [mimeType]: [ext] }, description }],
|
|
430
471
|
});
|