@jxsuite/studio 4.0.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/data/elements-meta.json +5 -15
- package/data/html-meta.json +51 -6
- package/dist/chunks/{2020-xp8vnwma.js → 2020-g79n01v9.js} +14 -14
- package/dist/chunks/action-group-sp6tna8v.js +118 -0
- package/dist/chunks/adapter-nj7tnjfn.js +13 -0
- package/dist/chunks/cf-account-picker-fyf63pmy.js +495 -0
- package/dist/chunks/cf-settings-71bv5zn9.js +20 -0
- package/dist/chunks/color-area-v17df7b8.js +154 -0
- package/dist/chunks/color-field-anwybnkn.js +208 -0
- package/dist/chunks/color-slider-44ez96fc.js +79 -0
- package/dist/chunks/color-xgg3kfw7.js +35 -0
- package/dist/chunks/combobox-5e7jev23.js +236 -0
- package/dist/chunks/components-2w1f35qs.js +18 -0
- package/dist/chunks/content-source-3wqeas45.js +46 -0
- package/dist/chunks/convert-to-repeater-d0cgnb6d.js +639 -0
- package/dist/chunks/dialog-s890b918.js +85 -0
- package/dist/chunks/editor-3qhbg51x.js +35 -0
- package/dist/chunks/entry-commands-d6g50j7s.js +42 -0
- package/dist/chunks/extension-sections-fy7q4fe9.js +651 -0
- package/dist/chunks/file-ops-3btj6st0.js +47 -0
- package/dist/chunks/files-ef8fgs3w.js +72 -0
- package/dist/chunks/format-host-3c33nwr8.js +40 -0
- package/dist/chunks/fs-events-13tj6sex.js +18 -0
- package/dist/chunks/git-panel-4wp2rn9b.js +49 -0
- package/dist/chunks/icons-yy10wk9r.js +402 -0
- package/dist/chunks/iframe-entry-15g3n6xv.js +114 -0
- package/dist/chunks/iframe-entry-b27vq81n.js +203 -0
- package/dist/chunks/iframe-entry-nbyxee1y.js +154 -0
- package/dist/chunks/iframe-host-jgesd924.js +115 -0
- package/dist/chunks/{index-nj44jpzj.js → index-mdmyx6s2.js} +11 -11
- package/dist/chunks/index-n4j7qxyr.js +109 -0
- package/dist/chunks/{javascript-q8kpmfah.js → javascript-xvrfrpkb.js} +8 -9
- package/dist/chunks/{jsonMode-dkr040ga.js → jsonMode-tyx2kj6p.js} +526 -527
- package/dist/chunks/jx-validate-j0wxk72w.js +15 -0
- package/dist/chunks/layers-1nq5evsh.js +29 -0
- package/dist/chunks/layers-panel-ar2gh90g.js +40 -0
- package/dist/chunks/listbox-6v2ac08j.js +44 -0
- package/dist/chunks/lit-html-m244w9nh.js +17 -0
- package/dist/chunks/media-picker-2qbetq73.js +33 -0
- package/dist/chunks/menu-q99sy9rf.js +285 -0
- package/dist/chunks/menu-rf7n72mf.js +14 -0
- package/dist/chunks/{monaco-binding-rj6xpx9y.js → monaco-binding-sw6en4dw.js} +12 -15
- package/dist/chunks/monaco-buffer-bhy3hb6m.js +24 -0
- package/dist/chunks/{monaco-setup-rws7k4br.js → monaco-setup-8r62fj6y.js} +27 -37
- package/dist/chunks/notify-628t0anh.js +21 -0
- package/dist/chunks/number-field-5cndyft8.js +72 -0
- package/dist/chunks/parse-0zx14y15.js +10 -0
- package/dist/chunks/platform-ts9cg1a4.js +15 -0
- package/dist/chunks/popover-47z3ytva.js +25 -0
- package/dist/chunks/publish-panel-98f7sr3g.js +27 -0
- package/dist/chunks/quick-search-srzz83k2.js +45 -0
- package/dist/chunks/references-n553f0e1.js +26 -0
- package/dist/chunks/right-panel-rrgx2dn3.js +45 -0
- package/dist/chunks/section-registry-5pq32t0q.js +25 -0
- package/dist/chunks/select-2r16ez41.js +49 -0
- package/dist/chunks/split-g7nm1rgb.js +191 -0
- package/dist/chunks/studio-0hqbpbd0.js +62 -0
- package/dist/chunks/studio-18avnhjp.js +2430 -0
- package/dist/chunks/{studio-kryvsw6j.js → studio-1k325pwf.js} +48 -48
- package/dist/chunks/{studio-hbtp0eh1.js → studio-25hkdrkw.js} +356 -85
- package/dist/chunks/studio-26d7myd1.js +258 -0
- package/dist/chunks/{studio-p8j86wag.js → studio-38emantv.js} +22 -5
- package/dist/chunks/studio-3gxv60tn.js +422 -0
- package/dist/chunks/{studio-8swrjbny.js → studio-3hxkd92t.js} +275 -163
- package/dist/chunks/studio-4m0haseg.js +185 -0
- package/dist/chunks/{studio-ynxwkrzd.js → studio-4wbb9ct0.js} +1953 -1785
- package/dist/chunks/{studio-gv8vvshc.js → studio-5523bpzt.js} +11 -11
- package/dist/chunks/{studio-5q69gfag.js → studio-57mf66w2.js} +1753 -2484
- package/dist/chunks/studio-5jy81t3s.js +17463 -0
- package/dist/chunks/studio-5rt7sqa0.js +1168 -0
- package/dist/chunks/studio-5te5tqng.js +81 -0
- package/dist/chunks/{studio-p4ngc046.js → studio-6ewqv390.js} +9 -9
- package/dist/chunks/{studio-9ab8gqsm.js → studio-6nzaktvy.js} +7 -7
- package/dist/chunks/studio-6xa21ej9.js +28 -0
- package/dist/chunks/{studio-5ehhackm.js → studio-727xh0e3.js} +19 -19
- package/dist/chunks/{studio-eenfkt4e.js → studio-79y5sz51.js} +52 -38
- package/dist/chunks/{studio-4q0wznzf.js → studio-7e11jpa9.js} +461 -145
- package/dist/chunks/{studio-q7v10cg2.js → studio-7r42c6ca.js} +17 -7
- package/dist/chunks/studio-7xptrg0j.js +954 -0
- package/dist/chunks/{studio-cft9r4r7.js → studio-81390n6f.js} +22 -22
- package/dist/chunks/{studio-q43a5y9h.js → studio-8jn5yhyn.js} +16 -16
- package/dist/chunks/studio-8qtrpzr3.js +839 -0
- package/dist/chunks/{studio-dg7zyt5x.js → studio-98b3z07n.js} +1 -1
- package/dist/chunks/studio-9xxz1q69.js +1356 -0
- package/dist/chunks/studio-akbww0j5.js +13615 -0
- package/dist/chunks/studio-arfpe389.js +195 -0
- package/dist/chunks/{studio-2zkz8evn.js → studio-az3zd49t.js} +473 -281
- package/dist/chunks/studio-cpvb2ed1.js +1171 -0
- package/dist/chunks/{studio-9r6j5ev1.js → studio-d0300636.js} +5078 -19
- package/dist/chunks/{studio-bgxt93ga.js → studio-d055c37e.js} +13 -13
- package/dist/chunks/studio-d1ja2x9r.js +362 -0
- package/dist/chunks/{studio-b9b6t1dg.js → studio-e1f24eff.js} +5664 -5666
- package/dist/chunks/{studio-4pqqxbrt.js → studio-em9nw8eh.js} +301 -112
- package/dist/chunks/studio-erdatzvp.js +1190 -0
- package/dist/chunks/{studio-g1wdche0.js → studio-esrxgwh6.js} +80 -80
- package/dist/chunks/studio-fabxk6r9.js +2811 -0
- package/dist/chunks/{studio-3n4ndrzh.js → studio-h4nvnjvz.js} +303 -303
- package/dist/chunks/studio-hhvs4sdg.js +195 -0
- package/dist/chunks/{studio-68n67094.js → studio-kcgff4r0.js} +15 -18
- package/dist/chunks/{studio-685s0ytq.js → studio-nqgawfks.js} +572 -572
- package/dist/chunks/{studio-xrapxwwc.js → studio-p1dw8wfw.js} +55 -29
- package/dist/chunks/studio-pm6hgy7r.js +4763 -0
- package/dist/chunks/studio-q0a3yk4n.js +33 -0
- package/dist/chunks/{studio-wcy8trfx.js → studio-q3x06vmj.js} +23 -22
- package/dist/chunks/studio-qahxvnan.js +111 -0
- package/dist/chunks/{studio-53n8bp04.js → studio-r6xmmtfh.js} +1 -1
- package/dist/chunks/{studio-kjjsjak4.js → studio-rkstz940.js} +3661 -6136
- package/dist/chunks/{studio-tvgyw9xw.js → studio-rnyf3f8e.js} +83 -250
- package/dist/chunks/studio-rpyah2ew.js +2805 -0
- package/dist/chunks/studio-rs76k67r.js +12 -0
- package/dist/chunks/{studio-yxrkyv8a.js → studio-s6z853aq.js} +12108 -11766
- package/dist/chunks/{studio-sf7zjgv1.js → studio-sgdc5pfc.js} +8 -8
- package/dist/chunks/studio-tb3ev01j.js +763 -0
- package/dist/chunks/{studio-t5wqwzdh.js → studio-tjjk7jvk.js} +1 -1
- package/dist/chunks/studio-vhv5tgxm.js +51 -0
- package/dist/chunks/{studio-htsf0w6m.js → studio-vz68yn9e.js} +31 -154
- package/dist/chunks/studio-wqpngpsk.js +174 -0
- package/dist/chunks/{studio-eesa1myv.js → studio-x3rty6tr.js} +58 -58
- package/dist/chunks/studio-xsykpvsh.js +8448 -0
- package/dist/chunks/{studio-92ab2jqe.js → studio-y9zedyjn.js} +14 -14
- package/dist/chunks/studio-yxa81f45.js +12 -0
- package/dist/chunks/swatch-group-t0n6h2rn.js +139 -0
- package/dist/chunks/tabs-wbp1cdws.js +156 -0
- package/dist/chunks/textfield-abk6qyee.js +73 -0
- package/dist/chunks/toast-780pvfbv.js +27 -0
- package/dist/chunks/toast-host-3sqv46sn.js +116 -0
- package/dist/chunks/toolbar-xbh5bhtr.js +194 -0
- package/dist/chunks/tooltip-eptb614w.js +369 -0
- package/dist/chunks/tree-a73p0pqm.js +367 -0
- package/dist/chunks/{tsMode-76kr53q0.js → tsMode-jy4m86rv.js} +83 -85
- package/dist/chunks/workspace-wrew8zk4.js +69 -0
- package/dist/chunks/{ws-client-6shc5rze.js → ws-client-ny4zc51r.js} +20 -22
- package/dist/iframe-entry.js +1812 -698
- package/dist/manifest.json +7 -0
- package/dist/studio.js +52900 -36573
- package/dist/workers/editor.worker.js +1040 -1085
- package/dist/workers/json.worker.js +1946 -1991
- package/dist/workers/ts.worker.js +4960 -5005
- package/favicon.ico +0 -0
- package/index.html +2 -0
- package/package.json +22 -55
- package/src/about/about-modal.ts +73 -123
- package/src/browse/library-commands.ts +20 -49
- package/src/browse/library-layouts.ts +87 -218
- package/src/browse/library-pane.ts +406 -438
- package/src/canvas/canvas-helpers.ts +0 -49
- package/src/canvas/canvas-live-render.ts +25 -2
- package/src/canvas/canvas-render.ts +666 -231
- package/src/canvas/canvas-surface.ts +0 -1
- package/src/canvas/canvas-utils.ts +310 -117
- package/src/canvas/dialog-path.ts +76 -0
- package/src/canvas/dialog-state.ts +67 -0
- package/src/canvas/diff-marks.ts +252 -0
- package/src/canvas/diff-toolbar.ts +349 -0
- package/src/canvas/diff-view.ts +123 -0
- package/src/canvas/edit-width-drag.ts +187 -0
- package/src/canvas/edit-width.ts +150 -0
- package/src/canvas/iframe-entry.ts +125 -8
- package/src/canvas/iframe-host.ts +271 -15
- package/src/canvas/iframe-interaction.ts +133 -13
- package/src/canvas/iframe-patch.ts +7 -1
- package/src/canvas/iframe-position.ts +5 -6
- package/src/canvas/iframe-protocol.ts +106 -5
- package/src/canvas/iframe-render.ts +373 -5
- package/src/canvas/iframe-slash.ts +2 -2
- package/src/canvas/iframe-subtree.ts +5 -8
- package/src/canvas/path-mapping.ts +25 -3
- package/src/canvas/popover-path.ts +106 -0
- package/src/canvas/popover-state.ts +155 -0
- package/src/canvas/surface-registry.ts +21 -10
- package/src/collab/presence-chips.ts +51 -73
- package/src/commands/app-commands.ts +10 -0
- package/src/commands/budget.ts +12 -0
- package/src/commands/command-args.ts +369 -6
- package/src/commands/defaults.ts +44 -14
- package/src/commands/live-context.ts +11 -5
- package/src/commands/reference.ts +12 -2
- package/src/commands/registry.ts +165 -8
- package/src/content/entry-commands.ts +16 -23
- package/src/content/entry-editor.ts +144 -101
- package/src/editor/canvas-slash-bridge.ts +2 -2
- package/src/editor/context-menu.ts +49 -200
- package/src/editor/convert-to-component.ts +42 -82
- package/src/editor/convert-to-repeater.ts +132 -173
- package/src/editor/inline-edit.ts +11 -0
- package/src/editor/shortcuts.ts +65 -26
- package/src/editor/slash-menu.ts +150 -157
- package/src/files/file-ops.ts +117 -11
- package/src/files/files.ts +949 -664
- package/src/files/json-layout.ts +474 -0
- package/src/files/media-paths.ts +13 -42
- package/src/files/media-usage.ts +41 -131
- package/src/files/serialize-document.ts +8 -1
- package/src/format/convert-file.ts +16 -10
- package/src/format/format-host.ts +50 -1
- package/src/github/github-auth.ts +71 -29
- package/src/github/github-publish.ts +57 -65
- package/src/grid/cell-editors.ts +46 -4
- package/src/grid/cell-popovers.ts +65 -62
- package/src/grid/grid-open.ts +86 -64
- package/src/grid/grid-panel.ts +390 -469
- package/src/grid/redirects-grid.ts +40 -44
- package/src/hosting/document.ts +2 -0
- package/src/hosting/layout.ts +10 -0
- package/src/i18n/i18n-commands.ts +127 -62
- package/src/media/media-pane.ts +83 -133
- package/src/new-project/add-repo-modal.ts +125 -176
- package/src/new-project/import-tab.ts +201 -250
- package/src/new-project/location-fields.ts +101 -165
- package/src/new-project/new-project-modal.ts +376 -367
- package/src/packages/jxsuite-update.ts +76 -18
- package/src/panels/activity-panel.ts +137 -104
- package/src/panels/ai-chat/chat-markdown.ts +15 -13
- package/src/panels/ai-chat/chat-view.ts +307 -472
- package/src/panels/ai-chat/composer.ts +175 -153
- package/src/panels/ai-chat/sessions-view.ts +31 -62
- package/src/panels/ai-panel.ts +210 -185
- package/src/panels/block-action-bar.ts +437 -643
- package/src/panels/bottom-dock.ts +112 -47
- package/src/panels/chat-panel.ts +19 -14
- package/src/panels/data-explorer.ts +141 -102
- package/src/panels/data-grid.ts +183 -150
- package/src/panels/dnd.ts +75 -20
- package/src/panels/editors.ts +26 -19
- package/src/panels/elements-panel.ts +243 -186
- package/src/panels/empty-state.ts +26 -42
- package/src/panels/events-panel.ts +950 -729
- package/src/panels/formula-workspace.ts +434 -207
- package/src/panels/frontmatter-fields.ts +185 -153
- package/src/panels/frontmatter-panel.ts +411 -187
- package/src/panels/git-diff-open.ts +148 -0
- package/src/panels/git-panel.ts +679 -605
- package/src/panels/head-panel.ts +617 -435
- package/src/panels/i18n-panel.ts +153 -133
- package/src/panels/imports-panel.ts +388 -414
- package/src/panels/jump-bar.ts +174 -147
- package/src/panels/layers-panel.ts +785 -671
- package/src/panels/left-panel.ts +166 -94
- package/src/panels/navigator-panels.ts +1 -1
- package/src/panels/pane-context.ts +529 -677
- package/src/panels/pane-grid.ts +265 -241
- package/src/panels/panel-registry.ts +15 -4
- package/src/panels/problems-panel.ts +177 -99
- package/src/panels/properties-panel.ts +1525 -966
- package/src/panels/provenance.ts +31 -113
- package/src/panels/quick-search.ts +217 -172
- package/src/panels/right-panel.ts +135 -169
- package/src/panels/seo-modal.ts +346 -167
- package/src/panels/settings-menu.ts +109 -646
- package/src/panels/settings-pane.ts +102 -86
- package/src/panels/signals-panel.ts +1318 -1172
- package/src/panels/statement-editor.ts +556 -428
- package/src/panels/style-panel.ts +1367 -630
- package/src/panels/style-utils.ts +36 -32
- package/src/panels/stylebook-doc.ts +30 -73
- package/src/panels/stylebook-layers-panel.ts +202 -109
- package/src/panels/stylebook-panel.ts +124 -88
- package/src/panels/tab-strip.ts +385 -287
- package/src/platforms/cloud.ts +347 -86
- package/src/platforms/devserver.ts +13 -0
- package/src/publish/deploy-checklist.ts +124 -78
- package/src/publish/publish-commands.ts +4 -12
- package/src/publish/publish-panel.ts +165 -299
- package/src/services/a11y-report.ts +100 -43
- package/src/services/ai-command-tools.ts +468 -0
- package/src/services/ai-import-tools.ts +50 -12
- package/src/services/ai-models.ts +108 -1
- package/src/services/ai-session-store.ts +6 -0
- package/src/services/ai-system-prompt.ts +110 -18
- package/src/services/ai-tools.ts +28 -143
- package/src/services/ai-write-report.ts +174 -0
- package/src/services/context-manager.ts +12 -1
- package/src/services/document-assistant.ts +50 -2
- package/src/services/idle.ts +16 -14
- package/src/services/live-surfaces.ts +237 -0
- package/src/services/model-uri.ts +75 -0
- package/src/services/notify.ts +63 -6
- package/src/services/popover-report.ts +325 -0
- package/src/services/surface-registry.ts +56 -0
- package/src/services/tool-executor.ts +17 -0
- package/src/settings/contexts-section.ts +301 -299
- package/src/settings/contributed-section.ts +361 -222
- package/src/settings/css-vars-editor.ts +320 -325
- package/src/settings/defs-editor.ts +572 -535
- package/src/settings/dependencies-editor.ts +79 -107
- package/src/settings/extension-commands.ts +379 -0
- package/src/settings/extension-rows.ts +113 -0
- package/src/settings/extensions-section.ts +287 -0
- package/src/settings/general-settings.ts +130 -181
- package/src/settings/head-editor.ts +10 -305
- package/src/settings/locales-section.ts +146 -196
- package/src/settings/preferences-accounts.ts +193 -12
- package/src/settings/preferences-dialog.ts +384 -307
- package/src/settings/project-sections.ts +108 -181
- package/src/settings/schema-field-ui.ts +11 -399
- package/src/settings/section-registry.ts +8 -1
- package/src/settings/settings-document.ts +31 -29
- package/src/shell/tree.ts +42 -87
- package/src/shell.ts +48 -36
- package/src/studio.ts +90 -67
- package/src/style/token-ref.ts +0 -39
- package/src/surfaces/about.json +263 -0
- package/src/surfaces/about.ts +163 -0
- package/src/surfaces/add-repo.json +486 -0
- package/src/surfaces/add-repo.ts +236 -0
- package/src/surfaces/ai-chat.json +2185 -0
- package/src/surfaces/ai-chat.ts +549 -0
- package/src/surfaces/ai-credentials-form.json +332 -0
- package/src/surfaces/ai-credentials-form.ts +151 -0
- package/src/surfaces/ai-managed-connect.json +108 -0
- package/src/surfaces/ai-managed-connect.ts +123 -0
- package/src/surfaces/ai-model-picker.json +114 -0
- package/src/surfaces/ai-model-picker.ts +139 -0
- package/src/surfaces/block-action-bar.json +640 -0
- package/src/surfaces/block-action-bar.ts +368 -0
- package/src/surfaces/bottom-dock.json +154 -0
- package/src/surfaces/bottom-dock.ts +125 -0
- package/src/surfaces/canvas-stage.json +444 -0
- package/src/surfaces/canvas-stage.ts +253 -0
- package/src/surfaces/cf-account-picker.json +300 -0
- package/src/surfaces/cf-account-picker.ts +214 -0
- package/src/surfaces/commandbar.json +984 -0
- package/src/{panels/toolbar.ts → surfaces/commandbar.ts} +414 -389
- package/src/surfaces/convert-repeater.json +309 -0
- package/src/surfaces/convert-repeater.ts +276 -0
- package/src/surfaces/data-actions.json +157 -0
- package/src/surfaces/data-actions.ts +115 -0
- package/src/surfaces/dialog.json +289 -0
- package/src/surfaces/dialog.ts +343 -0
- package/src/surfaces/diff-toolbar.json +266 -0
- package/src/surfaces/diff-toolbar.ts +139 -0
- package/src/surfaces/doc-header.json +739 -0
- package/src/surfaces/doc-header.ts +223 -0
- package/src/surfaces/empty-state.json +152 -0
- package/src/surfaces/empty-state.ts +173 -0
- package/src/surfaces/entry-editor.json +281 -0
- package/src/surfaces/entry-editor.ts +191 -0
- package/src/surfaces/expression-editor.json +977 -0
- package/src/surfaces/expression-editor.ts +266 -0
- package/src/surfaces/files-panel.json +592 -0
- package/src/surfaces/files-panel.ts +301 -0
- package/src/surfaces/formula-palette.json +364 -0
- package/src/surfaces/formula-palette.ts +340 -0
- package/src/surfaces/git-panel.json +1822 -0
- package/src/surfaces/git-panel.ts +272 -0
- package/src/surfaces/github-auth.json +112 -0
- package/src/surfaces/github-auth.ts +139 -0
- package/src/surfaces/github-publish.json +206 -0
- package/src/surfaces/github-publish.ts +169 -0
- package/src/surfaces/grid-cell.json +218 -0
- package/src/surfaces/grid-cell.ts +120 -0
- package/src/surfaces/grid-open.json +147 -0
- package/src/surfaces/grid-open.ts +87 -0
- package/src/surfaces/grid-panel.json +706 -0
- package/src/surfaces/grid-panel.ts +206 -0
- package/src/surfaces/grid-replace.json +179 -0
- package/src/surfaces/grid-replace.ts +89 -0
- package/src/surfaces/grid-views.json +446 -0
- package/src/surfaces/grid-views.ts +172 -0
- package/src/surfaces/inspector-dock.json +187 -0
- package/src/surfaces/inspector-dock.ts +161 -0
- package/src/surfaces/jump-bar.json +243 -0
- package/src/surfaces/jump-bar.ts +129 -0
- package/src/surfaces/jxsuite-update.json +146 -0
- package/src/surfaces/jxsuite-update.ts +149 -0
- package/src/surfaces/library-pane.json +1509 -0
- package/src/surfaces/library-pane.ts +363 -0
- package/src/surfaces/logic-panel.json +1949 -0
- package/src/surfaces/logic-panel.ts +369 -0
- package/src/surfaces/logic-workspace.json +685 -0
- package/src/surfaces/logic-workspace.ts +238 -0
- package/src/surfaces/media-browser.json +303 -0
- package/src/surfaces/media-browser.ts +145 -0
- package/src/surfaces/media-field.json +163 -0
- package/src/surfaces/media-field.ts +116 -0
- package/src/surfaces/media-pane.json +513 -0
- package/src/surfaces/media-pane.ts +197 -0
- package/src/surfaces/menu.json +232 -0
- package/src/surfaces/menu.ts +375 -0
- package/src/surfaces/navigator-dock.json +113 -0
- package/src/surfaces/navigator-dock.ts +130 -0
- package/src/surfaces/new-project.json +1654 -0
- package/src/surfaces/new-project.ts +411 -0
- package/src/surfaces/palette.json +535 -0
- package/src/surfaces/pane-context.json +1497 -0
- package/src/surfaces/pane-context.ts +513 -0
- package/src/surfaces/pane-grid.json +188 -0
- package/src/surfaces/pane-grid.ts +250 -0
- package/src/surfaces/panel-activity.json +563 -0
- package/src/surfaces/panel-activity.ts +187 -0
- package/src/surfaces/panel-data.json +141 -0
- package/src/surfaces/panel-data.ts +156 -0
- package/src/surfaces/panel-deploy-checklist.json +283 -0
- package/src/surfaces/panel-deploy-checklist.ts +175 -0
- package/src/surfaces/panel-elements.json +367 -0
- package/src/surfaces/panel-elements.ts +175 -0
- package/src/surfaces/panel-i18n.json +569 -0
- package/src/surfaces/panel-i18n.ts +212 -0
- package/src/surfaces/panel-imports.json +780 -0
- package/src/surfaces/panel-imports.ts +209 -0
- package/src/surfaces/panel-outline.json +734 -0
- package/src/surfaces/panel-outline.ts +326 -0
- package/src/surfaces/panel-page.json +1017 -0
- package/src/surfaces/panel-page.ts +240 -0
- package/src/surfaces/panel-problems.json +497 -0
- package/src/surfaces/panel-problems.ts +157 -0
- package/src/surfaces/panel-signals.json +1973 -0
- package/src/surfaces/panel-signals.ts +436 -0
- package/src/surfaces/panel-stylebook-layers.json +317 -0
- package/src/surfaces/panel-stylebook-layers.ts +155 -0
- package/src/surfaces/preferences.json +850 -0
- package/src/surfaces/preferences.ts +332 -0
- package/src/surfaces/progress-modal.json +110 -0
- package/src/surfaces/progress-modal.ts +150 -0
- package/src/surfaces/properties-panel.json +1578 -0
- package/src/surfaces/properties-panel.ts +337 -0
- package/src/surfaces/publish.json +945 -0
- package/src/surfaces/publish.ts +392 -0
- package/src/surfaces/push-plan.json +110 -0
- package/src/surfaces/push-plan.ts +87 -0
- package/src/surfaces/rail.json +255 -0
- package/src/surfaces/rail.ts +206 -0
- package/src/surfaces/reference-field.json +191 -0
- package/src/surfaces/reference-field.ts +168 -0
- package/src/surfaces/schema-builder.json +1011 -0
- package/src/surfaces/schema-builder.ts +181 -0
- package/src/surfaces/schema-form.json +1013 -0
- package/src/surfaces/schema-form.ts +287 -0
- package/src/surfaces/secret-field.json +60 -0
- package/src/surfaces/secret-field.ts +146 -0
- package/src/surfaces/seo.json +932 -0
- package/src/surfaces/seo.ts +334 -0
- package/src/surfaces/settings-contexts.json +538 -0
- package/src/surfaces/settings-contexts.ts +196 -0
- package/src/surfaces/settings-contributed.json +489 -0
- package/src/surfaces/settings-contributed.ts +199 -0
- package/src/surfaces/settings-css-vars.json +820 -0
- package/src/surfaces/settings-css-vars.ts +199 -0
- package/src/surfaces/settings-defs.json +1363 -0
- package/src/surfaces/settings-defs.ts +232 -0
- package/src/surfaces/settings-deploy.json +108 -0
- package/src/surfaces/settings-deploy.ts +135 -0
- package/src/surfaces/settings-extensions.json +486 -0
- package/src/surfaces/settings-extensions.ts +201 -0
- package/src/surfaces/settings-head.json +779 -0
- package/src/surfaces/settings-head.ts +397 -0
- package/src/surfaces/settings-locales.json +420 -0
- package/src/surfaces/settings-locales.ts +137 -0
- package/src/surfaces/settings-overview.json +423 -0
- package/src/surfaces/settings-overview.ts +218 -0
- package/src/surfaces/settings-packages.json +549 -0
- package/src/surfaces/settings-packages.ts +158 -0
- package/src/surfaces/settings-pane.json +147 -0
- package/src/surfaces/settings-pane.ts +150 -0
- package/src/surfaces/settings-rawjson.json +104 -0
- package/src/surfaces/settings-rawjson.ts +107 -0
- package/src/surfaces/shell.json +99 -0
- package/src/surfaces/shell.ts +30 -0
- package/src/surfaces/slash-menu.json +180 -0
- package/src/surfaces/slash-menu.ts +272 -0
- package/src/surfaces/statements.json +607 -0
- package/src/surfaces/statements.ts +238 -0
- package/src/surfaces/statusbar.json +94 -0
- package/src/{panels → surfaces}/statusbar.ts +163 -90
- package/src/surfaces/style-panel.json +1643 -0
- package/src/surfaces/style-panel.ts +338 -0
- package/src/surfaces/stylebook-chrome.json +122 -0
- package/src/surfaces/stylebook-chrome.ts +122 -0
- package/src/surfaces/tab-strip.json +448 -0
- package/src/surfaces/tab-strip.ts +200 -0
- package/src/surfaces/target-line.json +419 -0
- package/src/surfaces/target-line.ts +349 -0
- package/src/surfaces/toasts.json +189 -0
- package/src/surfaces/welcome.json +571 -0
- package/src/surfaces/welcome.ts +338 -0
- package/src/tabs/project-config.ts +71 -15
- package/src/tabs/tab.ts +52 -1
- package/src/types.ts +49 -3
- package/src/ui/ai-credentials-form.ts +104 -100
- package/src/ui/ai-managed-connect.ts +116 -49
- package/src/ui/ai-model-picker.ts +102 -47
- package/src/ui/cf-account-picker.ts +135 -0
- package/src/ui/color-selector.ts +80 -301
- package/src/ui/dynamic-slot.ts +43 -283
- package/src/ui/expression-editor.ts +797 -576
- package/src/ui/field-input.ts +8 -181
- package/src/ui/form-controls.ts +838 -366
- package/src/ui/formula-chips.ts +80 -85
- package/src/ui/kit.ts +33 -0
- package/src/ui/layers.ts +293 -593
- package/src/ui/media-picker.ts +203 -284
- package/src/ui/panel-resize.ts +251 -64
- package/src/ui/popover-surface.ts +153 -0
- package/src/ui/progress-modal.ts +22 -60
- package/src/ui/regions.ts +13 -7
- package/src/ui/schema-form.ts +906 -440
- package/src/ui/surface.ts +122 -0
- package/src/ui/unit-selector.ts +15 -131
- package/src/ui/value-source.ts +14 -0
- package/src/ui/virtual-window.ts +88 -9
- package/src/utils/canvas-media.ts +72 -0
- package/src/utils/edit-display.ts +7 -2
- package/src/utils/element-selectors.ts +69 -0
- package/src/utils/link-target.ts +2 -2
- package/src/utils/studio-utils.ts +0 -10
- package/src/view.ts +15 -0
- package/src/workspace/pane-derive.ts +36 -14
- package/src/workspace/workspace.ts +15 -6
- package/styles/canvas.css +72 -467
- package/styles/forced-colors.css +48 -82
- package/styles/forced-colors.json +41 -0
- package/styles/inspector.css +2 -1301
- package/styles/overlays.css +96 -2823
- package/styles/panels.css +6 -1423
- package/styles/shell-frame.css +272 -0
- package/styles/shell-frame.json +227 -0
- package/styles/shell.css +0 -1532
- package/styles/tokens.css +65 -136
- package/styles/tokens.json +84 -0
- package/dist/chunks/Overlay.dev-723bv0df.js +0 -23
- package/dist/chunks/adapter-jkcyhgtr.js +0 -14
- package/dist/chunks/cf-settings-45fgyx8y.js +0 -21
- package/dist/chunks/components-zmx10t62.js +0 -21
- package/dist/chunks/content-source-t88vb2dr.js +0 -49
- package/dist/chunks/convert-to-repeater-dhw1nrz9.js +0 -268
- package/dist/chunks/editor-cptq5jp1.js +0 -37
- package/dist/chunks/entry-commands-6z6bhxg0.js +0 -46
- package/dist/chunks/extension-sections-3ydgjbdy.js +0 -311
- package/dist/chunks/file-ops-rskmhxyq.js +0 -48
- package/dist/chunks/files-0cratsr0.js +0 -92
- package/dist/chunks/flow-qbfgrpeh.js +0 -634
- package/dist/chunks/focus-trap.esm-ggawf1hy.js +0 -1024
- package/dist/chunks/focus-visible-6eg70z18.js +0 -167
- package/dist/chunks/format-host-tgcmfs4p.js +0 -43
- package/dist/chunks/fs-events-hrrg328g.js +0 -21
- package/dist/chunks/git-panel-0yywyk76.js +0 -58
- package/dist/chunks/index-zqxmqxmh.js +0 -109
- package/dist/chunks/jx-validate-8q2g05x1.js +0 -19
- package/dist/chunks/layers-panel-z3tqe5cd.js +0 -67
- package/dist/chunks/layers-q75tj2mf.js +0 -45
- package/dist/chunks/lit-html-j055mkh8.js +0 -22
- package/dist/chunks/monaco-buffer-dqw0xxpx.js +0 -25
- package/dist/chunks/notify-yjm79n4s.js +0 -30
- package/dist/chunks/parse-24d0gay3.js +0 -19
- package/dist/chunks/platform-ba1j1gbh.js +0 -16
- package/dist/chunks/publish-panel-54jvhskq.js +0 -28
- package/dist/chunks/quick-search-cgfmjwq5.js +0 -65
- package/dist/chunks/references-3qx8fkyp.js +0 -29
- package/dist/chunks/right-panel-cqp8bc4v.js +0 -46
- package/dist/chunks/section-registry-sx1ykvkw.js +0 -30
- package/dist/chunks/sp-overlay.dev-yztmtrs1.js +0 -18
- package/dist/chunks/sp-popover.dev-n2etmqdp.js +0 -9
- package/dist/chunks/sp-progress-circle.dev-hryhj0es.js +0 -15
- package/dist/chunks/sp-tooltip.dev-xcvpnqr0.js +0 -15
- package/dist/chunks/sp-tray.dev-tkbscm06.js +0 -199
- package/dist/chunks/studio-0a5qrh01.js +0 -3
- package/dist/chunks/studio-18j3bmcz.js +0 -14
- package/dist/chunks/studio-1hbqnt19.js +0 -1823
- package/dist/chunks/studio-4rzyrtjz.js +0 -426
- package/dist/chunks/studio-5rywrkxz.js +0 -1903
- package/dist/chunks/studio-7afd21nw.js +0 -67
- package/dist/chunks/studio-7nte2hj4.js +0 -613
- package/dist/chunks/studio-8jpzqk5s.js +0 -128
- package/dist/chunks/studio-8q517dfr.js +0 -24
- package/dist/chunks/studio-9c4k4vhv.js +0 -357
- package/dist/chunks/studio-9n4mrmnb.js +0 -184
- package/dist/chunks/studio-a0tswy0w.js +0 -58
- package/dist/chunks/studio-ahjfdy6e.js +0 -387
- package/dist/chunks/studio-ahnzd9rg.js +0 -23
- package/dist/chunks/studio-bw5dz6km.js +0 -608
- package/dist/chunks/studio-cb12yz9w.js +0 -15055
- package/dist/chunks/studio-d1ks410h.js +0 -175
- package/dist/chunks/studio-eqq1w638.js +0 -113
- package/dist/chunks/studio-ex8zyp98.js +0 -1813
- package/dist/chunks/studio-h4rxscfc.js +0 -10
- package/dist/chunks/studio-kyh9avvv.js +0 -28
- package/dist/chunks/studio-kyk2v92a.js +0 -659
- package/dist/chunks/studio-m3hwn7y1.js +0 -120
- package/dist/chunks/studio-mmv72a27.js +0 -4344
- package/dist/chunks/studio-n8b9wqwy.js +0 -291
- package/dist/chunks/studio-pdfjntbk.js +0 -6939
- package/dist/chunks/studio-qq6jym04.js +0 -53
- package/dist/chunks/studio-r1r7afxx.js +0 -1066
- package/dist/chunks/studio-rdx8jcxy.js +0 -83
- package/dist/chunks/studio-rn9ta2mz.js +0 -111
- package/dist/chunks/studio-t7qb9db8.js +0 -665
- package/dist/chunks/studio-tmc5emrw.js +0 -8
- package/dist/chunks/studio-txwkm6p9.js +0 -12
- package/dist/chunks/studio-v38hmvx1.js +0 -390
- package/dist/chunks/studio-vadzgkrz.js +0 -318
- package/dist/chunks/studio-wx5609xd.js +0 -341
- package/dist/chunks/studio-z6nw2ek2.js +0 -18
- package/dist/chunks/studio-zczps70q.js +0 -378
- package/dist/chunks/workspace-xpres40v.js +0 -89
- package/src/panels/activity-bar.ts +0 -251
- package/src/panels/panel-scheduler.ts +0 -219
- package/src/panels/style-inputs.ts +0 -237
- package/src/panels/target-line.ts +0 -274
- package/src/panels/welcome-screen.ts +0 -346
- package/src/ui/button-group.ts +0 -102
- package/src/ui/choice-field.ts +0 -72
- package/src/ui/field-row.ts +0 -249
- package/src/ui/formula-palette.ts +0 -213
- package/src/ui/icons.ts +0 -52
- package/src/ui/jx-theme.ts +0 -130
- package/src/ui/spectrum.ts +0 -340
- package/src/ui/value-selector.ts +0 -174
- package/src/ui/widgets.ts +0 -172
- /package/dist/chunks/{javascript-s56a8dpk.css → javascript-4abzjcy9.css} +0 -0
- /package/dist/chunks/{jsonMode-zr9sw0c7.css → jsonMode-vvmpmk34.css} +0 -0
- /package/dist/chunks/{monaco-setup-pav68602.css → monaco-setup-8vbyqnhr.css} +0 -0
- /package/dist/chunks/{tsMode-ef187txx.css → tsMode-hnxxb73h.css} +0 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
/**
|
|
3
|
+
* The Site head settings section: the project-level Google Fonts, and the raw `$head` tags every
|
|
4
|
+
* page emits.
|
|
5
|
+
*
|
|
6
|
+
* The adapter owns the decisions — which field set an entry needs, when a write reaches disk, what
|
|
7
|
+
* "remove this font" also has to remove — and `settings-head.json` draws them. That is the whole
|
|
8
|
+
* shape of the conversion this replaced: `settings/head-editor.ts` built its markup from the
|
|
9
|
+
* `$head` array on every pass and re-entered itself (`renderHeadEditor(container)`) after each
|
|
10
|
+
* structural edit, so adding one entry rebuilt every field in the section. The rows are a
|
|
11
|
+
* projection now, keyed per entry, so an added tag appears and nothing else is touched.
|
|
12
|
+
*
|
|
13
|
+
* **The `$head` array is edited in place, and that is the contract, not an implementation detail.**
|
|
14
|
+
* `projectState.projectConfig.$head` is the array the rest of Studio reads; a copy would be a
|
|
15
|
+
* second source of truth that the next `commitProjectConfig` would overwrite. So every mutation
|
|
16
|
+
* here is `push`/`splice` on that same array, followed by the one commit call.
|
|
17
|
+
*
|
|
18
|
+
* @docs studio/projects/settings
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import { reactive } from "../reactivity";
|
|
22
|
+
import { projectState } from "../store";
|
|
23
|
+
import { updateSiteConfig } from "../site-context";
|
|
24
|
+
import {
|
|
25
|
+
buildGoogleFontUrl,
|
|
26
|
+
cleanupGoogleFontPreconnects,
|
|
27
|
+
ensureGoogleFontPreconnects,
|
|
28
|
+
extractFontFamily,
|
|
29
|
+
isGoogleFontEntry,
|
|
30
|
+
} from "../utils/google-fonts";
|
|
31
|
+
import { mountSurface, registerSurface } from "../ui/surface";
|
|
32
|
+
import headDoc from "./settings-head.json";
|
|
33
|
+
import type { JxDocument, JxHeadEntry, ProjectConfig } from "@jxsuite/schema/types";
|
|
34
|
+
import type { SurfaceHandle } from "../ui/surface";
|
|
35
|
+
|
|
36
|
+
registerSurface("settings-head", headDoc as unknown as JxDocument);
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* How long a keystroke waits before it is written.
|
|
40
|
+
*
|
|
41
|
+
* Every field commit is a `project.json` write, and the two body fields commit on `input` — one
|
|
42
|
+
* write per keystroke without this. The lit editor debounced per ENTRY, with one timer shared by
|
|
43
|
+
* that entry's fields, so editing `rel` and then `href` inside the window cancelled the first write
|
|
44
|
+
* outright; the timers are per field here, which is why each edit lands.
|
|
45
|
+
*/
|
|
46
|
+
const EDIT_DEBOUNCE_MS = 300;
|
|
47
|
+
|
|
48
|
+
/** One `$head` entry as the document draws it: which fields, and what is in them. */
|
|
49
|
+
interface HeadRow extends Record<string, unknown> {
|
|
50
|
+
id: string;
|
|
51
|
+
/** The tag name, drawn as `<link>` and named in the delete button. */
|
|
52
|
+
tag: string;
|
|
53
|
+
/**
|
|
54
|
+
* Which field set to draw. `script-inline` is a script with no `src` — the one entry kind whose
|
|
55
|
+
* shape depends on a value rather than on its tag.
|
|
56
|
+
*/
|
|
57
|
+
kind: "link" | "meta" | "script" | "script-inline" | "style" | "none";
|
|
58
|
+
rel: string;
|
|
59
|
+
href: string;
|
|
60
|
+
name: string;
|
|
61
|
+
content: string;
|
|
62
|
+
src: string;
|
|
63
|
+
body: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** One Google Fonts stylesheet link, by the family it loads. */
|
|
67
|
+
interface FontRow extends Record<string, unknown> {
|
|
68
|
+
id: string;
|
|
69
|
+
family: string;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** One of the four tags the section can add, and the button that adds it. */
|
|
73
|
+
interface AddTag extends Record<string, unknown> {
|
|
74
|
+
tag: string;
|
|
75
|
+
label: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
interface HeadScope extends Record<string, unknown> {
|
|
79
|
+
rows: HeadRow[];
|
|
80
|
+
fonts: FontRow[];
|
|
81
|
+
/**
|
|
82
|
+
* Whether to draw the font list or the empty line, as a `$switch` discriminant. Two states, not a
|
|
83
|
+
* length test: the document says "No fonts imported." rather than drawing an empty box.
|
|
84
|
+
*/
|
|
85
|
+
fontsState: "empty" | "listed";
|
|
86
|
+
/** What is in the family field. The document reads it back, so clearing it is an assignment. */
|
|
87
|
+
fontDraft: string;
|
|
88
|
+
tags: AddTag[];
|
|
89
|
+
add: (tag: string) => void;
|
|
90
|
+
remove: (id: string) => void;
|
|
91
|
+
edit: (id: string, key: string, value: string) => void;
|
|
92
|
+
draftFont: (value: string) => void;
|
|
93
|
+
addFont: () => void;
|
|
94
|
+
removeFont: (id: string) => void;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const ADD_TAGS: AddTag[] = [
|
|
98
|
+
{ label: "+ Link", tag: "link" },
|
|
99
|
+
{ label: "+ Meta", tag: "meta" },
|
|
100
|
+
{ label: "+ Script", tag: "script" },
|
|
101
|
+
{ label: "+ Style", tag: "style" },
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
// ─── The entries, and the identity a row is keyed by ──────────────────────────
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* A stable id per entry OBJECT, so the repeater can key on it.
|
|
108
|
+
*
|
|
109
|
+
* A `$head` entry carries nothing unique — two `<meta>` tags may be identical until they are filled
|
|
110
|
+
* in — and keying on the index would rebuild every row below a deletion, taking the caret out of
|
|
111
|
+
* whatever was being typed. A `WeakMap` gives each object one id for as long as it exists and
|
|
112
|
+
* forgets it with the entry.
|
|
113
|
+
*/
|
|
114
|
+
const ids = new WeakMap<JxHeadEntry, string>();
|
|
115
|
+
let minted = 0;
|
|
116
|
+
|
|
117
|
+
function idOf(entry: JxHeadEntry): string {
|
|
118
|
+
let id = ids.get(entry);
|
|
119
|
+
if (id === undefined) {
|
|
120
|
+
minted += 1;
|
|
121
|
+
id = `head-${minted}`;
|
|
122
|
+
ids.set(entry, id);
|
|
123
|
+
}
|
|
124
|
+
return id;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** The config object the entries last came from, so a project switch does not inherit them. */
|
|
128
|
+
let _config: ProjectConfig | null = null;
|
|
129
|
+
/** The `$head` array being edited. */
|
|
130
|
+
let _entries: JxHeadEntry[] = [];
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* The `$head` array this section edits — the project's own whenever it declares one.
|
|
134
|
+
*
|
|
135
|
+
* A project with no `$head` yet is the case worth stating: the array is held here until the first
|
|
136
|
+
* commit lands one on the config, because the write is asynchronous and re-reading the config in
|
|
137
|
+
* between would answer "no entries" and lose the tag that was just added.
|
|
138
|
+
*/
|
|
139
|
+
function entries(): JxHeadEntry[] {
|
|
140
|
+
const config = (projectState?.projectConfig ?? null) as ProjectConfig | null;
|
|
141
|
+
if (config !== _config) {
|
|
142
|
+
_config = config;
|
|
143
|
+
_entries = [];
|
|
144
|
+
/* The half-typed family goes with the project it was typed into. The section is a singleton —
|
|
145
|
+
one scope for every project this window opens — so a draft nobody submitted would otherwise
|
|
146
|
+
be sitting in the field of the NEXT project, and the Add button would take it. */
|
|
147
|
+
if (_scope) {
|
|
148
|
+
_scope.fontDraft = "";
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const declared = config?.$head;
|
|
152
|
+
if (Array.isArray(declared)) {
|
|
153
|
+
_entries = declared as JxHeadEntry[];
|
|
154
|
+
}
|
|
155
|
+
return _entries;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** The entry a row id names, or `undefined` when it has since been removed. */
|
|
159
|
+
function entryFor(id: string): JxHeadEntry | undefined {
|
|
160
|
+
return entries().find((entry) => ids.get(entry) === id);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** A `$head` attribute as a field's text: anything that is not a string has none to show. */
|
|
164
|
+
function text(value: unknown): string {
|
|
165
|
+
return typeof value === "string" ? value : "";
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ─── The projection ───────────────────────────────────────────────────────────
|
|
169
|
+
|
|
170
|
+
/** One entry as the document draws it. */
|
|
171
|
+
function row(entry: JxHeadEntry): HeadRow {
|
|
172
|
+
const attributes = entry.attributes ?? {};
|
|
173
|
+
const src = text(attributes["src"]);
|
|
174
|
+
const tag = String(entry.tagName ?? "");
|
|
175
|
+
const kinds: Record<string, HeadRow["kind"]> = {
|
|
176
|
+
link: "link",
|
|
177
|
+
meta: "meta",
|
|
178
|
+
script: src === "" ? "script-inline" : "script",
|
|
179
|
+
style: "style",
|
|
180
|
+
};
|
|
181
|
+
return {
|
|
182
|
+
body: text(entry.textContent),
|
|
183
|
+
content: text(attributes["content"]),
|
|
184
|
+
href: text(attributes["href"]),
|
|
185
|
+
id: idOf(entry),
|
|
186
|
+
kind: kinds[tag] ?? "none",
|
|
187
|
+
name: text(attributes["name"]),
|
|
188
|
+
rel: text(attributes["rel"]),
|
|
189
|
+
src,
|
|
190
|
+
tag,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** The section, as the document reads it, from the project config as it stands now. */
|
|
195
|
+
function project(): Pick<HeadScope, "rows" | "fonts" | "fontsState"> {
|
|
196
|
+
const list = entries();
|
|
197
|
+
const fonts = list.filter((entry) => isGoogleFontEntry(entry));
|
|
198
|
+
return {
|
|
199
|
+
fonts: fonts.map((entry) => ({
|
|
200
|
+
family: extractFontFamily(text(entry.attributes?.["href"])),
|
|
201
|
+
id: idOf(entry),
|
|
202
|
+
})),
|
|
203
|
+
fontsState: fonts.length === 0 ? "empty" : "listed",
|
|
204
|
+
rows: list.map((entry) => row(entry)),
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// ─── Writing ──────────────────────────────────────────────────────────────────
|
|
209
|
+
|
|
210
|
+
/** Commit the whole `$head` array through the project-config chokepoint. */
|
|
211
|
+
function save(): void {
|
|
212
|
+
void updateSiteConfig({ $head: entries() });
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Field edits waiting out {@link EDIT_DEBOUNCE_MS}, one per field. */
|
|
216
|
+
const _pending = new Map<string, { commit: () => void; timer: ReturnType<typeof setTimeout> }>();
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Write every waiting edit now.
|
|
220
|
+
*
|
|
221
|
+
* Called before each structural change, and it is not housekeeping: a structural change recomputes
|
|
222
|
+
* the rows, so an edit still in flight would be drawn back at its OLD value and then written at its
|
|
223
|
+
* new one — the field and the file disagreeing, with the reader watching their typing revert.
|
|
224
|
+
*/
|
|
225
|
+
function flushEdits(): void {
|
|
226
|
+
for (const pending of _pending.values()) {
|
|
227
|
+
clearTimeout(pending.timer);
|
|
228
|
+
pending.commit();
|
|
229
|
+
}
|
|
230
|
+
_pending.clear();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** Put a value on the entry, choosing the attribute or the text body the way `$head` means it. */
|
|
234
|
+
function write(id: string, key: string, value: string): void {
|
|
235
|
+
const entry = entryFor(id);
|
|
236
|
+
if (!entry) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (key === "content" && (entry.tagName === "script" || entry.tagName === "style")) {
|
|
240
|
+
entry.textContent = value;
|
|
241
|
+
} else {
|
|
242
|
+
entry.attributes ??= {};
|
|
243
|
+
entry.attributes[key] = value;
|
|
244
|
+
}
|
|
245
|
+
save();
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// ─── The scope ────────────────────────────────────────────────────────────────
|
|
249
|
+
|
|
250
|
+
let _scope: HeadScope | null = null;
|
|
251
|
+
|
|
252
|
+
/** Recompute the projection; the surface follows. */
|
|
253
|
+
function refresh(): void {
|
|
254
|
+
Object.assign(state(), project());
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** The reactive scope the surface reads, made once. */
|
|
258
|
+
function state(): HeadScope {
|
|
259
|
+
_scope ??= reactive<HeadScope>({
|
|
260
|
+
add(tag: string) {
|
|
261
|
+
flushEdits();
|
|
262
|
+
const attributes: Record<string, string | boolean> = {};
|
|
263
|
+
const entry: JxHeadEntry = { attributes, tagName: tag };
|
|
264
|
+
if (tag === "link") {
|
|
265
|
+
attributes["rel"] = "stylesheet";
|
|
266
|
+
attributes["href"] = "";
|
|
267
|
+
} else if (tag === "meta") {
|
|
268
|
+
attributes["name"] = "";
|
|
269
|
+
attributes["content"] = "";
|
|
270
|
+
} else if (tag === "script") {
|
|
271
|
+
attributes["src"] = "";
|
|
272
|
+
} else if (tag === "style") {
|
|
273
|
+
entry.textContent = "";
|
|
274
|
+
}
|
|
275
|
+
entries().push(entry);
|
|
276
|
+
save();
|
|
277
|
+
refresh();
|
|
278
|
+
},
|
|
279
|
+
addFont() {
|
|
280
|
+
flushEdits();
|
|
281
|
+
const family = state().fontDraft.trim();
|
|
282
|
+
if (family === "") {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const list = entries();
|
|
286
|
+
ensureGoogleFontPreconnects(list);
|
|
287
|
+
list.push({
|
|
288
|
+
attributes: { href: buildGoogleFontUrl(family), rel: "stylesheet" },
|
|
289
|
+
tagName: "link",
|
|
290
|
+
});
|
|
291
|
+
state().fontDraft = "";
|
|
292
|
+
save();
|
|
293
|
+
refresh();
|
|
294
|
+
},
|
|
295
|
+
draftFont(value: string) {
|
|
296
|
+
state().fontDraft = value;
|
|
297
|
+
},
|
|
298
|
+
edit(id: string, key: string, value: string) {
|
|
299
|
+
const token = `${id}:${key}`;
|
|
300
|
+
clearTimeout(_pending.get(token)?.timer);
|
|
301
|
+
const commit = (): void => {
|
|
302
|
+
_pending.delete(token);
|
|
303
|
+
write(id, key, value);
|
|
304
|
+
};
|
|
305
|
+
_pending.set(token, { commit, timer: setTimeout(commit, EDIT_DEBOUNCE_MS) });
|
|
306
|
+
},
|
|
307
|
+
fonts: [],
|
|
308
|
+
fontDraft: "",
|
|
309
|
+
fontsState: "empty",
|
|
310
|
+
remove(id: string) {
|
|
311
|
+
flushEdits();
|
|
312
|
+
const list = entries();
|
|
313
|
+
const index = list.findIndex((entry) => ids.get(entry) === id);
|
|
314
|
+
if (index === -1) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
list.splice(index, 1);
|
|
318
|
+
save();
|
|
319
|
+
refresh();
|
|
320
|
+
},
|
|
321
|
+
removeFont(id: string) {
|
|
322
|
+
flushEdits();
|
|
323
|
+
const list = entries();
|
|
324
|
+
const index = list.findIndex((entry) => ids.get(entry) === id);
|
|
325
|
+
if (index === -1) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
list.splice(index, 1);
|
|
329
|
+
/* The preconnects go with the last font, and only with the last: `cleanupGoogleFontPreconnects`
|
|
330
|
+
answers with a new array when it dropped something, which is copied back into the array the
|
|
331
|
+
project holds rather than replacing it. */
|
|
332
|
+
const cleaned = cleanupGoogleFontPreconnects(list);
|
|
333
|
+
if (cleaned !== list) {
|
|
334
|
+
list.length = 0;
|
|
335
|
+
list.push(...cleaned);
|
|
336
|
+
}
|
|
337
|
+
save();
|
|
338
|
+
refresh();
|
|
339
|
+
},
|
|
340
|
+
rows: [],
|
|
341
|
+
tags: ADD_TAGS,
|
|
342
|
+
}) as HeadScope;
|
|
343
|
+
return _scope;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// ─── The mount ────────────────────────────────────────────────────────────────
|
|
347
|
+
|
|
348
|
+
let _host: HTMLElement | null = null;
|
|
349
|
+
let _mount: Promise<SurfaceHandle> | null = null;
|
|
350
|
+
let _handle: SurfaceHandle | null = null;
|
|
351
|
+
|
|
352
|
+
/** Take the surface down and forget its host. */
|
|
353
|
+
function dispose(): void {
|
|
354
|
+
const pending = _mount;
|
|
355
|
+
_mount = null;
|
|
356
|
+
if (_handle) {
|
|
357
|
+
_handle.dispose();
|
|
358
|
+
_handle = null;
|
|
359
|
+
} else if (pending) {
|
|
360
|
+
void pending.then((handle) => {
|
|
361
|
+
handle.dispose();
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
_host = null;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Draw the Site head section into `container`, or bring the one already there up to date.
|
|
369
|
+
*
|
|
370
|
+
* This is the `render` the settings registry holds (`settings/section-registry.ts`), and the pane
|
|
371
|
+
* calls it again on every registry change with the same container — so a mount still standing is
|
|
372
|
+
* only refreshed, and one whose root has left the container is disposed and remade.
|
|
373
|
+
*
|
|
374
|
+
* @param {HTMLElement} container
|
|
375
|
+
*/
|
|
376
|
+
export function renderHeadEditor(container: HTMLElement): void {
|
|
377
|
+
refresh();
|
|
378
|
+
if (_host === container && _handle?.root.parentNode === container) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
if (_mount !== null && _host === container && _handle === null) {
|
|
382
|
+
// Still mounting into this very container.
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
dispose();
|
|
386
|
+
_host = container;
|
|
387
|
+
container.textContent = "";
|
|
388
|
+
const pending = mountSurface("settings-head", state(), container);
|
|
389
|
+
_mount = pending;
|
|
390
|
+
void pending.then((handle) => {
|
|
391
|
+
if (_mount === pending) {
|
|
392
|
+
_handle = handle;
|
|
393
|
+
} else {
|
|
394
|
+
handle.dispose();
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
}
|