@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
package/src/panels/head-panel.ts
CHANGED
|
@@ -27,12 +27,14 @@
|
|
|
27
27
|
* `packages/compiler/src/site/head-merger.ts` by `tests/head-panel.test.ts`.
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
|
+
import { isString } from "@jxsuite/schema/guards";
|
|
30
31
|
import { nothing } from "lit-html";
|
|
31
32
|
import { projectState, renderOnly } from "../store";
|
|
32
33
|
import type { DirEntry, JsonValue } from "../types";
|
|
33
34
|
import { activeTab } from "../workspace/workspace";
|
|
34
35
|
import { activeRegistry } from "../commands/active-registry";
|
|
35
36
|
import { clearProblems, notify } from "../services/notify";
|
|
37
|
+
import type { NotifyOptions } from "../services/notify";
|
|
36
38
|
import { registerPanel } from "./panel-registry";
|
|
37
39
|
import { mutateUpdateFrontmatter, transact, transactDoc } from "../tabs/transact";
|
|
38
40
|
import { collectFmFields, projectFmField } from "./frontmatter-fields";
|
|
@@ -49,13 +51,14 @@ import type { JxHeadEntry, JxMutableNode } from "@jxsuite/schema/types";
|
|
|
49
51
|
import type { Tab } from "../tabs/tab";
|
|
50
52
|
import type * as MediaPickerModule from "../ui/media-picker";
|
|
51
53
|
import type {
|
|
52
|
-
PageChoice,
|
|
53
54
|
PagePanelActions,
|
|
54
55
|
PagePanelView,
|
|
55
56
|
PageRow,
|
|
56
57
|
PageSection,
|
|
57
58
|
PageTagRow,
|
|
58
59
|
} from "../surfaces/panel-page";
|
|
60
|
+
import type { SurfaceOption } from "../ui/surface";
|
|
61
|
+
import type { SeoWarningView } from "../surfaces/seo";
|
|
59
62
|
|
|
60
63
|
interface MetaField {
|
|
61
64
|
label: string;
|
|
@@ -154,6 +157,15 @@ export const RESERVED_FM_KEYS = new Set(["title"]);
|
|
|
154
157
|
|
|
155
158
|
// ─── Helpers ─────────────────────────────────────────────────────────────
|
|
156
159
|
|
|
160
|
+
/**
|
|
161
|
+
* One slot of a `$head` array as it is read off a document.
|
|
162
|
+
*
|
|
163
|
+
* Wider than `JxHeadEntry` on purpose: a Markdown page's `$head` is its frontmatter, which reaches
|
|
164
|
+
* these helpers through {@link buildHeadDoc} without being validated, so an empty YAML list item
|
|
165
|
+
* arrives as `null`. Every reader here steps over such a slot rather than throwing on it.
|
|
166
|
+
*/
|
|
167
|
+
type HeadSlot = JxHeadEntry | null | undefined;
|
|
168
|
+
|
|
157
169
|
/**
|
|
158
170
|
* Find a `$head` meta entry by attribute match.
|
|
159
171
|
*
|
|
@@ -162,11 +174,8 @@ export const RESERVED_FM_KEYS = new Set(["title"]);
|
|
|
162
174
|
* @param {string} key
|
|
163
175
|
* @returns {JxHeadEntry | undefined}
|
|
164
176
|
*/
|
|
165
|
-
export function findMetaEntry(head:
|
|
166
|
-
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
return head.find((e: JxHeadEntry) => e?.tagName === "meta" && e?.attributes?.[attr] === key);
|
|
177
|
+
export function findMetaEntry(head: readonly HeadSlot[], attr: "name" | "property", key: string) {
|
|
178
|
+
return head.find((e): e is JxHeadEntry => e?.tagName === "meta" && e.attributes?.[attr] === key);
|
|
170
179
|
}
|
|
171
180
|
|
|
172
181
|
/**
|
|
@@ -176,11 +185,8 @@ export function findMetaEntry(head: JxHeadEntry[], attr: "name" | "property", ke
|
|
|
176
185
|
* @param {string} rel
|
|
177
186
|
* @returns {JxHeadEntry | undefined}
|
|
178
187
|
*/
|
|
179
|
-
export function findLinkEntry(head:
|
|
180
|
-
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
return head.find((e: JxHeadEntry) => e?.tagName === "link" && e?.attributes?.rel === rel);
|
|
188
|
+
export function findLinkEntry(head: readonly HeadSlot[], rel: string) {
|
|
189
|
+
return head.find((e): e is JxHeadEntry => e?.tagName === "link" && e.attributes?.rel === rel);
|
|
184
190
|
}
|
|
185
191
|
|
|
186
192
|
/**
|
|
@@ -189,20 +195,20 @@ export function findLinkEntry(head: JxHeadEntry[], rel: string) {
|
|
|
189
195
|
* @param {JxHeadEntry} entry
|
|
190
196
|
* @returns {boolean}
|
|
191
197
|
*/
|
|
192
|
-
export function isManagedEntry(entry:
|
|
198
|
+
export function isManagedEntry(entry: HeadSlot) {
|
|
193
199
|
if (!entry?.tagName) {
|
|
194
200
|
return false;
|
|
195
201
|
}
|
|
196
202
|
// Managed meta tags
|
|
197
203
|
if (entry.tagName === "meta") {
|
|
198
|
-
const name = String(entry
|
|
199
|
-
const prop = String(entry
|
|
204
|
+
const name = String(entry.attributes?.name ?? "");
|
|
205
|
+
const prop = String(entry.attributes?.property ?? "");
|
|
200
206
|
return (
|
|
201
207
|
Boolean(name && MANAGED_META_KEYS.has(name)) || Boolean(prop && MANAGED_META_KEYS.has(prop))
|
|
202
208
|
);
|
|
203
209
|
}
|
|
204
210
|
// Managed link: favicon
|
|
205
|
-
if (entry.tagName === "link" && entry
|
|
211
|
+
if (entry.tagName === "link" && entry.attributes?.rel === "icon") {
|
|
206
212
|
return true;
|
|
207
213
|
}
|
|
208
214
|
return false;
|
|
@@ -226,7 +232,7 @@ export function upsertMeta(
|
|
|
226
232
|
doc.$head = [];
|
|
227
233
|
}
|
|
228
234
|
const idx = doc.$head.findIndex(
|
|
229
|
-
(e:
|
|
235
|
+
(e: HeadSlot) => e?.tagName === "meta" && e.attributes?.[attr] === key,
|
|
230
236
|
);
|
|
231
237
|
if (content) {
|
|
232
238
|
const entry = { attributes: { [attr]: key, content }, tagName: "meta" };
|
|
@@ -252,7 +258,7 @@ export function upsertLink(doc: JxMutableNode, rel: string, href: string) {
|
|
|
252
258
|
doc.$head = [];
|
|
253
259
|
}
|
|
254
260
|
const idx = doc.$head.findIndex(
|
|
255
|
-
(e:
|
|
261
|
+
(e: HeadSlot) => e?.tagName === "link" && e.attributes?.rel === rel,
|
|
256
262
|
);
|
|
257
263
|
if (href) {
|
|
258
264
|
const entry = { attributes: { href, rel }, tagName: "link" };
|
|
@@ -272,7 +278,7 @@ export function upsertLink(doc: JxMutableNode, rel: string, href: string) {
|
|
|
272
278
|
* @param {JxHeadEntry} entry
|
|
273
279
|
* @returns {string}
|
|
274
280
|
*/
|
|
275
|
-
export function entryLabel(entry:
|
|
281
|
+
export function entryLabel(entry: HeadSlot) {
|
|
276
282
|
if (!entry?.tagName) {
|
|
277
283
|
return "unknown";
|
|
278
284
|
}
|
|
@@ -301,7 +307,7 @@ export function entryLabel(entry: JxHeadEntry) {
|
|
|
301
307
|
* @param {JxHeadEntry} entry
|
|
302
308
|
* @returns {string}
|
|
303
309
|
*/
|
|
304
|
-
export function entryValue(entry:
|
|
310
|
+
export function entryValue(entry: HeadSlot) {
|
|
305
311
|
const a = entry?.attributes ?? {};
|
|
306
312
|
return String(a.content ?? a.href ?? a.src ?? entry?.textContent ?? "");
|
|
307
313
|
}
|
|
@@ -358,11 +364,15 @@ const NOT_SUPPLIED: ResolvedHeadField = { donor: null, source: "none", value: ""
|
|
|
358
364
|
* Last rather than first, because the merger folds a layer into a keyed map in array order: a layer
|
|
359
365
|
* that lists `description` twice emits the second one.
|
|
360
366
|
*/
|
|
361
|
-
function metaContentIn(
|
|
367
|
+
function metaContentIn(
|
|
368
|
+
head: readonly HeadSlot[],
|
|
369
|
+
attr: "name" | "property",
|
|
370
|
+
key: string,
|
|
371
|
+
): string | null {
|
|
362
372
|
let found: string | null = null;
|
|
363
373
|
for (const entry of head) {
|
|
364
|
-
if (entry?.tagName === "meta" && entry
|
|
365
|
-
found = String(entry.attributes
|
|
374
|
+
if (entry?.tagName === "meta" && entry.attributes?.[attr] === key) {
|
|
375
|
+
found = String(entry.attributes.content ?? "");
|
|
366
376
|
}
|
|
367
377
|
}
|
|
368
378
|
return found;
|
|
@@ -483,12 +493,12 @@ export interface SeoField extends ResolvedHeadField {
|
|
|
483
493
|
* a verdict, and the verdict is what gets optimised (§16.6). A count beside a limit says the same
|
|
484
494
|
* thing without pretending to rank it.
|
|
485
495
|
*/
|
|
486
|
-
export const SEO_LIMITS:
|
|
487
|
-
description
|
|
488
|
-
"og:description"
|
|
489
|
-
"og:title"
|
|
490
|
-
title
|
|
491
|
-
|
|
496
|
+
export const SEO_LIMITS: ReadonlyMap<string, number> = new Map([
|
|
497
|
+
["description", 160],
|
|
498
|
+
["og:description", 200],
|
|
499
|
+
["og:title", 60],
|
|
500
|
+
["title", 60],
|
|
501
|
+
]);
|
|
492
502
|
|
|
493
503
|
/** Counts what a reader sees as one character. See {@link visibleLength}. */
|
|
494
504
|
const GRAPHEME_SEGMENTER = new Intl.Segmenter("en-US", { granularity: "grapheme" });
|
|
@@ -518,15 +528,6 @@ export function visibleLength(value: string): number {
|
|
|
518
528
|
return count;
|
|
519
529
|
}
|
|
520
530
|
|
|
521
|
-
/** A named thing that is wrong, or absent. Never summed — the list IS the report. */
|
|
522
|
-
export interface SeoWarning {
|
|
523
|
-
/** Stable id, so a test and a shot name the same warning. */
|
|
524
|
-
id: string;
|
|
525
|
-
/** The head key the warning is about, so the field row can carry it. */
|
|
526
|
-
field: string;
|
|
527
|
-
message: string;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
531
|
/** The Problems `source` the SEO warnings carry, so a re-run replaces rather than stacks. */
|
|
531
532
|
export const SEO_PROBLEM_SOURCE = "Search appearance";
|
|
532
533
|
|
|
@@ -548,13 +549,16 @@ export const SEO_PROBLEM_SOURCE = "Search appearance";
|
|
|
548
549
|
export function reportSeoProblems(preview: SeoPreview, path?: string): number {
|
|
549
550
|
clearProblems((record) => record.source === SEO_PROBLEM_SOURCE);
|
|
550
551
|
for (const warning of preview.warnings) {
|
|
551
|
-
|
|
552
|
+
const opts: NotifyOptions = {
|
|
552
553
|
action: "document.openSeo",
|
|
553
554
|
key: `seo.${warning.id}`,
|
|
554
555
|
source: SEO_PROBLEM_SOURCE,
|
|
555
556
|
tier: "problem",
|
|
556
|
-
|
|
557
|
-
|
|
557
|
+
};
|
|
558
|
+
if (path !== undefined) {
|
|
559
|
+
opts.path = path;
|
|
560
|
+
}
|
|
561
|
+
notify.warn(warning.message, opts);
|
|
558
562
|
}
|
|
559
563
|
return preview.warnings.length;
|
|
560
564
|
}
|
|
@@ -564,7 +568,7 @@ export interface SeoPreview {
|
|
|
564
568
|
url: SeoUrl;
|
|
565
569
|
/** In render order: `title`, `description`, then the four OpenGraph keys. */
|
|
566
570
|
fields: SeoField[];
|
|
567
|
-
warnings:
|
|
571
|
+
warnings: SeoWarningView[];
|
|
568
572
|
}
|
|
569
573
|
|
|
570
574
|
/** Look one field up by key — the previews read four of the six by name. */
|
|
@@ -574,14 +578,16 @@ export function seoField(preview: SeoPreview, key: string): SeoField {
|
|
|
574
578
|
...NOT_SUPPLIED,
|
|
575
579
|
key,
|
|
576
580
|
label: key,
|
|
577
|
-
limit: SEO_LIMITS
|
|
581
|
+
limit: SEO_LIMITS.get(key) ?? null,
|
|
578
582
|
}
|
|
579
583
|
);
|
|
580
584
|
}
|
|
581
585
|
|
|
582
586
|
/** Whether any layer declares a `<title>` element, which the merger discards. */
|
|
583
587
|
function hasTitleEntry(layers: HeadLayers): boolean {
|
|
584
|
-
return [...layers.site, ...layers.layout, ...layers.page].some(
|
|
588
|
+
return [...layers.site, ...layers.layout, ...layers.page].some(
|
|
589
|
+
(e: HeadSlot) => e?.tagName === "title",
|
|
590
|
+
);
|
|
585
591
|
}
|
|
586
592
|
|
|
587
593
|
/**
|
|
@@ -593,13 +599,13 @@ function hasTitleEntry(layers: HeadLayers): boolean {
|
|
|
593
599
|
*
|
|
594
600
|
* @param {SeoPreview} preview — `warnings` is ignored; this computes it.
|
|
595
601
|
* @param {HeadLayers} layers
|
|
596
|
-
* @returns {
|
|
602
|
+
* @returns {SeoWarningView[]}
|
|
597
603
|
*/
|
|
598
604
|
export function seoWarnings(
|
|
599
605
|
preview: Omit<SeoPreview, "warnings">,
|
|
600
606
|
layers: HeadLayers,
|
|
601
|
-
):
|
|
602
|
-
const warnings:
|
|
607
|
+
): SeoWarningView[] {
|
|
608
|
+
const warnings: SeoWarningView[] = [];
|
|
603
609
|
const get = (key: string) => preview.fields.find((f) => f.key === key);
|
|
604
610
|
|
|
605
611
|
const title = get("title");
|
|
@@ -671,6 +677,14 @@ export function seoWarnings(
|
|
|
671
677
|
return warnings;
|
|
672
678
|
}
|
|
673
679
|
|
|
680
|
+
/** What {@link buildSeoPreview} needs besides the layers: the page's own title, route and site. */
|
|
681
|
+
export interface SeoPreviewContext {
|
|
682
|
+
pageTitle: string;
|
|
683
|
+
route: string | null;
|
|
684
|
+
siteName?: string;
|
|
685
|
+
siteUrl?: string;
|
|
686
|
+
}
|
|
687
|
+
|
|
674
688
|
/**
|
|
675
689
|
* Build the whole preview from the three layers, the page title, the route and the site config.
|
|
676
690
|
*
|
|
@@ -678,18 +692,15 @@ export function seoWarnings(
|
|
|
678
692
|
* (resolving the layout document) happens in {@link layoutHeadEntries} before this is called.
|
|
679
693
|
*
|
|
680
694
|
* @param {HeadLayers} layers
|
|
681
|
-
* @param {
|
|
695
|
+
* @param {SeoPreviewContext} ctx
|
|
682
696
|
* @returns {SeoPreview}
|
|
683
697
|
*/
|
|
684
|
-
export function buildSeoPreview(
|
|
685
|
-
layers: HeadLayers,
|
|
686
|
-
ctx: { pageTitle: string; route: string | null; siteName?: string; siteUrl?: string },
|
|
687
|
-
): SeoPreview {
|
|
698
|
+
export function buildSeoPreview(layers: HeadLayers, ctx: SeoPreviewContext): SeoPreview {
|
|
688
699
|
const field = (key: string, label: string, resolved: ResolvedHeadField): SeoField => ({
|
|
689
700
|
...resolved,
|
|
690
701
|
key,
|
|
691
702
|
label,
|
|
692
|
-
limit: SEO_LIMITS
|
|
703
|
+
limit: SEO_LIMITS.get(key) ?? null,
|
|
693
704
|
});
|
|
694
705
|
|
|
695
706
|
const fields: SeoField[] = [
|
|
@@ -765,6 +776,12 @@ export function layoutDisplayName(path: string): string {
|
|
|
765
776
|
);
|
|
766
777
|
}
|
|
767
778
|
|
|
779
|
+
/** A layout's `$head` entries, and the name to print for the layout. */
|
|
780
|
+
export interface LayoutHead {
|
|
781
|
+
entries: JxHeadEntry[];
|
|
782
|
+
name: string | null;
|
|
783
|
+
}
|
|
784
|
+
|
|
768
785
|
/**
|
|
769
786
|
* The effective layout's `$head`, and the name to print for it.
|
|
770
787
|
*
|
|
@@ -774,15 +791,9 @@ export function layoutDisplayName(path: string): string {
|
|
|
774
791
|
*
|
|
775
792
|
* @param {Tab | null} tab — the tab whose document the entries are being resolved FOR.
|
|
776
793
|
* @param {string | false} [docLayout]
|
|
777
|
-
* @returns {
|
|
794
|
+
* @returns {LayoutHead}
|
|
778
795
|
*/
|
|
779
|
-
export function layoutHeadEntries(
|
|
780
|
-
tab: Tab | null,
|
|
781
|
-
docLayout?: string | false,
|
|
782
|
-
): {
|
|
783
|
-
entries: JxHeadEntry[];
|
|
784
|
-
name: string | null;
|
|
785
|
-
} {
|
|
796
|
+
export function layoutHeadEntries(tab: Tab | null, docLayout?: string | false): LayoutHead {
|
|
786
797
|
const path = isPageDocument(tab) ? getEffectiveLayoutPath(docLayout) : null;
|
|
787
798
|
if (path === null) {
|
|
788
799
|
return { entries: [], name: null };
|
|
@@ -807,6 +818,17 @@ export function seoPreviewFor(tab: Tab | null, doc: JxMutableNode): SeoPreview {
|
|
|
807
818
|
const config = projectState?.projectConfig;
|
|
808
819
|
const layout = layoutHeadEntries(tab, doc.$layout);
|
|
809
820
|
const path = tab?.documentPath;
|
|
821
|
+
// A content document's head doc may carry a non-string title (see buildHeadDoc).
|
|
822
|
+
const ctx: SeoPreviewContext = {
|
|
823
|
+
pageTitle: isString(doc.title) ? doc.title : "",
|
|
824
|
+
route: path ? pageRoute(path) : null,
|
|
825
|
+
};
|
|
826
|
+
if (config?.name !== undefined) {
|
|
827
|
+
ctx.siteName = config.name;
|
|
828
|
+
}
|
|
829
|
+
if (config?.url !== undefined) {
|
|
830
|
+
ctx.siteUrl = config.url;
|
|
831
|
+
}
|
|
810
832
|
return buildSeoPreview(
|
|
811
833
|
{
|
|
812
834
|
layout: layout.entries,
|
|
@@ -814,12 +836,7 @@ export function seoPreviewFor(tab: Tab | null, doc: JxMutableNode): SeoPreview {
|
|
|
814
836
|
page: doc.$head ?? [],
|
|
815
837
|
site: config?.$head ?? [],
|
|
816
838
|
},
|
|
817
|
-
|
|
818
|
-
pageTitle: typeof doc.title === "string" ? doc.title : "",
|
|
819
|
-
route: path ? pageRoute(path) : null,
|
|
820
|
-
...(config?.name === undefined ? {} : { siteName: config.name }),
|
|
821
|
-
...(config?.url === undefined ? {} : { siteUrl: config.url }),
|
|
822
|
-
},
|
|
839
|
+
ctx,
|
|
823
840
|
);
|
|
824
841
|
}
|
|
825
842
|
|
|
@@ -853,14 +870,24 @@ export function isPageDocument(tab: Tab | null): boolean {
|
|
|
853
870
|
}
|
|
854
871
|
|
|
855
872
|
/** Overlay content-mode frontmatter title/`$head` onto the document the panel edits. */
|
|
856
|
-
export function buildHeadDoc(
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
873
|
+
export function buildHeadDoc(
|
|
874
|
+
doc: JxMutableNode,
|
|
875
|
+
fm: Tab["doc"]["content"]["frontmatter"],
|
|
876
|
+
): JxMutableNode {
|
|
877
|
+
const headDoc: JxMutableNode = { ...doc };
|
|
878
|
+
if (fm.title !== undefined) {
|
|
879
|
+
/* SAFETY: deliberately not narrowed — a YAML title can be a number, and it is overlaid as
|
|
880
|
+
written. Every reader of a head doc's `title` (titleRow here and in frontmatter-panel.ts,
|
|
881
|
+
seoPreviewFor) tests it with isString before using it as text. */
|
|
882
|
+
headDoc.title = fm.title as string;
|
|
883
|
+
}
|
|
884
|
+
if (fm.$head !== undefined) {
|
|
885
|
+
/* SAFETY: Studio's one writer of the frontmatter `$head` key is applyContentMutation below,
|
|
886
|
+
which stores a JxHeadEntry[] or deletes the key. A hand-written one is trusted exactly as
|
|
887
|
+
far as a JSON page's `doc.$head` is, and the readers step over null slots (HeadSlot). */
|
|
888
|
+
headDoc.$head = fm.$head as JxHeadEntry[];
|
|
889
|
+
}
|
|
890
|
+
return headDoc;
|
|
864
891
|
}
|
|
865
892
|
|
|
866
893
|
/**
|
|
@@ -890,19 +917,25 @@ export function applyContentMutation(
|
|
|
890
917
|
if (!tab) {
|
|
891
918
|
return;
|
|
892
919
|
}
|
|
893
|
-
const fmNow =
|
|
894
|
-
|
|
895
|
-
const
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
920
|
+
const fmNow = tab.doc.content.frontmatter;
|
|
921
|
+
// The frontmatter `$head`, read through the one place that types it.
|
|
922
|
+
const fmHead = buildHeadDoc({}, fmNow).$head;
|
|
923
|
+
const tmp: JxMutableNode = {};
|
|
924
|
+
if (isString(fmNow.title)) {
|
|
925
|
+
tmp.title = fmNow.title;
|
|
926
|
+
}
|
|
927
|
+
if (fmHead) {
|
|
928
|
+
tmp.$head = [...fmHead];
|
|
929
|
+
}
|
|
899
930
|
fn(tmp);
|
|
900
931
|
if (tmp.title !== fmNow.title) {
|
|
901
|
-
mutateUpdateFrontmatter(tab, "title", tmp.title
|
|
932
|
+
mutateUpdateFrontmatter(tab, "title", tmp.title);
|
|
902
933
|
}
|
|
903
934
|
const newHead = tmp.$head && tmp.$head.length > 0 ? tmp.$head : undefined;
|
|
904
|
-
|
|
905
|
-
|
|
935
|
+
/* SAFETY: every entry here either came from the frontmatter (JSON, from the format's split) or
|
|
936
|
+
was built by a head editor out of string attributes; JxHeadEntry is wider than JsonValue only
|
|
937
|
+
through its open index signature, which no head editor writes. */
|
|
938
|
+
mutateUpdateFrontmatter(tab, "$head", newHead as JsonValue | undefined);
|
|
906
939
|
rerender();
|
|
907
940
|
}
|
|
908
941
|
|
|
@@ -957,7 +990,7 @@ const _entries = new Map<string, JxHeadEntry>();
|
|
|
957
990
|
const _pending = new Map<string, { commit: () => void; timer: ReturnType<typeof setTimeout> }>();
|
|
958
991
|
|
|
959
992
|
/** The elements the add form offers, in the order a reader meets them. */
|
|
960
|
-
const TAG_OPTIONS:
|
|
993
|
+
const TAG_OPTIONS: SurfaceOption[] = [
|
|
961
994
|
{ label: "meta", value: "meta" },
|
|
962
995
|
{ label: "link", value: "link" },
|
|
963
996
|
{ label: "script", value: "script" },
|
|
@@ -991,7 +1024,7 @@ function thumbFor(row: PageRow, value: string): void {
|
|
|
991
1024
|
|
|
992
1025
|
/** The one head value you type while writing, in both realms. */
|
|
993
1026
|
function titleRow(doc: JxMutableNode, apply: PagePanelContext["applyMutation"]): PageRow {
|
|
994
|
-
const title =
|
|
1027
|
+
const title = isString(doc.title) ? doc.title : "";
|
|
995
1028
|
_commits.set("title", {
|
|
996
1029
|
clear: () =>
|
|
997
1030
|
apply((d) => {
|
|
@@ -1140,8 +1173,7 @@ function frontmatterSection(tab: Tab | null): PageSection | null {
|
|
|
1140
1173
|
});
|
|
1141
1174
|
_commits.set(key, {
|
|
1142
1175
|
clear: () => transactDoc(tab, (t) => mutateUpdateFrontmatter(t, f.field)),
|
|
1143
|
-
commit: (raw) =>
|
|
1144
|
-
transactDoc(tab, (t) => mutateUpdateFrontmatter(t, f.field, parse(raw) as JsonValue)),
|
|
1176
|
+
commit: (raw) => transactDoc(tab, (t) => mutateUpdateFrontmatter(t, f.field, parse(raw))),
|
|
1145
1177
|
});
|
|
1146
1178
|
return Object.assign(blankRow(key, f.field, row.label), row, {
|
|
1147
1179
|
clearLabel: `Clear ${f.field}`,
|
|
@@ -1158,16 +1190,18 @@ function frontmatterSection(tab: Tab | null): PageSection | null {
|
|
|
1158
1190
|
/** The `$head` entries no structured control owns, and the keys a Remove hands back. */
|
|
1159
1191
|
function customEntries(head: JxHeadEntry[]): PageTagRow[] {
|
|
1160
1192
|
_entries.clear();
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
});
|
|
1193
|
+
const rows: PageTagRow[] = [];
|
|
1194
|
+
for (const entry of head) {
|
|
1195
|
+
if (isManagedEntry(entry) || isGoogleFontEntry(entry) || isGoogleFontPreconnect(entry)) {
|
|
1196
|
+
continue;
|
|
1197
|
+
}
|
|
1198
|
+
// The key counts the LISTED entries, as the index of the filtered list it replaces did.
|
|
1199
|
+
const key = `tag:${rows.length}`;
|
|
1200
|
+
_entries.set(key, entry);
|
|
1201
|
+
const label = entryLabel(entry);
|
|
1202
|
+
rows.push({ key, label, removeLabel: `Remove ${label}`, value: entryValue(entry) });
|
|
1203
|
+
}
|
|
1204
|
+
return rows;
|
|
1171
1205
|
}
|
|
1172
1206
|
|
|
1173
1207
|
/**
|
|
@@ -1436,20 +1470,6 @@ function contentArea(body: HTMLElement): HTMLElement {
|
|
|
1436
1470
|
return body.querySelector<HTMLElement>(".panel-content") ?? body;
|
|
1437
1471
|
}
|
|
1438
1472
|
|
|
1439
|
-
/**
|
|
1440
|
-
* The Navigator no longer draws this panel with lit.
|
|
1441
|
-
*
|
|
1442
|
-
* The record below returns `nothing` and mounts its document in `afterRender`, so this is a stub:
|
|
1443
|
-
* it survives only because `NavigatorPanelDeps` still declares the injection and `studio.ts` still
|
|
1444
|
-
* passes it. Both go in the change that deletes this.
|
|
1445
|
-
*
|
|
1446
|
-
* @deprecated The panel is `surfaces/panel-page.json`; call {@link renderPagePanel}.
|
|
1447
|
-
* @returns {typeof nothing}
|
|
1448
|
-
*/
|
|
1449
|
-
export function renderHeadTemplate(_against: PagePanelContext): typeof nothing {
|
|
1450
|
-
return nothing;
|
|
1451
|
-
}
|
|
1452
|
-
|
|
1453
1473
|
/**
|
|
1454
1474
|
* Contribute the Page panel.
|
|
1455
1475
|
*
|
package/src/panels/i18n-panel.ts
CHANGED
|
@@ -63,6 +63,7 @@ import type {
|
|
|
63
63
|
I18nSurfaceHandle,
|
|
64
64
|
I18nValues,
|
|
65
65
|
} from "../surfaces/panel-i18n";
|
|
66
|
+
import type { CommandArgValues } from "../commands/command-args";
|
|
66
67
|
import type { LibraryFile, ScanFailure } from "../browse/library-model";
|
|
67
68
|
import type { NavigatorPanelContext, PanelBody } from "./panel-registry";
|
|
68
69
|
import type { ResolvedI18n } from "@jxsuite/schema/locale";
|
|
@@ -254,7 +255,7 @@ export function parityRows(
|
|
|
254
255
|
/* Every key the paths alone produce, so a declared one can be matched against a real file rather
|
|
255
256
|
than against a spelling. */
|
|
256
257
|
const derivedKeys = new Set(
|
|
257
|
-
files.
|
|
258
|
+
files.flatMap((f) => (f.category === "Media" ? [] : [translationKeyOfPath(f.path, i18n)])),
|
|
258
259
|
);
|
|
259
260
|
const keyOf = (file: LibraryFile): string => {
|
|
260
261
|
const own = declared.get(file.path);
|
|
@@ -401,7 +402,7 @@ function cellTitle(cell: ParityCell, locale: string, refusal: string | undefined
|
|
|
401
402
|
* report is what makes the next such drift a sentence in the Problems panel rather than an
|
|
402
403
|
* exception out of a click.
|
|
403
404
|
*/
|
|
404
|
-
function runByName(id: string, args:
|
|
405
|
+
function runByName(id: string, args: CommandArgValues = {}): void {
|
|
405
406
|
const registry = activeRegistry();
|
|
406
407
|
if (!registry?.get(id)) {
|
|
407
408
|
return;
|
|
@@ -437,7 +438,13 @@ function projectRow(row: ParityRow, i18n: ResolvedI18n): I18nParityRow {
|
|
|
437
438
|
}
|
|
438
439
|
|
|
439
440
|
/** How many squares are not yet a file, and how many are behind their source. */
|
|
440
|
-
|
|
441
|
+
interface CellCounts {
|
|
442
|
+
missing: number;
|
|
443
|
+
stale: number;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/** Tallies {@link CellCounts} over every square of the grid. */
|
|
447
|
+
function countCells(rows: readonly ParityRow[]): CellCounts {
|
|
441
448
|
let missing = 0;
|
|
442
449
|
let stale = 0;
|
|
443
450
|
for (const row of rows) {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* turn, where a Navigator repaint is a frame away and would rebuild far more than one field.
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
+
import { isNonNullObject, isString } from "@jxsuite/schema/guards";
|
|
24
25
|
import { nothing } from "lit-html";
|
|
25
26
|
import { componentRegistry } from "../files/components";
|
|
26
27
|
import {
|
|
@@ -46,9 +47,9 @@ import type {
|
|
|
46
47
|
ImportsActions,
|
|
47
48
|
ImportsView,
|
|
48
49
|
PackageRow,
|
|
49
|
-
PickerOption,
|
|
50
50
|
} from "../surfaces/panel-imports";
|
|
51
|
-
import type {
|
|
51
|
+
import type { JxMutableNode } from "@jxsuite/schema/types";
|
|
52
|
+
import type { SurfaceOption } from "../ui/surface";
|
|
52
53
|
|
|
53
54
|
/** What the panel is drawn against. `left-panel.ts`'s context, reduced to what this reads. */
|
|
54
55
|
export interface ImportsContext {
|
|
@@ -105,17 +106,19 @@ function groupByPackage() {
|
|
|
105
106
|
if (comp.source !== "npm" || !comp.package || !comp.modulePath) {
|
|
106
107
|
continue;
|
|
107
108
|
}
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
let group = groups.get(comp.package);
|
|
110
|
+
if (!group) {
|
|
111
|
+
group = [];
|
|
112
|
+
groups.set(comp.package, group);
|
|
110
113
|
}
|
|
111
|
-
|
|
114
|
+
group.push(comp);
|
|
112
115
|
}
|
|
113
116
|
return groups;
|
|
114
117
|
}
|
|
115
118
|
|
|
116
119
|
/** The project's `$elements`, as the site-level mood reads and rewrites it. */
|
|
117
120
|
function siteElements(): ElementsEntry[] {
|
|
118
|
-
return
|
|
121
|
+
return projectState?.projectConfig?.$elements ?? [];
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
/**
|
|
@@ -163,19 +166,15 @@ function siteView(): ImportsView {
|
|
|
163
166
|
/** The document-level mood: this document's component imports, and what it could still import. */
|
|
164
167
|
function documentView(ctx: ImportsContext): ImportsView {
|
|
165
168
|
const { documentElements, documentPath } = ctx;
|
|
166
|
-
const refs = documentElements
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
typeof entry === "object" &&
|
|
171
|
-
typeof (entry as { $ref?: unknown }).$ref === "string",
|
|
172
|
-
)
|
|
173
|
-
.map((entry) => ({ ref: entry.$ref }));
|
|
169
|
+
const refs = documentElements.flatMap((entry) => {
|
|
170
|
+
const ref = isNonNullObject(entry) ? entry.$ref : undefined;
|
|
171
|
+
return isString(ref) ? [{ ref }] : [];
|
|
172
|
+
});
|
|
174
173
|
/* The checkbox reads the STRING entries only. A `$ref` is a project component and is listed
|
|
175
174
|
above; letting it answer here would tick an npm box for a file that happens to share a name. */
|
|
176
|
-
const npmEntries = documentElements.filter((entry) =>
|
|
175
|
+
const npmEntries = documentElements.filter((entry) => isString(entry));
|
|
177
176
|
const imported = new Set(refs.map((entry) => entry.ref));
|
|
178
|
-
const available:
|
|
177
|
+
const available: SurfaceOption[] = componentRegistry
|
|
179
178
|
.filter(
|
|
180
179
|
(comp: ComponentEntry) =>
|
|
181
180
|
comp.source !== "npm" &&
|
|
@@ -276,7 +275,7 @@ async function onRemovePackage(pkg: string): Promise<void> {
|
|
|
276
275
|
const updated = removePackageElements(siteElements(), pkg);
|
|
277
276
|
const { loadComponentRegistry } = await import("../files/components.js");
|
|
278
277
|
await loadComponentRegistry();
|
|
279
|
-
await updateSiteConfig({ $elements: updated
|
|
278
|
+
await updateSiteConfig({ $elements: updated });
|
|
280
279
|
context()?.renderLeftPanel();
|
|
281
280
|
} catch (error) {
|
|
282
281
|
console.error("Failed to remove package:", error);
|
|
@@ -301,17 +300,15 @@ async function onToggleComponent(id: string, checked: boolean): Promise<void> {
|
|
|
301
300
|
const updated = checked
|
|
302
301
|
? enableElement(before, comp, null)
|
|
303
302
|
: disableElement(before, comp, null);
|
|
304
|
-
await updateSiteConfig({ $elements: updated
|
|
303
|
+
await updateSiteConfig({ $elements: updated });
|
|
305
304
|
ctx.renderLeftPanel();
|
|
306
305
|
return;
|
|
307
306
|
}
|
|
308
307
|
ctx.applyMutation((doc: JxMutableNode) => {
|
|
309
|
-
const before =
|
|
310
|
-
doc.$elements =
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
: disableElement(before, comp, ctx.documentPath)
|
|
314
|
-
) as (string | JxElement)[];
|
|
308
|
+
const before = doc.$elements ?? [];
|
|
309
|
+
doc.$elements = checked
|
|
310
|
+
? enableElement(before, comp, ctx.documentPath)
|
|
311
|
+
: disableElement(before, comp, ctx.documentPath);
|
|
315
312
|
});
|
|
316
313
|
ctx.renderLeftPanel();
|
|
317
314
|
}
|
|
@@ -339,11 +336,7 @@ function onPick(value: string): void {
|
|
|
339
336
|
/* Through the service, which is also what makes this idempotent: it checked nothing and pushed a
|
|
340
337
|
second `$ref` every time you chose the same component. */
|
|
341
338
|
ctx.applyMutation((doc: JxMutableNode) => {
|
|
342
|
-
doc.$elements = enableElement(
|
|
343
|
-
(doc.$elements ?? []) as ElementsEntry[],
|
|
344
|
-
comp,
|
|
345
|
-
ctx.documentPath,
|
|
346
|
-
) as (string | JxElement)[];
|
|
339
|
+
doc.$elements = enableElement(doc.$elements ?? [], comp, ctx.documentPath);
|
|
347
340
|
});
|
|
348
341
|
ctx.renderLeftPanel();
|
|
349
342
|
}
|
|
@@ -355,10 +348,7 @@ function onRemoveRef(elementRef: string): void {
|
|
|
355
348
|
return;
|
|
356
349
|
}
|
|
357
350
|
ctx.applyMutation((doc: JxMutableNode) => {
|
|
358
|
-
doc.$elements = removeElementRef(
|
|
359
|
-
| string
|
|
360
|
-
| JxElement
|
|
361
|
-
)[];
|
|
351
|
+
doc.$elements = removeElementRef(doc.$elements ?? [], elementRef);
|
|
362
352
|
});
|
|
363
353
|
ctx.renderLeftPanel();
|
|
364
354
|
}
|
|
@@ -437,20 +427,6 @@ function contentArea(body: HTMLElement): HTMLElement {
|
|
|
437
427
|
return body.querySelector<HTMLElement>(".panel-content") ?? body;
|
|
438
428
|
}
|
|
439
429
|
|
|
440
|
-
/**
|
|
441
|
-
* The Navigator no longer draws this panel with lit.
|
|
442
|
-
*
|
|
443
|
-
* The record below returns `nothing` and mounts its document in `afterRender`, so this is a stub:
|
|
444
|
-
* it survives only because `NavigatorPanelDeps` still declares the injection and `studio.ts` still
|
|
445
|
-
* passes it. Both go in the change that deletes this.
|
|
446
|
-
*
|
|
447
|
-
* @deprecated The panel is `surfaces/panel-imports.json`; call {@link renderImportsPanel}.
|
|
448
|
-
* @returns {typeof nothing}
|
|
449
|
-
*/
|
|
450
|
-
export function renderImportsTemplate(_against: ImportsContext): typeof nothing {
|
|
451
|
-
return nothing;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
430
|
/**
|
|
455
431
|
* Contribute the Packages panel.
|
|
456
432
|
*
|