@jxsuite/studio 6.1.0 → 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-f2gkpy8d.js +4 -0
- 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-gybvv7a6.js → index-zpjmzqfk.js} +3 -3
- package/dist/chunks/{javascript-rnvdp3k4.js → javascript-m54mnwp6.js} +3 -3
- package/dist/chunks/jsonMode-w15cmrcm.js +13 -0
- 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-5g0ag7c0.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-pxg4ap1e.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-qbj760tx.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-anyrgzvb.js → studio-90pq9km1.js} +4 -4
- package/dist/chunks/studio-924p1tm1.js +6 -0
- package/dist/chunks/{studio-v2bvmbjj.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-txjjzrsm.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-0x3jyb8r.js → studio-tq0rtfwj.js} +4 -4
- package/dist/chunks/{studio-cpxkgjrj.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-y64hrt8p.js +12 -0
- 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-sf49ee9x.js +14 -0
- 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 +98 -98
- package/dist/workers/ts.worker.js +3 -3
- package/package.json +11 -11
- 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 +66 -42
- package/src/canvas/canvas-surface.ts +5 -3
- package/src/canvas/canvas-utils.ts +163 -64
- 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 +203 -118
- package/src/canvas/iframe-inline-edit.ts +69 -32
- package/src/canvas/iframe-insert.ts +5 -4
- package/src/canvas/iframe-interaction.ts +37 -26
- 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 +15 -16
- package/src/canvas/iframe-render.ts +41 -36
- 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/defaults.ts +4 -1
- package/src/commands/keymap.ts +47 -43
- package/src/commands/levels.ts +3 -3
- package/src/commands/live-context.ts +10 -8
- 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 +87 -47
- 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 +6 -1
- 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 +55 -22
- 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 +254 -216
- 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 +174 -127
- 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 +39 -77
- 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 +25 -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.json +126 -73
- package/src/surfaces/rail.ts +38 -12
- 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/tabs/typing.ts +31 -0
- 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 +103 -74
- 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 +47 -36
- package/dist/chunks/2020-nkxms0ay.js +0 -4
- package/dist/chunks/adapter-m948ab5f.js +0 -4
- package/dist/chunks/cf-account-picker-n8hr38v7.js +0 -4
- package/dist/chunks/cf-settings-356xdtne.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-yk3t844e.js +0 -4
- package/dist/chunks/content-source-bawmyc09.js +0 -4
- package/dist/chunks/convert-to-repeater-7wns8kf1.js +0 -4
- package/dist/chunks/dialog-mtm9fq5t.js +0 -4
- package/dist/chunks/editor-6sc8nacq.js +0 -4
- package/dist/chunks/entry-commands-8ay9fh81.js +0 -4
- package/dist/chunks/extension-sections-na7rj3nr.js +0 -4
- package/dist/chunks/file-ops-gye0qw56.js +0 -4
- package/dist/chunks/files-dmc2xvcq.js +0 -4
- package/dist/chunks/format-host-t76b53f8.js +0 -4
- package/dist/chunks/fs-events-cg4tpz06.js +0 -4
- package/dist/chunks/git-panel-yef7bshy.js +0 -4
- package/dist/chunks/grid-view-7tt4bxw1.js +0 -51
- package/dist/chunks/icons-qbh8akb1.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-tmz30gfp.js +0 -4
- package/dist/chunks/index-nag78a9h.js +0 -4
- package/dist/chunks/jsonMode-zhwsprqk.js +0 -13
- package/dist/chunks/jx-validate-3gbp5nkn.js +0 -4
- package/dist/chunks/layers-fvz99859.js +0 -4
- package/dist/chunks/layers-panel-gchmbf9p.js +0 -4
- package/dist/chunks/listbox-s8fkmnq8.js +0 -4
- package/dist/chunks/lit-html-9agdspkt.js +0 -4
- package/dist/chunks/media-picker-rhjvyy00.js +0 -4
- package/dist/chunks/menu-2e4y9j7b.js +0 -4
- package/dist/chunks/menu-37d07z9m.js +0 -4
- package/dist/chunks/monaco-binding-2jnhjjvr.js +0 -4
- package/dist/chunks/monaco-buffer-rp21359g.js +0 -4
- package/dist/chunks/monaco-setup-vhh7gayr.js +0 -4
- package/dist/chunks/notify-h3www560.js +0 -4
- package/dist/chunks/number-field-gw7sq8rn.js +0 -4
- package/dist/chunks/parse-897fvqah.js +0 -4
- package/dist/chunks/platform-hz34wcd7.js +0 -4
- package/dist/chunks/popover-8htra4er.js +0 -4
- package/dist/chunks/publish-panel-exsmjzyj.js +0 -4
- package/dist/chunks/quick-search-pgaqeh0m.js +0 -4
- package/dist/chunks/references-2cgdxnb8.js +0 -4
- package/dist/chunks/right-panel-jf856w5w.js +0 -4
- package/dist/chunks/section-registry-jnf8r5gy.js +0 -4
- package/dist/chunks/select-n3v7gwas.js +0 -4
- package/dist/chunks/split-pff8f3ze.js +0 -4
- package/dist/chunks/studio-0f55h9ye.js +0 -5
- package/dist/chunks/studio-0sqdhnew.js +0 -12
- package/dist/chunks/studio-19x1c75w.js +0 -5
- package/dist/chunks/studio-2sqcndak.js +0 -5
- package/dist/chunks/studio-3aey7dd3.js +0 -5
- package/dist/chunks/studio-3bpdkq2s.js +0 -5
- package/dist/chunks/studio-47y6fbpf.js +0 -5
- package/dist/chunks/studio-4m3826v2.js +0 -5
- package/dist/chunks/studio-4nx2dj1g.js +0 -4
- package/dist/chunks/studio-4xv5s47r.js +0 -9
- package/dist/chunks/studio-5g4t8v6w.js +0 -5
- package/dist/chunks/studio-5py436sf.js +0 -5
- package/dist/chunks/studio-77kt594t.js +0 -5
- package/dist/chunks/studio-8f87n763.js +0 -10
- package/dist/chunks/studio-8mb00b84.js +0 -5
- package/dist/chunks/studio-8p51gq2h.js +0 -6
- package/dist/chunks/studio-954ds834.js +0 -5
- package/dist/chunks/studio-9ft45c83.js +0 -9
- package/dist/chunks/studio-a2138x5k.js +0 -7
- package/dist/chunks/studio-a9yzstqj.js +0 -5
- package/dist/chunks/studio-acdksxx6.js +0 -5
- package/dist/chunks/studio-ar8jcf2y.js +0 -5
- package/dist/chunks/studio-bmn4mn9j.js +0 -7
- package/dist/chunks/studio-e7xxa0sj.js +0 -5
- package/dist/chunks/studio-ecaz25vk.js +0 -5
- package/dist/chunks/studio-ery42sqr.js +0 -4
- package/dist/chunks/studio-fzdywr6p.js +0 -9
- package/dist/chunks/studio-g5fmf0c1.js +0 -5
- package/dist/chunks/studio-g7nse7zb.js +0 -5
- package/dist/chunks/studio-geq1ea6k.js +0 -14
- package/dist/chunks/studio-ghkb32r8.js +0 -5
- package/dist/chunks/studio-ghrhy2y7.js +0 -5
- package/dist/chunks/studio-grawhey1.js +0 -5
- package/dist/chunks/studio-h0xgswew.js +0 -5
- package/dist/chunks/studio-h9c4p2tx.js +0 -5
- package/dist/chunks/studio-jyzj5cxs.js +0 -5
- package/dist/chunks/studio-mgx8yhnz.js +0 -64
- package/dist/chunks/studio-mpb04y1d.js +0 -6
- package/dist/chunks/studio-n17mty64.js +0 -5
- package/dist/chunks/studio-nwh2eqsk.js +0 -6
- package/dist/chunks/studio-q1h883bt.js +0 -16
- package/dist/chunks/studio-q4tv82h7.js +0 -9
- package/dist/chunks/studio-qpqa7vk3.js +0 -5
- package/dist/chunks/studio-qqz8e5gk.js +0 -5
- package/dist/chunks/studio-qvasen3f.js +0 -5
- package/dist/chunks/studio-rggdb3hm.js +0 -5
- package/dist/chunks/studio-sghy936h.js +0 -4
- package/dist/chunks/studio-skprc6ef.js +0 -5
- package/dist/chunks/studio-tt2nactf.js +0 -5
- package/dist/chunks/studio-tyasmc39.js +0 -5
- package/dist/chunks/studio-vk9ezads.js +0 -5
- package/dist/chunks/studio-vzacdfsc.js +0 -4
- package/dist/chunks/studio-w4c0xmrw.js +0 -5
- package/dist/chunks/studio-wfjqhhbk.js +0 -5
- package/dist/chunks/studio-wgh5kxpj.js +0 -5
- package/dist/chunks/studio-xasj0796.js +0 -5
- package/dist/chunks/studio-y78s8r2n.js +0 -5
- package/dist/chunks/studio-z8w183sh.js +0 -5
- package/dist/chunks/studio-zscd9ty4.js +0 -928
- package/dist/chunks/studio-zxp13sss.js +0 -7
- package/dist/chunks/studio-zygnmm01.js +0 -5
- package/dist/chunks/swatch-group-8qh9a3bm.js +0 -4
- package/dist/chunks/tabs-jwthg40w.js +0 -4
- package/dist/chunks/textfield-spy3hc77.js +0 -4
- package/dist/chunks/toast-4d35zd64.js +0 -4
- package/dist/chunks/toast-host-8sjmfed3.js +0 -4
- package/dist/chunks/tooltip-fd6g9xy3.js +0 -4
- package/dist/chunks/tree-h19v1jfz.js +0 -4
- package/dist/chunks/tsMode-gr0m4dzr.js +0 -14
- package/dist/chunks/workspace-m15qtcqp.js +0 -4
- package/dist/chunks/ws-client-nf61frr1.js +0 -4
|
@@ -9,8 +9,15 @@
|
|
|
9
9
|
|
|
10
10
|
import { setProjectSchemasForMonaco } from "../services/monaco-lazy";
|
|
11
11
|
import { getPlatform } from "../platform";
|
|
12
|
-
import type {
|
|
13
|
-
|
|
12
|
+
import type {
|
|
13
|
+
ExtensionCatalogEntry,
|
|
14
|
+
ExtensionsInfo,
|
|
15
|
+
FormatActionRequest,
|
|
16
|
+
ProjectSchemasResponse,
|
|
17
|
+
StudioPlatform,
|
|
18
|
+
} from "../types";
|
|
19
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
20
|
+
import type { JxDocumentValue, JxMutableNode } from "@jxsuite/schema/types";
|
|
14
21
|
|
|
15
22
|
export interface StudioFormatHints {
|
|
16
23
|
icon?: string;
|
|
@@ -25,6 +32,10 @@ export interface StudioFormatHints {
|
|
|
25
32
|
inline?: string[];
|
|
26
33
|
void?: string[];
|
|
27
34
|
textOnly?: string[];
|
|
35
|
+
/**
|
|
36
|
+
* Per-parent child rules. The registry arrives over the wire unvalidated, so a rule may be a
|
|
37
|
+
* JSON `null`, which every reader treats as a tag the format leaves undeclared.
|
|
38
|
+
*/
|
|
28
39
|
nesting?: Record<
|
|
29
40
|
string,
|
|
30
41
|
{
|
|
@@ -32,10 +43,9 @@ export interface StudioFormatHints {
|
|
|
32
43
|
inline?: boolean;
|
|
33
44
|
directive?: boolean;
|
|
34
45
|
only?: string[];
|
|
35
|
-
}
|
|
46
|
+
} | null
|
|
36
47
|
>;
|
|
37
48
|
};
|
|
38
|
-
[key: string]: unknown;
|
|
39
49
|
}
|
|
40
50
|
|
|
41
51
|
export interface StudioFormat {
|
|
@@ -57,10 +67,11 @@ export function loadFormats(): Promise<StudioFormat[]> {
|
|
|
57
67
|
if (!_loaded) {
|
|
58
68
|
_loaded = (async () => {
|
|
59
69
|
try {
|
|
60
|
-
const platform = getPlatform()
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
70
|
+
const platform = getPlatform();
|
|
71
|
+
/* SAFETY: every backend's formats route serializes its format registry as the records this
|
|
72
|
+
Module declares (`StudioFormat`); the PAL types the payload `unknown[]` only because this
|
|
73
|
+
Module, not `types.ts`, owns that shape. */
|
|
74
|
+
_formats = ((await platform.listFormats?.()) as StudioFormat[] | undefined) ?? [];
|
|
64
75
|
} catch {
|
|
65
76
|
_formats = [];
|
|
66
77
|
}
|
|
@@ -100,9 +111,7 @@ export function loadExtensions(): Promise<ExtensionsInfo[]> {
|
|
|
100
111
|
if (!_extensionsLoaded) {
|
|
101
112
|
_extensionsLoaded = (async () => {
|
|
102
113
|
try {
|
|
103
|
-
const platform = getPlatform()
|
|
104
|
-
listExtensions?: () => Promise<ExtensionsInfo[]>;
|
|
105
|
-
};
|
|
114
|
+
const platform = getPlatform();
|
|
106
115
|
_extensions = (await platform.listExtensions?.()) ?? [];
|
|
107
116
|
} catch {
|
|
108
117
|
_extensions = [];
|
|
@@ -144,9 +153,7 @@ export function loadExtensionCatalog(): Promise<ExtensionCatalogEntry[]> {
|
|
|
144
153
|
if (!_catalogLoaded) {
|
|
145
154
|
_catalogLoaded = (async () => {
|
|
146
155
|
try {
|
|
147
|
-
const platform = getPlatform()
|
|
148
|
-
listExtensionCatalog?: () => Promise<ExtensionCatalogEntry[]>;
|
|
149
|
-
};
|
|
156
|
+
const platform = getPlatform();
|
|
150
157
|
_catalog = (await platform.listExtensionCatalog?.()) ?? [];
|
|
151
158
|
} catch {
|
|
152
159
|
_catalog = [];
|
|
@@ -180,10 +187,10 @@ export function setExtensionCatalog(catalog: ExtensionCatalogEntry[]) {
|
|
|
180
187
|
* @param {object} platform - The studio platform (only `fetchProjectSchemas` is consulted)
|
|
181
188
|
* @returns {Promise<void>} Resolves once both consumers have been updated
|
|
182
189
|
*/
|
|
183
|
-
async function shareProjectSchemas(
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
let schemas:
|
|
190
|
+
async function shareProjectSchemas(
|
|
191
|
+
platform: Pick<StudioPlatform, "fetchProjectSchemas">,
|
|
192
|
+
): Promise<void> {
|
|
193
|
+
let schemas: ProjectSchemasResponse | null = null;
|
|
187
194
|
try {
|
|
188
195
|
schemas = (await platform.fetchProjectSchemas?.()) ?? null;
|
|
189
196
|
} catch {
|
|
@@ -208,9 +215,7 @@ async function shareProjectSchemas(platform: {
|
|
|
208
215
|
*
|
|
209
216
|
* @param {object} platform - The studio platform (only `fetchProjectSchemas` is consulted here)
|
|
210
217
|
*/
|
|
211
|
-
export function refreshExtensionUi(platform: {
|
|
212
|
-
fetchProjectSchemas?: () => Promise<{ project?: unknown; document?: unknown }>;
|
|
213
|
-
}): void {
|
|
218
|
+
export function refreshExtensionUi(platform: Pick<StudioPlatform, "fetchProjectSchemas">): void {
|
|
214
219
|
void shareProjectSchemas(platform);
|
|
215
220
|
// `installed` and `bundled` are per-project facts, so an install or a project switch can move
|
|
216
221
|
// Them even when the shipped half has not changed.
|
|
@@ -284,10 +289,20 @@ export function defaultContentFormat(): StudioFormat | undefined {
|
|
|
284
289
|
return _formats.find((f) => f.capabilities.serialize && f.documentKinds.includes("content"));
|
|
285
290
|
}
|
|
286
291
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
292
|
+
/** The options a format capability is invoked with. */
|
|
293
|
+
export interface FormatActionOptions {
|
|
294
|
+
/** `"roundtrip"` asks the format to preserve what it can of the source's own spelling. */
|
|
295
|
+
mode?: string;
|
|
296
|
+
/** Whether the serializer writes a frontmatter block. */
|
|
297
|
+
frontmatter?: boolean;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Send one request to the format route (POST /__studio/format, or the desktop RPC of the same
|
|
302
|
+
* name). A serialize request carries the caller's document through unchanged.
|
|
303
|
+
*/
|
|
304
|
+
async function formatAction(payload: FormatActionRequest): Promise<JxMutableNode | string> {
|
|
305
|
+
const platform = getPlatform();
|
|
291
306
|
if (!platform.formatAction) {
|
|
292
307
|
throw new Error("Platform does not support format actions");
|
|
293
308
|
}
|
|
@@ -298,8 +313,11 @@ async function formatAction(payload: Record<string, unknown>): Promise<unknown>
|
|
|
298
313
|
export async function formatParse(
|
|
299
314
|
name: string,
|
|
300
315
|
source: string,
|
|
301
|
-
options?:
|
|
316
|
+
options?: FormatActionOptions,
|
|
302
317
|
): Promise<JxMutableNode> {
|
|
318
|
+
/* SAFETY: a format class's `parse` capability returns the Jx document it built from the source —
|
|
319
|
+
The contract every format class implements (specs/extensions.md) — and nothing here inspects
|
|
320
|
+
It before `splitFormatDocument` reads its keys. */
|
|
303
321
|
return (await formatAction({
|
|
304
322
|
action: "parse",
|
|
305
323
|
format: name,
|
|
@@ -308,12 +326,19 @@ export async function formatParse(
|
|
|
308
326
|
})) as JxMutableNode;
|
|
309
327
|
}
|
|
310
328
|
|
|
311
|
-
/**
|
|
329
|
+
/**
|
|
330
|
+
* Serialize a Jx document to source text via the named format's serialize capability.
|
|
331
|
+
*
|
|
332
|
+
* `doc` is relayed to the format class verbatim: the document merged with its frontmatter, whose
|
|
333
|
+
* open keys are whatever the format's own parser produced.
|
|
334
|
+
*/
|
|
312
335
|
export async function formatSerialize(
|
|
313
336
|
name: string,
|
|
314
|
-
doc:
|
|
315
|
-
options?:
|
|
337
|
+
doc: JxMutableNode,
|
|
338
|
+
options?: FormatActionOptions,
|
|
316
339
|
): Promise<string> {
|
|
340
|
+
/* SAFETY: a format class's `serialize` capability returns the source text it wrote — the contract
|
|
341
|
+
Every format class implements (specs/extensions.md) — so the answer is a string. */
|
|
317
342
|
return (await formatAction({
|
|
318
343
|
action: "serialize",
|
|
319
344
|
doc,
|
|
@@ -322,42 +347,47 @@ export async function formatSerialize(
|
|
|
322
347
|
})) as string;
|
|
323
348
|
}
|
|
324
349
|
|
|
350
|
+
/** A document's frontmatter: the open keys of a Jx node, as a format's parser left them. */
|
|
351
|
+
export type FormatFrontmatter = Record<string, JxDocumentValue | undefined>;
|
|
352
|
+
|
|
353
|
+
/** What {@link splitFormatDocument} makes of a parsed format document. */
|
|
354
|
+
export interface SplitFormatDocument {
|
|
355
|
+
document: JxMutableNode;
|
|
356
|
+
frontmatter: FormatFrontmatter;
|
|
357
|
+
mode: "component" | "content";
|
|
358
|
+
}
|
|
359
|
+
|
|
325
360
|
/**
|
|
326
361
|
* Split a parsed format document into { document, frontmatter, mode } per the format's
|
|
327
362
|
* `$studio.documentMode` hints. Component documents (e.g. a frontmatter `tagName` with a hyphen)
|
|
328
363
|
* keep their full shape; content documents separate frontmatter metadata from the body children.
|
|
329
364
|
*/
|
|
330
|
-
export function splitFormatDocument(
|
|
365
|
+
export function splitFormatDocument(
|
|
366
|
+
format: StudioFormat | undefined,
|
|
367
|
+
doc: JxMutableNode,
|
|
368
|
+
): SplitFormatDocument {
|
|
331
369
|
const hints = format?.studio?.documentMode;
|
|
332
370
|
const componentWhen = hints?.componentWhen;
|
|
333
371
|
if (componentWhen?.frontmatterKey) {
|
|
334
372
|
const value = doc[componentWhen.frontmatterKey];
|
|
335
373
|
const pattern = componentWhen.matches ? new RegExp(componentWhen.matches) : /./;
|
|
336
|
-
if (
|
|
337
|
-
return {
|
|
338
|
-
document: doc,
|
|
339
|
-
frontmatter: {} as Record<string, unknown>,
|
|
340
|
-
mode: "component",
|
|
341
|
-
};
|
|
374
|
+
if (isString(value) && pattern.test(value)) {
|
|
375
|
+
return { document: doc, frontmatter: {}, mode: "component" };
|
|
342
376
|
}
|
|
343
377
|
}
|
|
344
378
|
if (hints?.default === "component") {
|
|
345
|
-
return {
|
|
346
|
-
document: doc,
|
|
347
|
-
frontmatter: {} as Record<string, unknown>,
|
|
348
|
-
mode: "component",
|
|
349
|
-
};
|
|
379
|
+
return { document: doc, frontmatter: {}, mode: "component" };
|
|
350
380
|
}
|
|
351
381
|
|
|
352
382
|
// Content document — children form the root-level body; other keys are frontmatter
|
|
353
|
-
const children =
|
|
354
|
-
if (children.length === 0) {
|
|
383
|
+
const children = doc.children ?? [];
|
|
384
|
+
if (Array.isArray(children) && children.length === 0) {
|
|
355
385
|
children.push({ children: [], tagName: "p" });
|
|
356
386
|
}
|
|
357
387
|
|
|
358
388
|
const documentKeys = new Set(["state", "imports"]);
|
|
359
|
-
const contentDoc:
|
|
360
|
-
const frontmatter:
|
|
389
|
+
const contentDoc: JxMutableNode = { children };
|
|
390
|
+
const frontmatter: FormatFrontmatter = {};
|
|
361
391
|
for (const [key, value] of Object.entries(doc)) {
|
|
362
392
|
if (key === "children") {
|
|
363
393
|
continue;
|
|
@@ -369,9 +399,5 @@ export function splitFormatDocument(format: StudioFormat | undefined, doc: JxMut
|
|
|
369
399
|
}
|
|
370
400
|
}
|
|
371
401
|
|
|
372
|
-
return {
|
|
373
|
-
document: contentDoc as JxMutableNode,
|
|
374
|
-
frontmatter,
|
|
375
|
-
mode: "content",
|
|
376
|
-
};
|
|
402
|
+
return { document: contentDoc, frontmatter, mode: "content" };
|
|
377
403
|
}
|
|
@@ -18,6 +18,14 @@
|
|
|
18
18
|
|
|
19
19
|
const STORAGE_KEY = "jx_github_token";
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* The GitHub OAuth app every Jx sign-in authorizes against: the browser's device flow in
|
|
23
|
+
* `github-auth.ts`, and the desktop launcher's RFC 8252 loopback redirect
|
|
24
|
+
* (`packages/desktop/src/github-signin.ts`). Here, in the module with no UI dependency, because the
|
|
25
|
+
* launcher's main process imports it too.
|
|
26
|
+
*/
|
|
27
|
+
export const GITHUB_OAUTH_CLIENT_ID = "Ov23liYVlMFpgjOEPXJH";
|
|
28
|
+
|
|
21
29
|
/**
|
|
22
30
|
* The desktop launcher's RFC 8252 sign-in, when this build is running inside one.
|
|
23
31
|
*
|
|
@@ -30,13 +38,29 @@ export interface NativeGithubAuth {
|
|
|
30
38
|
status: () => Promise<{ stored: boolean }>;
|
|
31
39
|
}
|
|
32
40
|
|
|
33
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Whether the registered platform object carries a launcher's `githubAuth` member.
|
|
43
|
+
*
|
|
44
|
+
* Presence is the whole test, as it always was: the member is written only by a launcher's adapter
|
|
45
|
+
* (`packages/desktop/src/platform.ts`), which installs a {@link NativeGithubAuth}, and a browser
|
|
46
|
+
* build has no member at all.
|
|
47
|
+
*/
|
|
48
|
+
function carriesNativeAuth(platform: unknown): platform is { githubAuth: NativeGithubAuth } {
|
|
34
49
|
return (
|
|
35
|
-
|
|
36
|
-
|
|
50
|
+
typeof platform === "object" &&
|
|
51
|
+
platform !== null &&
|
|
52
|
+
"githubAuth" in platform &&
|
|
53
|
+
platform.githubAuth != null
|
|
37
54
|
);
|
|
38
55
|
}
|
|
39
56
|
|
|
57
|
+
export function nativeAuth(): NativeGithubAuth | null {
|
|
58
|
+
// `globalThis` as a plain object: its declared type knows nothing of the launcher's slot.
|
|
59
|
+
const host: object = globalThis;
|
|
60
|
+
const platform = "__jxPlatform" in host ? host.__jxPlatform : undefined;
|
|
61
|
+
return carriesNativeAuth(platform) ? platform.githubAuth : null;
|
|
62
|
+
}
|
|
63
|
+
|
|
40
64
|
/**
|
|
41
65
|
* The token the desktop store handed us this session.
|
|
42
66
|
*
|
|
@@ -59,8 +59,14 @@ import { errorMessage } from "@jxsuite/schema/parse";
|
|
|
59
59
|
import { notify } from "../services/notify";
|
|
60
60
|
import { layerHost } from "../ui/layers";
|
|
61
61
|
import { openGithubAuthSurface } from "../surfaces/github-auth";
|
|
62
|
-
import
|
|
63
|
-
|
|
62
|
+
import {
|
|
63
|
+
getGithubToken,
|
|
64
|
+
GITHUB_OAUTH_CLIENT_ID,
|
|
65
|
+
nativeAuth,
|
|
66
|
+
setNativeToken,
|
|
67
|
+
STORAGE_KEY,
|
|
68
|
+
} from "./github-auth-status";
|
|
69
|
+
import type { DialogLayerHandle } from "../ui/surface";
|
|
64
70
|
|
|
65
71
|
// Every other caller in Studio still reaches these through this module.
|
|
66
72
|
export {
|
|
@@ -71,8 +77,6 @@ export {
|
|
|
71
77
|
hydrateGithubToken,
|
|
72
78
|
} from "./github-auth-status";
|
|
73
79
|
|
|
74
|
-
const CLIENT_ID = "Ov23liYVlMFpgjOEPXJH";
|
|
75
|
-
|
|
76
80
|
/** One key for the whole sign-in, so a second attempt REPLACES the first report. */
|
|
77
81
|
const NOTIFY_KEY = "github.auth";
|
|
78
82
|
|
|
@@ -108,10 +112,10 @@ interface TokenResponse {
|
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
/** The request never completed — a Problem, with the one sentence that covers both causes. */
|
|
111
|
-
function reportUnreachable(
|
|
115
|
+
function reportUnreachable(cause: unknown): void {
|
|
112
116
|
notify.error("Could not reach GitHub to sign in.", {
|
|
113
117
|
action: RETRY,
|
|
114
|
-
detail: `${UNREACHABLE_DETAIL}\n\n${errorMessage(
|
|
118
|
+
detail: `${UNREACHABLE_DETAIL}\n\n${errorMessage(cause)}`,
|
|
115
119
|
key: NOTIFY_KEY,
|
|
116
120
|
source: SOURCE,
|
|
117
121
|
});
|
|
@@ -132,7 +136,7 @@ async function requestDeviceCode(): Promise<DeviceCodeResponse | null> {
|
|
|
132
136
|
let codeRes: Response;
|
|
133
137
|
try {
|
|
134
138
|
codeRes = await fetch("https://github.com/login/device/code", {
|
|
135
|
-
body: JSON.stringify({ client_id:
|
|
139
|
+
body: JSON.stringify({ client_id: GITHUB_OAUTH_CLIENT_ID, scope: "repo" }),
|
|
136
140
|
headers: {
|
|
137
141
|
Accept: "application/json",
|
|
138
142
|
"Content-Type": "application/json",
|
|
@@ -151,6 +155,9 @@ async function requestDeviceCode(): Promise<DeviceCodeResponse | null> {
|
|
|
151
155
|
);
|
|
152
156
|
return null;
|
|
153
157
|
}
|
|
158
|
+
/* SAFETY: a 2xx from GitHub's device-code endpoint (checked just above) is the JSON object
|
|
159
|
+
RFC 8628 §3.2 defines — `device_code`, `user_code`, `verification_uri` and an optional
|
|
160
|
+
`interval` — which is exactly what `DeviceCodeResponse` declares. */
|
|
154
161
|
return (await codeRes.json()) as DeviceCodeResponse;
|
|
155
162
|
}
|
|
156
163
|
|
|
@@ -247,7 +254,7 @@ export async function authenticateGithub() {
|
|
|
247
254
|
try {
|
|
248
255
|
const tokenRes = await fetch("https://github.com/login/oauth/access_token", {
|
|
249
256
|
body: JSON.stringify({
|
|
250
|
-
client_id:
|
|
257
|
+
client_id: GITHUB_OAUTH_CLIENT_ID,
|
|
251
258
|
device_code,
|
|
252
259
|
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
253
260
|
}),
|
|
@@ -257,6 +264,9 @@ export async function authenticateGithub() {
|
|
|
257
264
|
},
|
|
258
265
|
method: "POST",
|
|
259
266
|
});
|
|
267
|
+
/* SAFETY: GitHub's token endpoint answers every poll with a JSON object carrying either an
|
|
268
|
+
`access_token` (RFC 6749 §5.1) or an `error` code (RFC 8628 §3.5); `TokenResponse` makes
|
|
269
|
+
Both optional, and every branch below reads them as possibly absent. */
|
|
260
270
|
const tokenData = (await tokenRes.json()) as TokenResponse;
|
|
261
271
|
failures = 0;
|
|
262
272
|
|
|
@@ -303,7 +313,7 @@ export async function authenticateGithub() {
|
|
|
303
313
|
* the surface existed would find a binding that is not initialised yet — which a zero-second
|
|
304
314
|
* device interval makes reachable rather than theoretical.
|
|
305
315
|
*/
|
|
306
|
-
const handle:
|
|
316
|
+
const handle: DialogLayerHandle = openGithubAuthSurface({
|
|
307
317
|
layer: layerHost("dialog"),
|
|
308
318
|
onCancel: () => {
|
|
309
319
|
takeDown();
|
|
@@ -31,7 +31,8 @@ import { authenticateGithub } from "./github-auth";
|
|
|
31
31
|
import { beginActivity } from "../panels/activity-panel";
|
|
32
32
|
import { getPlatform } from "../platform";
|
|
33
33
|
import { notify } from "../services/notify";
|
|
34
|
-
import type {
|
|
34
|
+
import type { RepoOptions } from "../surfaces/github-publish";
|
|
35
|
+
import type { DialogLayerHandle } from "../ui/surface";
|
|
35
36
|
|
|
36
37
|
interface GithubErrorResponse {
|
|
37
38
|
errors?: { message?: string }[];
|
|
@@ -77,7 +78,7 @@ function askForRepoOptions(projectName: string): Promise<RepoOptions | null> {
|
|
|
77
78
|
answered = true;
|
|
78
79
|
resolve(value);
|
|
79
80
|
};
|
|
80
|
-
const handle:
|
|
81
|
+
const handle: DialogLayerHandle = openGithubPublishSurface({
|
|
81
82
|
layer: layerHost("dialog"),
|
|
82
83
|
name: projectName,
|
|
83
84
|
onCancel: () => {
|
|
@@ -125,25 +126,24 @@ export async function createGithubRepository({ projectName }: { projectName: str
|
|
|
125
126
|
});
|
|
126
127
|
|
|
127
128
|
activity.step(REPO_STEPS[0]);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
129
|
+
let createRes: Response;
|
|
130
|
+
try {
|
|
131
|
+
createRes = await fetch("https://api.github.com/user/repos", {
|
|
132
|
+
body: JSON.stringify({
|
|
133
|
+
auto_init: false,
|
|
134
|
+
description: repoOpts.description,
|
|
135
|
+
name: repoOpts.name,
|
|
136
|
+
private: repoOpts.isPrivate,
|
|
137
|
+
}),
|
|
138
|
+
headers: {
|
|
139
|
+
Accept: "application/vnd.github+json",
|
|
140
|
+
Authorization: `Bearer ${token}`,
|
|
141
|
+
"Content-Type": "application/json",
|
|
142
|
+
},
|
|
143
|
+
method: "POST",
|
|
144
|
+
});
|
|
145
|
+
} catch (error) {
|
|
142
146
|
activity.log(errorMessage(error));
|
|
143
|
-
return null;
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
if (!createRes) {
|
|
147
147
|
activity.fail("Could not reach GitHub to create the repository.", {
|
|
148
148
|
action: "git.createGithubRepository",
|
|
149
149
|
});
|
|
@@ -151,6 +151,8 @@ export async function createGithubRepository({ projectName }: { projectName: str
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
if (!createRes.ok) {
|
|
154
|
+
/* SAFETY: GitHub's REST API answers a failed request with a JSON body carrying `message` and,
|
|
155
|
+
For a validation failure, an `errors` array; both are optional here and read with fallbacks. */
|
|
154
156
|
const err = (await createRes.json()) as GithubErrorResponse;
|
|
155
157
|
activity.log(err.errors?.[0]?.message || err.message || `GitHub answered ${createRes.status}.`);
|
|
156
158
|
activity.fail("Could not create the GitHub repository.", {
|
|
@@ -159,6 +161,8 @@ export async function createGithubRepository({ projectName }: { projectName: str
|
|
|
159
161
|
return false;
|
|
160
162
|
}
|
|
161
163
|
|
|
164
|
+
/* SAFETY: `createRes.ok` was checked above, and a successful `POST /user/repos` answers with the
|
|
165
|
+
Full repository object, of which `clone_url` and `html_url` are required members. */
|
|
162
166
|
const repo = (await createRes.json()) as GithubRepoResponse;
|
|
163
167
|
activity.log(`Created ${repo.html_url}`);
|
|
164
168
|
const platform = getPlatform();
|
package/src/grid/cell-editors.ts
CHANGED
|
@@ -58,15 +58,18 @@ import { live } from "lit-html/directives/live.js";
|
|
|
58
58
|
import { cellToText, coerceCellInput } from "./schema-columns";
|
|
59
59
|
import type { GridCellValue, GridColumn } from "./grid-source";
|
|
60
60
|
|
|
61
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* The subset of Tabulator's CellComponent the editors/formatters touch. A cell's value is a
|
|
63
|
+
* {@link GridCellValue}: the grid's row data is the grid source's rows, which hold nothing else.
|
|
64
|
+
*/
|
|
62
65
|
export interface CellLike {
|
|
63
|
-
getValue: () =>
|
|
66
|
+
getValue: () => GridCellValue;
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
export type CellEditorFn = (
|
|
67
70
|
cell: CellLike,
|
|
68
71
|
onRendered: (fn: () => void) => void,
|
|
69
|
-
success: (value:
|
|
72
|
+
success: (value: GridCellValue) => void,
|
|
70
73
|
cancel: () => void,
|
|
71
74
|
) => HTMLElement;
|
|
72
75
|
|
|
@@ -75,6 +78,17 @@ export type CellFormatterFn = (cell: CellLike) => HTMLElement;
|
|
|
75
78
|
/** Detached-host factory — grid-view owns the one sanctioned document.createElement. */
|
|
76
79
|
export type HostFactory = (className: string) => HTMLElement;
|
|
77
80
|
|
|
81
|
+
/**
|
|
82
|
+
* The `<input>` a listener in this file is bound on.
|
|
83
|
+
*
|
|
84
|
+
* Every input listener here sits on the `<input>` its own template renders, and an input has no
|
|
85
|
+
* children, so a keydown, change or blur it hears was dispatched at the input itself.
|
|
86
|
+
*/
|
|
87
|
+
function inputOf(e: Event): HTMLInputElement {
|
|
88
|
+
// SAFETY: the listener is bound on an `<input>` (above), and a void element is its events' target.
|
|
89
|
+
return e.target as HTMLInputElement;
|
|
90
|
+
}
|
|
91
|
+
|
|
78
92
|
/** Commit/cancel wiring shared by every text-ish editor. */
|
|
79
93
|
function inputEditor(makeHost: HostFactory, column: GridColumn, inputType: string): CellEditorFn {
|
|
80
94
|
return (cell, onRendered, success, cancel) => {
|
|
@@ -94,8 +108,8 @@ function inputEditor(makeHost: HostFactory, column: GridColumn, inputType: strin
|
|
|
94
108
|
};
|
|
95
109
|
const initial =
|
|
96
110
|
column.kind === "date"
|
|
97
|
-
? cellToText(cell.getValue()
|
|
98
|
-
: cellToText(cell.getValue()
|
|
111
|
+
? cellToText(cell.getValue()).slice(0, 10)
|
|
112
|
+
: cellToText(cell.getValue());
|
|
99
113
|
render(
|
|
100
114
|
html`<input
|
|
101
115
|
class="jx-grid-input"
|
|
@@ -103,12 +117,12 @@ function inputEditor(makeHost: HostFactory, column: GridColumn, inputType: strin
|
|
|
103
117
|
.value=${live(initial)}
|
|
104
118
|
@keydown=${(e: KeyboardEvent) => {
|
|
105
119
|
if (e.key === "Enter") {
|
|
106
|
-
commit((e
|
|
120
|
+
commit(inputOf(e).value);
|
|
107
121
|
} else if (e.key === "Escape") {
|
|
108
122
|
abort();
|
|
109
123
|
}
|
|
110
124
|
}}
|
|
111
|
-
@blur=${(e: Event) => commit((e
|
|
125
|
+
@blur=${(e: Event) => commit(inputOf(e).value)}
|
|
112
126
|
/>`,
|
|
113
127
|
host,
|
|
114
128
|
);
|
|
@@ -133,7 +147,7 @@ function checkboxEditor(makeHost: HostFactory): CellEditorFn {
|
|
|
133
147
|
@change=${(e: Event) => {
|
|
134
148
|
if (!done) {
|
|
135
149
|
done = true;
|
|
136
|
-
success((e
|
|
150
|
+
success(inputOf(e).checked);
|
|
137
151
|
}
|
|
138
152
|
}}
|
|
139
153
|
@keydown=${(e: KeyboardEvent) => {
|
|
@@ -142,13 +156,13 @@ function checkboxEditor(makeHost: HostFactory): CellEditorFn {
|
|
|
142
156
|
cancel();
|
|
143
157
|
} else if (e.key === "Enter" && !done) {
|
|
144
158
|
done = true;
|
|
145
|
-
success((e
|
|
159
|
+
success(inputOf(e).checked);
|
|
146
160
|
}
|
|
147
161
|
}}
|
|
148
162
|
@blur=${(e: Event) => {
|
|
149
163
|
if (!done) {
|
|
150
164
|
done = true;
|
|
151
|
-
success((e
|
|
165
|
+
success(inputOf(e).checked);
|
|
152
166
|
}
|
|
153
167
|
}}
|
|
154
168
|
/>`,
|
|
@@ -160,19 +174,19 @@ function checkboxEditor(makeHost: HostFactory): CellEditorFn {
|
|
|
160
174
|
}
|
|
161
175
|
|
|
162
176
|
function selectEditor(makeHost: HostFactory, column: GridColumn): CellEditorFn {
|
|
163
|
-
const options = Array.isArray(column.schema?.enum)
|
|
164
|
-
? (column.schema.enum as unknown[]).map(String)
|
|
165
|
-
: [];
|
|
177
|
+
const options = Array.isArray(column.schema?.enum) ? column.schema.enum.map(String) : [];
|
|
166
178
|
return (cell, onRendered, success, cancel) => {
|
|
167
179
|
const host = makeHost("jx-grid-editor");
|
|
168
180
|
let done = false;
|
|
169
|
-
const current = cellToText(cell.getValue()
|
|
181
|
+
const current = cellToText(cell.getValue());
|
|
170
182
|
render(
|
|
171
183
|
html`<select
|
|
172
184
|
class="jx-grid-select"
|
|
173
185
|
@change=${(e: Event) => {
|
|
174
186
|
if (!done) {
|
|
175
187
|
done = true;
|
|
188
|
+
// SAFETY: this listener is bound on the `<select>` rendered here, and `change` is
|
|
189
|
+
// Dispatched at the select itself, never at one of its options.
|
|
176
190
|
const { value } = e.target as HTMLSelectElement;
|
|
177
191
|
success(value === "" ? null : value);
|
|
178
192
|
}
|
|
@@ -235,26 +249,27 @@ function pillEditor(makeHost: HostFactory, column: GridColumn): CellEditorFn {
|
|
|
235
249
|
render(
|
|
236
250
|
html`<span class="jx-grid-pills">
|
|
237
251
|
${chips.map(
|
|
238
|
-
(chip, i) =>
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
+
(chip, i) =>
|
|
253
|
+
html`<span class="jx-grid-chip"
|
|
254
|
+
>${chip}<button
|
|
255
|
+
class="jx-grid-chip-x"
|
|
256
|
+
title="Remove"
|
|
257
|
+
@mousedown=${(e: Event) => e.preventDefault()}
|
|
258
|
+
@click=${() => {
|
|
259
|
+
chips.splice(i, 1);
|
|
260
|
+
doRender();
|
|
261
|
+
inputEl()?.focus();
|
|
262
|
+
}}
|
|
263
|
+
>
|
|
264
|
+
×
|
|
265
|
+
</button></span
|
|
266
|
+
>`,
|
|
252
267
|
)}
|
|
253
268
|
<input
|
|
254
269
|
class="jx-grid-pill-input"
|
|
255
270
|
placeholder=${chips.length === 0 ? "add…" : ""}
|
|
256
271
|
@keydown=${(e: KeyboardEvent) => {
|
|
257
|
-
const input = e
|
|
272
|
+
const input = inputOf(e);
|
|
258
273
|
if (e.key === "Enter" || e.key === ",") {
|
|
259
274
|
e.preventDefault();
|
|
260
275
|
if (addFromInput(input)) {
|
|
@@ -272,7 +287,7 @@ function pillEditor(makeHost: HostFactory, column: GridColumn): CellEditorFn {
|
|
|
272
287
|
}
|
|
273
288
|
}}
|
|
274
289
|
@blur=${(e: Event) => {
|
|
275
|
-
addFromInput(e
|
|
290
|
+
addFromInput(inputOf(e));
|
|
276
291
|
finish([...chips]);
|
|
277
292
|
}}
|
|
278
293
|
/>
|
|
@@ -317,7 +332,7 @@ export function editorForColumn(
|
|
|
317
332
|
/** Formatter factory — plain-text projection rendered as a real element (innerHTML-safe). */
|
|
318
333
|
export function formatterForColumn(column: GridColumn, makeHost: HostFactory): CellFormatterFn {
|
|
319
334
|
return (cell) => {
|
|
320
|
-
const value = cell.getValue()
|
|
335
|
+
const value = cell.getValue();
|
|
321
336
|
const host = makeHost(`jx-grid-cell-content jx-grid-kind-${column.kind}`);
|
|
322
337
|
if (column.kind === "boolean") {
|
|
323
338
|
render(html`${value === true ? "✓" : ""}`, host);
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* through the panel's island seam (specs/studio-ui-guidelines.md §9.4) — the box is drawn by one
|
|
13
13
|
* document and filled by another, and nothing in this file renders anything.
|
|
14
14
|
*/
|
|
15
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
15
16
|
import { openGridCellSurface } from "../surfaces/grid-cell";
|
|
16
17
|
import { mountMediaPicker } from "../ui/media-picker";
|
|
17
18
|
import { listCollectionEntryIds } from "./sources/content-source";
|
|
@@ -25,8 +26,9 @@ export function hasPopoverEditor(column: GridColumn): boolean {
|
|
|
25
26
|
|
|
26
27
|
/** Target content-type name of a relationship column (`#/content/<name>` on the schema). */
|
|
27
28
|
export function referenceTargetType(column: GridColumn): string | null {
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
// The schema is the project's own JSON, so `$ref` is checked rather than trusted to be a string.
|
|
30
|
+
const ref = column.schema?.$ref;
|
|
31
|
+
if (!isString(ref) || !ref.startsWith("#/content/")) {
|
|
30
32
|
return null;
|
|
31
33
|
}
|
|
32
34
|
return ref.slice("#/content/".length);
|
|
@@ -47,7 +49,7 @@ export interface CellPopoverArgs {
|
|
|
47
49
|
* The clamp is the panel's own width and a floor for its height, because a cell near the right edge
|
|
48
50
|
* of a wide grid is exactly where a relationship column tends to be.
|
|
49
51
|
*/
|
|
50
|
-
function placement(anchor: CellPopoverArgs["anchor"])
|
|
52
|
+
function placement(anchor: CellPopoverArgs["anchor"]) {
|
|
51
53
|
return {
|
|
52
54
|
x: Math.max(4, Math.min(anchor.left, window.innerWidth - 340)),
|
|
53
55
|
y: Math.max(4, Math.min(anchor.bottom + 2, window.innerHeight - 200)),
|