@jxsuite/studio 4.1.0 → 5.1.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-n6tfwnda.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-qwkm9zrf.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-vj72gqtq.js +20 -0
- package/dist/chunks/content-source-5mex4x1h.js +46 -0
- package/dist/chunks/convert-to-repeater-n64h8znc.js +639 -0
- package/dist/chunks/dialog-s890b918.js +85 -0
- package/dist/chunks/editor-3qhbg51x.js +35 -0
- package/dist/chunks/entry-commands-234hjnqw.js +42 -0
- package/dist/chunks/extension-sections-3hpcambp.js +651 -0
- package/dist/chunks/file-ops-8yhd83xr.js +47 -0
- package/dist/chunks/files-hnxqxtsg.js +72 -0
- package/dist/chunks/format-host-779sfp2n.js +40 -0
- package/dist/chunks/fs-events-b88z7g4h.js +18 -0
- package/dist/chunks/git-panel-xwj8fpab.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-syr0f9sb.js +115 -0
- package/dist/chunks/{index-wcnt3r9g.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-ff81wthn.js +30 -0
- package/dist/chunks/layers-panel-pnnghw12.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-cqhhxhhe.js +33 -0
- package/dist/chunks/menu-9p2w46gj.js +15 -0
- package/dist/chunks/menu-q99sy9rf.js +285 -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-vx9bhp1d.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-5zt840sy.js +27 -0
- package/dist/chunks/quick-search-3748564r.js +45 -0
- package/dist/chunks/references-qvvxej7h.js +26 -0
- package/dist/chunks/right-panel-eccz92qt.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-kryvsw6j.js → studio-1k325pwf.js} +48 -48
- package/dist/chunks/{studio-b55y6ewx.js → studio-1knfqgy7.js} +58 -58
- package/dist/chunks/{studio-2b946z26.js → studio-1z1kcjv4.js} +3628 -6095
- package/dist/chunks/studio-3773086z.js +111 -0
- package/dist/chunks/{studio-4r1pv6zf.js → studio-38emantv.js} +22 -5
- package/dist/chunks/{studio-x813zp48.js → studio-3rz5md06.js} +30 -30
- package/dist/chunks/{studio-ynxwkrzd.js → studio-4wbb9ct0.js} +1953 -1785
- package/dist/chunks/studio-5te5tqng.js +81 -0
- package/dist/chunks/studio-5wt9nvhd.js +4763 -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-gcye7qka.js → studio-7e11jpa9.js} +21 -21
- package/dist/chunks/{studio-q7v10cg2.js → studio-7r42c6ca.js} +17 -7
- package/dist/chunks/studio-7xnmgv66.js +13615 -0
- package/dist/chunks/studio-8scdew0e.js +258 -0
- package/dist/chunks/{studio-fbf92ckf.js → studio-93zafjcm.js} +275 -163
- package/dist/chunks/{studio-dg7zyt5x.js → studio-98b3z07n.js} +1 -1
- package/dist/chunks/studio-a79k90n9.js +1162 -0
- package/dist/chunks/studio-aj37eer3.js +422 -0
- package/dist/chunks/studio-b0k5tqgp.js +2432 -0
- package/dist/chunks/studio-b4s9eykd.js +2811 -0
- package/dist/chunks/{studio-f3wqjtk5.js → studio-d0300636.js} +5076 -18
- package/dist/chunks/{studio-b9b6t1dg.js → studio-e1f24eff.js} +5664 -5666
- package/dist/chunks/studio-e1pgga3k.js +839 -0
- package/dist/chunks/{studio-g1wdche0.js → studio-esrxgwh6.js} +80 -80
- package/dist/chunks/{studio-q43a5y9h.js → studio-g3jevyjt.js} +16 -16
- package/dist/chunks/studio-gb13095a.js +2806 -0
- package/dist/chunks/{studio-3n4ndrzh.js → studio-h4nvnjvz.js} +303 -303
- package/dist/chunks/{studio-dm19q43r.js → studio-hhvs4sdg.js} +10 -10
- package/dist/chunks/{studio-x4qkdat5.js → studio-js8nv53n.js} +1749 -2481
- package/dist/chunks/{studio-qjy2z9bv.js → studio-jxp12rnj.js} +32 -137
- package/dist/chunks/{studio-trxrabqf.js → studio-k75n7vhp.js} +527 -283
- package/dist/chunks/{studio-q9jd1a60.js → studio-kcgff4r0.js} +15 -18
- package/dist/chunks/studio-kkqkcp3d.js +17668 -0
- package/dist/chunks/studio-mhhyamxf.js +763 -0
- package/dist/chunks/{studio-cft9r4r7.js → studio-nq5yf5mp.js} +22 -22
- package/dist/chunks/{studio-685s0ytq.js → studio-nqgawfks.js} +572 -572
- package/dist/chunks/studio-nzzpvzx9.js +185 -0
- package/dist/chunks/{studio-xrapxwwc.js → studio-p1dw8wfw.js} +55 -29
- package/dist/chunks/{studio-3bqpr0zh.js → studio-pxbgypmg.js} +299 -110
- package/dist/chunks/studio-q0a3yk4n.js +33 -0
- package/dist/chunks/{studio-wcy8trfx.js → studio-q3x06vmj.js} +23 -22
- package/dist/chunks/{studio-6yw4y3my.js → studio-qhhm6hbt.js} +8 -8
- package/dist/chunks/studio-qk4bfsq2.js +362 -0
- package/dist/chunks/{studio-msd847zn.js → studio-qk90fgqm.js} +361 -90
- package/dist/chunks/{studio-jkftxyvz.js → studio-r6nvacqs.js} +5861 -2154
- package/dist/chunks/{studio-53n8bp04.js → studio-r6xmmtfh.js} +1 -1
- package/dist/chunks/{studio-tvgyw9xw.js → studio-rnyf3f8e.js} +83 -250
- package/dist/chunks/studio-rs76k67r.js +12 -0
- package/dist/chunks/studio-sbjyc8bt.js +954 -0
- package/dist/chunks/{studio-1wagb550.js → studio-syg2tadj.js} +11 -11
- package/dist/chunks/{studio-t5wqwzdh.js → studio-tjjk7jvk.js} +1 -1
- package/dist/chunks/studio-tqgryxwg.js +1171 -0
- package/dist/chunks/studio-try13h8c.js +8448 -0
- package/dist/chunks/studio-vfq8qpjt.js +1219 -0
- package/dist/chunks/studio-vhv5tgxm.js +51 -0
- package/dist/chunks/{studio-ahn3pdgx.js → studio-vw7mzp6z.js} +52 -38
- package/dist/chunks/studio-wqpngpsk.js +174 -0
- package/dist/chunks/studio-wqz6dggm.js +1356 -0
- package/dist/chunks/{studio-92ab2jqe.js → studio-y9zedyjn.js} +14 -14
- package/dist/chunks/studio-yxa81f45.js +12 -0
- package/dist/chunks/studio-zdn2g6dt.js +148 -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-t55jdjbx.js +69 -0
- package/dist/chunks/{ws-client-6shc5rze.js → ws-client-ny4zc51r.js} +20 -22
- package/dist/iframe-entry.js +1873 -673
- package/dist/studio.js +52757 -36535
- 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/index.html +1 -0
- package/package.json +18 -52
- package/src/about/about-modal.ts +72 -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 +333 -113
- 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 +404 -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 +177 -10
- package/src/commands/run-reported.ts +120 -0
- 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 +76 -49
- package/src/editor/slash-menu.ts +150 -157
- package/src/files/components.ts +39 -0
- package/src/files/file-ops.ts +117 -11
- package/src/files/files.ts +944 -660
- package/src/files/json-layout.ts +474 -0
- 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/layout.ts +2 -0
- package/src/i18n/i18n-commands.ts +137 -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 +181 -252
- package/src/new-project/location-fields.ts +93 -160
- package/src/new-project/new-project-modal.ts +376 -367
- package/src/packages/jxsuite-update.ts +76 -18
- package/src/packages/pull-package-sync.ts +5 -1
- 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 -163
- package/src/panels/ai-chat/sessions-view.ts +31 -62
- package/src/panels/ai-panel.ts +213 -185
- package/src/panels/block-action-bar.ts +444 -645
- 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 +148 -135
- package/src/panels/imports-panel.ts +388 -414
- package/src/panels/jump-bar.ts +175 -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 +181 -99
- package/src/panels/properties-panel.ts +1525 -966
- package/src/panels/provenance.ts +31 -113
- package/src/panels/quick-search.ts +223 -184
- package/src/panels/right-panel.ts +135 -169
- package/src/panels/seo-modal.ts +346 -167
- package/src/panels/settings-menu.ts +114 -661
- 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 +386 -288
- package/src/platforms/cloud.ts +106 -16
- 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 +134 -328
- package/src/services/a11y-report.ts +100 -43
- package/src/services/ai-command-tools.ts +538 -0
- package/src/services/ai-project-tools.ts +8 -2
- package/src/services/ai-session-store.ts +6 -0
- package/src/services/ai-system-prompt.ts +112 -24
- package/src/services/ai-tools.ts +36 -212
- package/src/services/ai-write-report.ts +174 -0
- package/src/services/document-assistant.ts +59 -8
- 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 +6 -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 +1 -1
- package/src/settings/preferences-dialog.ts +350 -330
- 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 +104 -69
- 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 +985 -0
- package/src/{panels/toolbar.ts → surfaces/commandbar.ts} +417 -391
- 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 +164 -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 +111 -21
- package/src/tabs/tab.ts +52 -1
- package/src/types.ts +22 -0
- package/src/ui/ai-credentials-form.ts +104 -100
- package/src/ui/ai-managed-connect.ts +54 -36
- package/src/ui/ai-model-picker.ts +75 -47
- package/src/ui/cf-account-picker.ts +76 -141
- 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 +296 -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 +75 -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 -1568
- package/styles/tokens.css +65 -136
- package/styles/tokens.json +84 -0
- package/dist/chunks/Overlay.dev-etqjwyf9.js +0 -23
- package/dist/chunks/adapter-jkcyhgtr.js +0 -14
- package/dist/chunks/cf-account-picker-en86v7x7.js +0 -163
- package/dist/chunks/cf-settings-45fgyx8y.js +0 -21
- package/dist/chunks/components-zmx10t62.js +0 -21
- package/dist/chunks/content-source-48xg86wj.js +0 -49
- package/dist/chunks/convert-to-repeater-43tfn7cs.js +0 -268
- package/dist/chunks/editor-cptq5jp1.js +0 -37
- package/dist/chunks/entry-commands-e63f1xc0.js +0 -46
- package/dist/chunks/extension-sections-txv08xxg.js +0 -311
- package/dist/chunks/file-ops-wbh4hhsx.js +0 -48
- package/dist/chunks/files-3kfkwhk4.js +0 -93
- package/dist/chunks/flow-qbfgrpeh.js +0 -634
- package/dist/chunks/focus-trap.esm-9t2drp0g.js +0 -1025
- package/dist/chunks/focus-visible-6eg70z18.js +0 -167
- package/dist/chunks/format-host-w16q81tf.js +0 -43
- package/dist/chunks/fs-events-hrrg328g.js +0 -21
- package/dist/chunks/git-panel-532whr1y.js +0 -59
- package/dist/chunks/index-zqxmqxmh.js +0 -109
- package/dist/chunks/jx-validate-8er6gbxy.js +0 -19
- package/dist/chunks/layers-panel-07hm7g5j.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-v9st96ja.js +0 -29
- package/dist/chunks/quick-search-zccjp6gv.js +0 -66
- package/dist/chunks/references-3qx8fkyp.js +0 -29
- package/dist/chunks/right-panel-vm3b6kwy.js +0 -46
- package/dist/chunks/section-registry-sx1ykvkw.js +0 -30
- package/dist/chunks/sp-overlay.dev-qgvhnxf4.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-4sastdnw.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-0bq6eh7v.js +0 -12
- package/dist/chunks/studio-18j3bmcz.js +0 -14
- package/dist/chunks/studio-1ngbejft.js +0 -181
- package/dist/chunks/studio-4b5z1x43.js +0 -424
- package/dist/chunks/studio-4n2b5gzb.js +0 -357
- package/dist/chunks/studio-4rzyrtjz.js +0 -426
- package/dist/chunks/studio-5fx3g9jg.js +0 -4325
- package/dist/chunks/studio-5myknm0a.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-950k0dx6.js +0 -6939
- package/dist/chunks/studio-9n4mrmnb.js +0 -184
- package/dist/chunks/studio-a0tswy0w.js +0 -58
- package/dist/chunks/studio-ahnzd9rg.js +0 -23
- package/dist/chunks/studio-bgxt93ga.js +0 -62
- package/dist/chunks/studio-cmb03bg5.js +0 -13890
- package/dist/chunks/studio-d1ks410h.js +0 -175
- package/dist/chunks/studio-ef49pnzx.js +0 -387
- package/dist/chunks/studio-eqq1w638.js +0 -113
- package/dist/chunks/studio-ew0djmhg.js +0 -341
- package/dist/chunks/studio-gfgb8pe6.js +0 -1652
- package/dist/chunks/studio-h4rxscfc.js +0 -10
- package/dist/chunks/studio-jc994dnr.js +0 -1066
- package/dist/chunks/studio-kyh9avvv.js +0 -28
- package/dist/chunks/studio-m3hwn7y1.js +0 -120
- package/dist/chunks/studio-mtfnaqs9.js +0 -659
- package/dist/chunks/studio-n6j9t10q.js +0 -318
- package/dist/chunks/studio-n8b9wqwy.js +0 -291
- package/dist/chunks/studio-qcy05dp8.js +0 -1743
- package/dist/chunks/studio-qq6jym04.js +0 -53
- 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-z6nw2ek2.js +0 -18
- package/dist/chunks/studio-zczps70q.js +0 -378
- package/dist/chunks/studio-zqazsct2.js +0 -1823
- package/dist/chunks/workspace-fjx52ryv.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
package/dist/iframe-entry.js
CHANGED
|
@@ -1,3 +1,35 @@
|
|
|
1
|
+
var __chunkGraphs;
|
|
2
|
+
var __chunkSeen;
|
|
3
|
+
var __chunkNonce;
|
|
4
|
+
var __preload = (id, seenOnly) => {
|
|
5
|
+
for (var [base, graph, ids] of __chunkGraphs || [])
|
|
6
|
+
for (var stack = [id], g = globalThis, d = g.document, head, j, node, k, link;j = stack.pop(); )
|
|
7
|
+
if (!__chunkSeen[j] && (node = graph[j])) {
|
|
8
|
+
__chunkSeen[j] = 1;
|
|
9
|
+
for (k = 1;k < node.length; k++)
|
|
10
|
+
stack.push(ids[node[k]]);
|
|
11
|
+
if (!seenOnly && j !== id && (head = d && d.head)) {
|
|
12
|
+
if (__chunkNonce === undefined)
|
|
13
|
+
__chunkNonce = (k = d.querySelector("meta[property=csp-nonce]")) && (k.nonce || k.getAttribute("nonce")) || "";
|
|
14
|
+
link = d.createElement("link");
|
|
15
|
+
link.rel = "modulepreload";
|
|
16
|
+
link.crossOrigin = "";
|
|
17
|
+
if (__chunkNonce)
|
|
18
|
+
link.nonce = __chunkNonce;
|
|
19
|
+
link.href = new g.URL(node[0], base);
|
|
20
|
+
head.appendChild(link);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
var __chunks = (base, ids, nodes, entry) => {
|
|
25
|
+
for (var graph = {}, i = 0;i < ids.length; i++)
|
|
26
|
+
graph[ids[i]] = nodes[i];
|
|
27
|
+
(__chunkGraphs ||= []).push([base, graph, ids]);
|
|
28
|
+
__chunkSeen ||= {};
|
|
29
|
+
__preload(ids[entry], 1);
|
|
30
|
+
};
|
|
31
|
+
__chunks(import.meta.url,["1zk4r753","a73p0pqm","eptb614w","abk6qyee","780pvfbv","3sqv46sn","xgg3kfw7","yy10wk9r","5cndyft8","sp6tna8v","47z3ytva","2r16ez41","g7nm1rgb","t0n6h2rn","wbp1cdws","xbh5bhtr","v17df7b8","anwybnkn","44ez96fc","5e7jev23","s890b918","6v2ac08j","q99sy9rf","nbyxee1y","15g3n6xv","b27vq81n"],[["./iframe-entry.js"],["./chunks/tree-a73p0pqm.js"],["./chunks/tooltip-eptb614w.js",23],["./chunks/textfield-abk6qyee.js"],["./chunks/toast-780pvfbv.js",24],["./chunks/toast-host-3sqv46sn.js",24],["./chunks/color-xgg3kfw7.js",25],["./chunks/icons-yy10wk9r.js"],["./chunks/number-field-5cndyft8.js"],["./chunks/action-group-sp6tna8v.js"],["./chunks/popover-47z3ytva.js",23],["./chunks/select-2r16ez41.js"],["./chunks/split-g7nm1rgb.js"],["./chunks/swatch-group-t0n6h2rn.js"],["./chunks/tabs-wbp1cdws.js"],["./chunks/toolbar-xbh5bhtr.js"],["./chunks/color-area-v17df7b8.js",25],["./chunks/color-field-anwybnkn.js",25,23],["./chunks/color-slider-44ez96fc.js",25],["./chunks/combobox-5e7jev23.js",23],["./chunks/dialog-s890b918.js"],["./chunks/listbox-6v2ac08j.js"],["./chunks/menu-q99sy9rf.js",23],["./chunks/iframe-entry-nbyxee1y.js"],["./chunks/iframe-entry-15g3n6xv.js"],["./chunks/iframe-entry-b27vq81n.js"]],0);
|
|
32
|
+
|
|
1
33
|
// src/canvas/iframe-channel.ts
|
|
2
34
|
var ENVELOPE = "jx:canvas";
|
|
3
35
|
function postMessageChannel(opts) {
|
|
@@ -31,6 +63,17 @@ function postMessageChannel(opts) {
|
|
|
31
63
|
};
|
|
32
64
|
}
|
|
33
65
|
|
|
66
|
+
// src/utils/geometry.ts
|
|
67
|
+
function rectOf(el) {
|
|
68
|
+
return el.getBoundingClientRect();
|
|
69
|
+
}
|
|
70
|
+
function rectOfRange(r) {
|
|
71
|
+
return r.getBoundingClientRect();
|
|
72
|
+
}
|
|
73
|
+
function elementAtPoint(x, y, root = document) {
|
|
74
|
+
return root.elementFromPoint(x, y);
|
|
75
|
+
}
|
|
76
|
+
|
|
34
77
|
// ../schema/src/guards.ts
|
|
35
78
|
function isJsonObject(value) {
|
|
36
79
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -91,7 +134,17 @@ function paramNames(parameters) {
|
|
|
91
134
|
return parameters.map((p) => typeof p === "string" ? p : p.name);
|
|
92
135
|
}
|
|
93
136
|
function isTagExpression(tagName) {
|
|
94
|
-
|
|
137
|
+
if (!isJsonObject(tagName) || !isJsonObject(tagName.$expression)) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
const expression = tagName.$expression;
|
|
141
|
+
if (expression.operator === "?:") {
|
|
142
|
+
return typeof expression.value === "string" && typeof expression.initial === "string";
|
|
143
|
+
}
|
|
144
|
+
if (expression.operator === "switch") {
|
|
145
|
+
return isJsonObject(expression.cases) && Object.values(expression.cases).every((tag) => typeof tag === "string") && typeof expression.default === "string";
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
95
148
|
}
|
|
96
149
|
function tagNameCandidates(tagName) {
|
|
97
150
|
if (typeof tagName === "string") {
|
|
@@ -292,6 +345,13 @@ class EffectScope {
|
|
|
292
345
|
function effectScope(detached) {
|
|
293
346
|
return new EffectScope(detached);
|
|
294
347
|
}
|
|
348
|
+
function onScopeDispose(fn, failSilently = false) {
|
|
349
|
+
if (activeEffectScope) {
|
|
350
|
+
activeEffectScope.cleanups.push(fn);
|
|
351
|
+
} else if (!failSilently) {
|
|
352
|
+
warn(`onScopeDispose() is called when there is no active effect scope to be associated with.`);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
295
355
|
var activeSub;
|
|
296
356
|
var pausedQueueEffects = /* @__PURE__ */ new WeakSet;
|
|
297
357
|
|
|
@@ -1127,6 +1187,7 @@ class ReadonlyReactiveHandler extends BaseReactiveHandler {
|
|
|
1127
1187
|
}
|
|
1128
1188
|
var mutableHandlers = /* @__PURE__ */ new MutableReactiveHandler;
|
|
1129
1189
|
var readonlyHandlers = /* @__PURE__ */ new ReadonlyReactiveHandler;
|
|
1190
|
+
var shallowReactiveHandlers = /* @__PURE__ */ new MutableReactiveHandler(true);
|
|
1130
1191
|
var toShallow = (value) => value;
|
|
1131
1192
|
var getProto = (v) => Reflect.getPrototypeOf(v);
|
|
1132
1193
|
function createIterableMethod(method, isReadonly2, isShallow2) {
|
|
@@ -1304,6 +1365,9 @@ function createInstrumentationGetter(isReadonly2, shallow) {
|
|
|
1304
1365
|
var mutableCollectionHandlers = {
|
|
1305
1366
|
get: /* @__PURE__ */ createInstrumentationGetter(false, false)
|
|
1306
1367
|
};
|
|
1368
|
+
var shallowCollectionHandlers = {
|
|
1369
|
+
get: /* @__PURE__ */ createInstrumentationGetter(false, true)
|
|
1370
|
+
};
|
|
1307
1371
|
var readonlyCollectionHandlers = {
|
|
1308
1372
|
get: /* @__PURE__ */ createInstrumentationGetter(true, false)
|
|
1309
1373
|
};
|
|
@@ -1338,6 +1402,9 @@ function reactive(target) {
|
|
|
1338
1402
|
}
|
|
1339
1403
|
return createReactiveObject(target, false, mutableHandlers, mutableCollectionHandlers, reactiveMap);
|
|
1340
1404
|
}
|
|
1405
|
+
function shallowReactive(target) {
|
|
1406
|
+
return createReactiveObject(target, false, shallowReactiveHandlers, shallowCollectionHandlers, shallowReactiveMap);
|
|
1407
|
+
}
|
|
1341
1408
|
function readonly(target) {
|
|
1342
1409
|
return createReactiveObject(target, true, readonlyHandlers, readonlyCollectionHandlers, readonlyMap);
|
|
1343
1410
|
}
|
|
@@ -1514,6 +1581,87 @@ function resolveAtQuery(atKey, mediaQueries) {
|
|
|
1514
1581
|
}
|
|
1515
1582
|
return null;
|
|
1516
1583
|
}
|
|
1584
|
+
function isDeclarationAtRule(atKey) {
|
|
1585
|
+
return atKey.startsWith("@position-try") || atKey.startsWith("@property") || atKey.startsWith("@font-face") || atKey.startsWith("@counter-style");
|
|
1586
|
+
}
|
|
1587
|
+
function isKeyframesAtRule(atKey) {
|
|
1588
|
+
return atKey.startsWith("@keyframes");
|
|
1589
|
+
}
|
|
1590
|
+
function resolveNestedSelector(scope, key) {
|
|
1591
|
+
const resolved = [];
|
|
1592
|
+
for (const scopePart of splitSelectorList(scope)) {
|
|
1593
|
+
for (const keyPart of splitSelectorList(key)) {
|
|
1594
|
+
resolved.push(resolveOneNestedSelector(scopePart, keyPart));
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
return resolved.join(", ");
|
|
1598
|
+
}
|
|
1599
|
+
function resolveOneNestedSelector(scope, key) {
|
|
1600
|
+
if (key.startsWith("&")) {
|
|
1601
|
+
return key.replaceAll("&", scope);
|
|
1602
|
+
}
|
|
1603
|
+
if (key.startsWith("[") || key.startsWith(":") || key.startsWith(".")) {
|
|
1604
|
+
return `${scope}${key}`;
|
|
1605
|
+
}
|
|
1606
|
+
return `${scope} ${key}`;
|
|
1607
|
+
}
|
|
1608
|
+
function splitSelectorList(selector) {
|
|
1609
|
+
const members = [];
|
|
1610
|
+
let depth = 0;
|
|
1611
|
+
let quote = null;
|
|
1612
|
+
let start = 0;
|
|
1613
|
+
for (let i = 0;i < selector.length; i += 1) {
|
|
1614
|
+
const ch = selector[i];
|
|
1615
|
+
if (quote) {
|
|
1616
|
+
if (ch === "\\") {
|
|
1617
|
+
i += 1;
|
|
1618
|
+
} else if (ch === quote) {
|
|
1619
|
+
quote = null;
|
|
1620
|
+
}
|
|
1621
|
+
continue;
|
|
1622
|
+
}
|
|
1623
|
+
if (ch === '"' || ch === "'") {
|
|
1624
|
+
quote = ch;
|
|
1625
|
+
} else if (ch === "(" || ch === "[") {
|
|
1626
|
+
depth += 1;
|
|
1627
|
+
} else if (ch === ")" || ch === "]") {
|
|
1628
|
+
depth = Math.max(0, depth - 1);
|
|
1629
|
+
} else if (ch === "," && depth === 0) {
|
|
1630
|
+
members.push(selector.slice(start, i));
|
|
1631
|
+
start = i + 1;
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
members.push(selector.slice(start));
|
|
1635
|
+
const trimmed = members.map((member) => member.trim()).filter((member) => member !== "");
|
|
1636
|
+
return trimmed.length > 0 ? trimmed : [selector];
|
|
1637
|
+
}
|
|
1638
|
+
var COMPOUND_BREAK = /[\s>+~,()]/;
|
|
1639
|
+
var LEADING_TYPE = /^[A-Za-z_\u{00A0}-\u{FFFF}][\w\u{00A0}-\u{FFFF}-]*/u;
|
|
1640
|
+
function transposeOpenAttribute(selector, options) {
|
|
1641
|
+
let out = "";
|
|
1642
|
+
let from = 0;
|
|
1643
|
+
for (;; ) {
|
|
1644
|
+
const at = selector.indexOf("[open]", from);
|
|
1645
|
+
if (at === -1) {
|
|
1646
|
+
return out + selector.slice(from);
|
|
1647
|
+
}
|
|
1648
|
+
let start = at;
|
|
1649
|
+
while (start > 0 && !COMPOUND_BREAK.test(selector[start - 1])) {
|
|
1650
|
+
start -= 1;
|
|
1651
|
+
}
|
|
1652
|
+
const type = LEADING_TYPE.exec(selector.slice(start, at))?.[0]?.toLowerCase();
|
|
1653
|
+
const dialog = type === undefined ? options.dialog === true : type === "dialog";
|
|
1654
|
+
out += selector.slice(from, at) + (dialog ? "[data-jx-dialog-open]" : "[open]");
|
|
1655
|
+
from = at + "[open]".length;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
function transposeCanvasOverlaySelector(selector, options = {}) {
|
|
1659
|
+
if (selector.includes("::backdrop")) {
|
|
1660
|
+
return null;
|
|
1661
|
+
}
|
|
1662
|
+
const transposed = selector.replaceAll(":popover-open", "[data-jx-popover-open]").replaceAll(":modal", "[data-jx-dialog-open]").replaceAll("[inert]", "[data-jx-inert]");
|
|
1663
|
+
return transposeOpenAttribute(transposed, options);
|
|
1664
|
+
}
|
|
1517
1665
|
var COLOR_SCHEME_ATTR = "data-color-scheme";
|
|
1518
1666
|
function pureSchemeOf(query) {
|
|
1519
1667
|
const m = /^\(\s*prefers-color-scheme\s*:\s*(light|dark)\s*\)$/.exec(query.trim());
|
|
@@ -1531,6 +1679,195 @@ function schemeSelectors(selector, scheme) {
|
|
|
1531
1679
|
forced: `:where(:root[${COLOR_SCHEME_ATTR}="${scheme}"]) ${selector}`
|
|
1532
1680
|
};
|
|
1533
1681
|
}
|
|
1682
|
+
function isNestedSelectorKey(key) {
|
|
1683
|
+
return key.startsWith(":") || key.startsWith(".") || key.startsWith("&") || key.startsWith("[");
|
|
1684
|
+
}
|
|
1685
|
+
function cssPropertyName(property) {
|
|
1686
|
+
return property.startsWith("--") ? property : camelToKebab(property);
|
|
1687
|
+
}
|
|
1688
|
+
function hashCss(text) {
|
|
1689
|
+
let h = 2166136261;
|
|
1690
|
+
for (let i = 0;i < text.length; i += 1) {
|
|
1691
|
+
h ^= text.charCodeAt(i);
|
|
1692
|
+
h = Math.imul(h, 16777619);
|
|
1693
|
+
}
|
|
1694
|
+
return (h >>> 0).toString(36);
|
|
1695
|
+
}
|
|
1696
|
+
function cssRuleText(conditions, selector, declarations) {
|
|
1697
|
+
const body = declarations.map(([property, value]) => `${property}: ${value}`).join("; ");
|
|
1698
|
+
let text = selector === null ? body : `${selector} { ${body} }`;
|
|
1699
|
+
for (let i = conditions.length - 1;i >= 0; i -= 1) {
|
|
1700
|
+
text = `${conditions[i]} { ${text} }`;
|
|
1701
|
+
}
|
|
1702
|
+
return text;
|
|
1703
|
+
}
|
|
1704
|
+
function cssKeyframesText(conditions, name, blocks) {
|
|
1705
|
+
const body = blocks.map(({ selector, declarations }) => `${selector} { ${declarations.map(([property, value]) => `${property}: ${value}`).join("; ")} }`).join(" ");
|
|
1706
|
+
let text = `@keyframes ${name} { ${body} }`;
|
|
1707
|
+
for (let i = conditions.length - 1;i >= 0; i -= 1) {
|
|
1708
|
+
text = `${conditions[i]} { ${text} }`;
|
|
1709
|
+
}
|
|
1710
|
+
return text;
|
|
1711
|
+
}
|
|
1712
|
+
function withoutKeyframes(block) {
|
|
1713
|
+
const keyframeKeys = Object.keys(block).filter((key) => isKeyframesAtRule(key));
|
|
1714
|
+
if (keyframeKeys.length === 0) {
|
|
1715
|
+
return block;
|
|
1716
|
+
}
|
|
1717
|
+
const rest = { ...block };
|
|
1718
|
+
for (const key of keyframeKeys) {
|
|
1719
|
+
delete rest[key];
|
|
1720
|
+
}
|
|
1721
|
+
return rest;
|
|
1722
|
+
}
|
|
1723
|
+
function compoundsOntoScope(key) {
|
|
1724
|
+
const rest = key.startsWith("&") ? key.slice(1) : key;
|
|
1725
|
+
return rest === "" || rest.startsWith(":") || rest.startsWith(".") || rest.startsWith("[");
|
|
1726
|
+
}
|
|
1727
|
+
function buildStyleRules(style, options = {}) {
|
|
1728
|
+
const {
|
|
1729
|
+
scope = null,
|
|
1730
|
+
mediaQueries = {},
|
|
1731
|
+
transposeValue = (value) => value,
|
|
1732
|
+
transposeSelector = (selector) => selector,
|
|
1733
|
+
resolveValue
|
|
1734
|
+
} = options;
|
|
1735
|
+
const rules = [];
|
|
1736
|
+
const isBlock = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && !isRef(value);
|
|
1737
|
+
const blocksOf = (key, value) => {
|
|
1738
|
+
if (isBlock(value)) {
|
|
1739
|
+
return [value];
|
|
1740
|
+
}
|
|
1741
|
+
if (!isDeclarationAtRule(key) || !Array.isArray(value) || value.length === 0) {
|
|
1742
|
+
return [];
|
|
1743
|
+
}
|
|
1744
|
+
return value.every((entry) => isBlock(entry)) ? value : [];
|
|
1745
|
+
};
|
|
1746
|
+
const declarationValue = (property, value, reactive, target) => {
|
|
1747
|
+
if (value === undefined || value === null) {
|
|
1748
|
+
return null;
|
|
1749
|
+
}
|
|
1750
|
+
if (isRef(value)) {
|
|
1751
|
+
return reactive ? resolveValue?.(property, value, target) ?? null : null;
|
|
1752
|
+
}
|
|
1753
|
+
if (typeof value === "object") {
|
|
1754
|
+
return null;
|
|
1755
|
+
}
|
|
1756
|
+
const raw = String(value);
|
|
1757
|
+
if (isTemplateString(raw)) {
|
|
1758
|
+
return reactive ? resolveValue?.(property, raw, target) ?? null : null;
|
|
1759
|
+
}
|
|
1760
|
+
return transposeValue(raw);
|
|
1761
|
+
};
|
|
1762
|
+
const declarationsOf = (node, skipSelectorKeys, reactive = true, target = "self") => {
|
|
1763
|
+
const declarations = [];
|
|
1764
|
+
for (const [key, value] of Object.entries(node)) {
|
|
1765
|
+
if (blocksOf(key, value).length > 0) {
|
|
1766
|
+
continue;
|
|
1767
|
+
}
|
|
1768
|
+
if (skipSelectorKeys && (key.startsWith("@") || isNestedSelectorKey(key))) {
|
|
1769
|
+
continue;
|
|
1770
|
+
}
|
|
1771
|
+
if (key.startsWith("$")) {
|
|
1772
|
+
continue;
|
|
1773
|
+
}
|
|
1774
|
+
const resolved = declarationValue(key, value, reactive, target);
|
|
1775
|
+
if (resolved !== null) {
|
|
1776
|
+
declarations.push([cssPropertyName(key), resolved]);
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
return declarations;
|
|
1780
|
+
};
|
|
1781
|
+
const emit = (conditions, selector, declarations, target, description) => {
|
|
1782
|
+
if (declarations.length === 0) {
|
|
1783
|
+
return;
|
|
1784
|
+
}
|
|
1785
|
+
let resolved = selector;
|
|
1786
|
+
if (resolved !== null) {
|
|
1787
|
+
const transposed = transposeSelector(resolved);
|
|
1788
|
+
if (transposed === null) {
|
|
1789
|
+
return;
|
|
1790
|
+
}
|
|
1791
|
+
resolved = transposed;
|
|
1792
|
+
}
|
|
1793
|
+
const text = cssRuleText(conditions, resolved, declarations);
|
|
1794
|
+
rules.push({
|
|
1795
|
+
text,
|
|
1796
|
+
conditions: [...conditions],
|
|
1797
|
+
selector: resolved,
|
|
1798
|
+
declarations,
|
|
1799
|
+
target,
|
|
1800
|
+
key: hashCss(text),
|
|
1801
|
+
...typeof description === "string" && description !== "" ? { description } : {}
|
|
1802
|
+
});
|
|
1803
|
+
};
|
|
1804
|
+
const emitKeyframes = (atKey, block, conditions) => {
|
|
1805
|
+
const name = atKey.slice("@keyframes".length).trim();
|
|
1806
|
+
if (name === "") {
|
|
1807
|
+
return;
|
|
1808
|
+
}
|
|
1809
|
+
const blocks = [];
|
|
1810
|
+
for (const [key, value] of Object.entries(block)) {
|
|
1811
|
+
if (!isBlock(value)) {
|
|
1812
|
+
continue;
|
|
1813
|
+
}
|
|
1814
|
+
const declarations = declarationsOf(value, true, false, "unscoped");
|
|
1815
|
+
if (declarations.length > 0) {
|
|
1816
|
+
blocks.push({ declarations, selector: key.trim() });
|
|
1817
|
+
}
|
|
1818
|
+
}
|
|
1819
|
+
if (blocks.length === 0) {
|
|
1820
|
+
return;
|
|
1821
|
+
}
|
|
1822
|
+
const text = cssKeyframesText(conditions, name, blocks);
|
|
1823
|
+
rules.push({
|
|
1824
|
+
blocks,
|
|
1825
|
+
conditions: [...conditions],
|
|
1826
|
+
declarations: [],
|
|
1827
|
+
key: hashCss(text),
|
|
1828
|
+
selector: null,
|
|
1829
|
+
target: "unscoped",
|
|
1830
|
+
text
|
|
1831
|
+
});
|
|
1832
|
+
};
|
|
1833
|
+
const walkAt = (atKey, block, selector, conditions, target) => {
|
|
1834
|
+
if (atKey === "@--") {
|
|
1835
|
+
return;
|
|
1836
|
+
}
|
|
1837
|
+
if (isDeclarationAtRule(atKey)) {
|
|
1838
|
+
emit([...conditions, atKey], null, declarationsOf(block, false, true, "unscoped"), "unscoped", block["$description"]);
|
|
1839
|
+
return;
|
|
1840
|
+
}
|
|
1841
|
+
if (isKeyframesAtRule(atKey)) {
|
|
1842
|
+
emitKeyframes(atKey, block, conditions);
|
|
1843
|
+
return;
|
|
1844
|
+
}
|
|
1845
|
+
const query = resolveAtQuery(atKey, mediaQueries);
|
|
1846
|
+
const atRule = query === null ? atKey : `@media ${query}`;
|
|
1847
|
+
const scheme = query === null ? null : pureSchemeOf(query);
|
|
1848
|
+
if (scheme !== null && selector !== null) {
|
|
1849
|
+
const { auto, forced } = schemeSelectors(selector, scheme);
|
|
1850
|
+
walk(block, auto, [...conditions, atRule], target);
|
|
1851
|
+
walk(withoutKeyframes(block), forced, conditions, target);
|
|
1852
|
+
return;
|
|
1853
|
+
}
|
|
1854
|
+
walk(block, selector, [...conditions, atRule], target);
|
|
1855
|
+
};
|
|
1856
|
+
function walk(node, selector, conditions, target) {
|
|
1857
|
+
emit(conditions, selector, declarationsOf(node, true, true, target), target, node["$description"]);
|
|
1858
|
+
for (const [key, value] of Object.entries(node)) {
|
|
1859
|
+
for (const block of blocksOf(key, value)) {
|
|
1860
|
+
if (key.startsWith("@")) {
|
|
1861
|
+
walkAt(key, block, selector, conditions, target);
|
|
1862
|
+
} else if (selector !== null) {
|
|
1863
|
+
walk(block, resolveNestedSelector(selector, key), conditions, compoundsOntoScope(key) ? target : "descendant");
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
walk(style, scope, [], "self");
|
|
1869
|
+
return rules;
|
|
1870
|
+
}
|
|
1534
1871
|
|
|
1535
1872
|
// ../schema/src/intl.ts
|
|
1536
1873
|
var DEFAULT_FORMAT_LOCALE = "en-US";
|
|
@@ -1762,8 +2099,8 @@ function withPageLocale(path, args, state) {
|
|
|
1762
2099
|
filled[index] = locale;
|
|
1763
2100
|
return filled;
|
|
1764
2101
|
}
|
|
1765
|
-
function isBlessedGlobal(
|
|
1766
|
-
return
|
|
2102
|
+
function isBlessedGlobal(ref) {
|
|
2103
|
+
return ref.startsWith("window#/") && BLESSED_GLOBALS.has(ref.slice("window#/".length));
|
|
1767
2104
|
}
|
|
1768
2105
|
function isMutating(op) {
|
|
1769
2106
|
return MUTATING_OPS.has(op);
|
|
@@ -1802,24 +2139,43 @@ function resolveOperand(operand, state, event, iterCtx, trace) {
|
|
|
1802
2139
|
trace?.report(trace.path ?? [], operand);
|
|
1803
2140
|
return operand;
|
|
1804
2141
|
}
|
|
1805
|
-
function
|
|
1806
|
-
|
|
2142
|
+
function calleeOwner(ref, state, event, iterCtx) {
|
|
2143
|
+
const parentRef = (prefix) => {
|
|
2144
|
+
const rest = ref.slice(prefix.length);
|
|
2145
|
+
if (!rest.includes("/")) {
|
|
2146
|
+
return state;
|
|
2147
|
+
}
|
|
2148
|
+
return resolveExprRef(ref.slice(0, ref.lastIndexOf("/")), state, event, iterCtx);
|
|
2149
|
+
};
|
|
2150
|
+
if (ref.startsWith("#/state/")) {
|
|
2151
|
+
return parentRef("#/state/");
|
|
2152
|
+
}
|
|
2153
|
+
if (ref.startsWith("parent#/")) {
|
|
2154
|
+
return parentRef("parent#/");
|
|
2155
|
+
}
|
|
2156
|
+
if (ref.startsWith("$map/") || ref.startsWith("$args/")) {
|
|
2157
|
+
return ref.split("/").length > 2 ? resolveExprRef(ref.slice(0, ref.lastIndexOf("/")), state, event, iterCtx) : undefined;
|
|
2158
|
+
}
|
|
2159
|
+
return;
|
|
2160
|
+
}
|
|
2161
|
+
function resolveExprRef(ref, state, event, iterCtx) {
|
|
2162
|
+
if (ref === "$reduce/acc") {
|
|
1807
2163
|
return iterCtx?.acc;
|
|
1808
2164
|
}
|
|
1809
|
-
if (
|
|
2165
|
+
if (ref.startsWith("$reduce/")) {
|
|
1810
2166
|
return iterCtx?.acc;
|
|
1811
2167
|
}
|
|
1812
|
-
if (
|
|
1813
|
-
const parts =
|
|
2168
|
+
if (ref.startsWith("$args/")) {
|
|
2169
|
+
const parts = ref.slice("$args/".length).split("/");
|
|
1814
2170
|
const base = iterCtx?.args?.[parts[0]];
|
|
1815
2171
|
return parts.length > 1 ? getPath(base, parts.slice(1).join("/")) : base;
|
|
1816
2172
|
}
|
|
1817
|
-
if (
|
|
1818
|
-
const path =
|
|
2173
|
+
if (ref.startsWith("event#/")) {
|
|
2174
|
+
const path = ref.slice("event#/".length);
|
|
1819
2175
|
return getPath(event, path);
|
|
1820
2176
|
}
|
|
1821
|
-
if (
|
|
1822
|
-
const parts =
|
|
2177
|
+
if (ref.startsWith("$map/")) {
|
|
2178
|
+
const parts = ref.split("/");
|
|
1823
2179
|
const [, key] = parts;
|
|
1824
2180
|
let base;
|
|
1825
2181
|
const map = scopeMap(state);
|
|
@@ -1832,23 +2188,23 @@ function resolveExprRef(ref2, state, event, iterCtx) {
|
|
|
1832
2188
|
}
|
|
1833
2189
|
return parts.length > 2 ? getPath(base, parts.slice(2).join("/")) : base;
|
|
1834
2190
|
}
|
|
1835
|
-
if (
|
|
1836
|
-
return readPath(state,
|
|
2191
|
+
if (ref.startsWith("#/state/")) {
|
|
2192
|
+
return readPath(state, ref.slice("#/state/".length));
|
|
1837
2193
|
}
|
|
1838
|
-
if (
|
|
1839
|
-
return readPath(state,
|
|
2194
|
+
if (ref.startsWith("parent#/")) {
|
|
2195
|
+
return readPath(state, ref.slice("parent#/".length));
|
|
1840
2196
|
}
|
|
1841
|
-
if (
|
|
1842
|
-
return getPath(globalThis.window,
|
|
2197
|
+
if (ref.startsWith("window#/")) {
|
|
2198
|
+
return getPath(globalThis.window, ref.slice("window#/".length));
|
|
1843
2199
|
}
|
|
1844
|
-
if (
|
|
1845
|
-
return getPath(globalThis.document,
|
|
2200
|
+
if (ref.startsWith("document#/")) {
|
|
2201
|
+
return getPath(globalThis.document, ref.slice("document#/".length));
|
|
1846
2202
|
}
|
|
1847
|
-
return readPath(state,
|
|
2203
|
+
return readPath(state, ref) ?? null;
|
|
1848
2204
|
}
|
|
1849
|
-
function resolveWritableRef(
|
|
1850
|
-
if (
|
|
1851
|
-
const parts =
|
|
2205
|
+
function resolveWritableRef(ref, state, _event, iterCtx) {
|
|
2206
|
+
if (ref.startsWith("$map/")) {
|
|
2207
|
+
const parts = ref.split("/");
|
|
1852
2208
|
const [, key] = parts;
|
|
1853
2209
|
let base;
|
|
1854
2210
|
const map = scopeMap(state);
|
|
@@ -1870,8 +2226,8 @@ function resolveWritableRef(ref2, state, _event, iterCtx) {
|
|
|
1870
2226
|
obj: scopeMap(state) ?? state
|
|
1871
2227
|
};
|
|
1872
2228
|
}
|
|
1873
|
-
if (
|
|
1874
|
-
const sub =
|
|
2229
|
+
if (ref.startsWith("#/state/")) {
|
|
2230
|
+
const sub = ref.slice("#/state/".length);
|
|
1875
2231
|
const slash = sub.indexOf("/");
|
|
1876
2232
|
if (slash === -1) {
|
|
1877
2233
|
return { key: sub, obj: state };
|
|
@@ -1884,7 +2240,7 @@ function resolveWritableRef(ref2, state, _event, iterCtx) {
|
|
|
1884
2240
|
}
|
|
1885
2241
|
return { key: lastKey, obj };
|
|
1886
2242
|
}
|
|
1887
|
-
return { key:
|
|
2243
|
+
return { key: ref, obj: state };
|
|
1888
2244
|
}
|
|
1889
2245
|
function evaluateExpression(node, state, event, iterCtx, trace) {
|
|
1890
2246
|
const result = evaluateNode(node, state, event, iterCtx, trace);
|
|
@@ -1931,19 +2287,19 @@ function evaluateNode(node, state, event, iterCtx, trace) {
|
|
|
1931
2287
|
}
|
|
1932
2288
|
const callee = resolveExprRef(calleeRef, state, event, iterCtx);
|
|
1933
2289
|
if (typeof callee === "function") {
|
|
1934
|
-
return callee(
|
|
2290
|
+
return callee.apply(calleeOwner(calleeRef, state, event, iterCtx), argValues);
|
|
1935
2291
|
}
|
|
1936
2292
|
if (callee && typeof callee === "object" && "$expression" in callee) {
|
|
1937
|
-
const
|
|
2293
|
+
const def = callee;
|
|
1938
2294
|
const args = {};
|
|
1939
|
-
for (const [i, p] of (
|
|
2295
|
+
for (const [i, p] of (def.parameters ?? []).entries()) {
|
|
1940
2296
|
const name = typeof p === "string" ? p : p?.name ?? "";
|
|
1941
2297
|
if (!name) {
|
|
1942
2298
|
continue;
|
|
1943
2299
|
}
|
|
1944
2300
|
args[name] = argValues[i] === undefined && typeof p === "object" && p !== null && "default" in p ? p.default : argValues[i];
|
|
1945
2301
|
}
|
|
1946
|
-
return evaluateExpression(
|
|
2302
|
+
return evaluateExpression(def.$expression, state, event, { args, callDepth });
|
|
1947
2303
|
}
|
|
1948
2304
|
throw new TypeError(`$expression: call target "${calleeRef}" is not callable`);
|
|
1949
2305
|
}
|
|
@@ -2185,10 +2541,10 @@ function isNonRelativeRef(value) {
|
|
|
2185
2541
|
function normalizeProjectPath(path) {
|
|
2186
2542
|
return path.replaceAll("\\", "/").replace(/^\.\//, "").replace(/^\/+/, "").replace(/\/+$/, "");
|
|
2187
2543
|
}
|
|
2188
|
-
function joinProjectPath(dir,
|
|
2544
|
+
function joinProjectPath(dir, ref) {
|
|
2189
2545
|
const base = dir === "" || dir === "." ? [] : normalizeProjectPath(dir).split("/");
|
|
2190
2546
|
const out = base.filter((segment) => segment !== "" && segment !== ".");
|
|
2191
|
-
for (const segment of
|
|
2547
|
+
for (const segment of ref.replaceAll("\\", "/").split("/")) {
|
|
2192
2548
|
if (segment === "" || segment === ".") {
|
|
2193
2549
|
continue;
|
|
2194
2550
|
}
|
|
@@ -2310,6 +2666,12 @@ function statementKind(statement) {
|
|
|
2310
2666
|
if ("$switch" in statement) {
|
|
2311
2667
|
return "switch";
|
|
2312
2668
|
}
|
|
2669
|
+
if ("stopPropagation" in statement) {
|
|
2670
|
+
return "stopPropagation";
|
|
2671
|
+
}
|
|
2672
|
+
if ("preventDefault" in statement) {
|
|
2673
|
+
return "preventDefault";
|
|
2674
|
+
}
|
|
2313
2675
|
return "dispatch";
|
|
2314
2676
|
}
|
|
2315
2677
|
async function runStatements(statements, state, event, opts = {}) {
|
|
@@ -2343,7 +2705,8 @@ async function runStatements(statements, state, event, opts = {}) {
|
|
|
2343
2705
|
}
|
|
2344
2706
|
case "dispatch": {
|
|
2345
2707
|
const dispatch = statement;
|
|
2346
|
-
const
|
|
2708
|
+
const fallback = typeof opts.target === "function" ? opts.target() : opts.target;
|
|
2709
|
+
const target = event?.currentTarget ?? fallback;
|
|
2347
2710
|
if (!target) {
|
|
2348
2711
|
break;
|
|
2349
2712
|
}
|
|
@@ -2360,6 +2723,14 @@ async function runStatements(statements, state, event, opts = {}) {
|
|
|
2360
2723
|
target.dispatchEvent(new CustomEvent(dispatch.dispatchEvent, init));
|
|
2361
2724
|
break;
|
|
2362
2725
|
}
|
|
2726
|
+
case "stopPropagation": {
|
|
2727
|
+
event?.stopPropagation();
|
|
2728
|
+
break;
|
|
2729
|
+
}
|
|
2730
|
+
case "preventDefault": {
|
|
2731
|
+
event?.preventDefault();
|
|
2732
|
+
break;
|
|
2733
|
+
}
|
|
2363
2734
|
default: {
|
|
2364
2735
|
break;
|
|
2365
2736
|
}
|
|
@@ -2407,10 +2778,14 @@ function serializeCookie(name, value, options) {
|
|
|
2407
2778
|
}
|
|
2408
2779
|
// ../runtime/src/runtime.ts
|
|
2409
2780
|
var _resolveCache = new Map;
|
|
2410
|
-
async function resolve(source) {
|
|
2781
|
+
async function resolve(source, ctx) {
|
|
2411
2782
|
if (typeof source !== "string") {
|
|
2412
2783
|
return source;
|
|
2413
2784
|
}
|
|
2785
|
+
const served = ctx?.resolver?.(source);
|
|
2786
|
+
if (served) {
|
|
2787
|
+
return served;
|
|
2788
|
+
}
|
|
2414
2789
|
if (_resolveCache.has(source)) {
|
|
2415
2790
|
return _resolveCache.get(source);
|
|
2416
2791
|
}
|
|
@@ -2495,10 +2870,36 @@ var _canvasDelinkAnchors = false;
|
|
|
2495
2870
|
function setCanvasDelinkAnchors(on) {
|
|
2496
2871
|
_canvasDelinkAnchors = on;
|
|
2497
2872
|
}
|
|
2873
|
+
var _canvasDelinkPopovers = false;
|
|
2874
|
+
function setCanvasDelinkPopovers(on) {
|
|
2875
|
+
_canvasDelinkPopovers = on;
|
|
2876
|
+
}
|
|
2877
|
+
var _canvasDelinkCommands = false;
|
|
2878
|
+
function setCanvasDelinkCommands(on) {
|
|
2879
|
+
_canvasDelinkCommands = on;
|
|
2880
|
+
}
|
|
2881
|
+
var _canvasInsideStampedHost = false;
|
|
2882
|
+
function canvasStamped(el) {
|
|
2883
|
+
return _canvasInsideStampedHost || el.dataset.jxPath !== undefined;
|
|
2884
|
+
}
|
|
2498
2885
|
function canvasAttrName(el, key) {
|
|
2499
2886
|
if (_canvasDelinkAnchors && key === "href" && (el.tagName === "A" || el.tagName === "AREA")) {
|
|
2500
2887
|
return "data-jx-href";
|
|
2501
2888
|
}
|
|
2889
|
+
if (_canvasDelinkPopovers && key === "popover" && canvasStamped(el)) {
|
|
2890
|
+
return "data-jx-popover";
|
|
2891
|
+
}
|
|
2892
|
+
if (_canvasDelinkCommands && canvasStamped(el)) {
|
|
2893
|
+
if (key === "commandfor") {
|
|
2894
|
+
return "data-jx-commandfor";
|
|
2895
|
+
}
|
|
2896
|
+
if (key === "inert") {
|
|
2897
|
+
return "data-jx-inert";
|
|
2898
|
+
}
|
|
2899
|
+
if (key === "open" && el.tagName === "DIALOG") {
|
|
2900
|
+
return "data-jx-open";
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2502
2903
|
return key;
|
|
2503
2904
|
}
|
|
2504
2905
|
var _canvasAssetResolver = null;
|
|
@@ -2578,71 +2979,84 @@ function boundPropKey(key, val, state) {
|
|
|
2578
2979
|
}
|
|
2579
2980
|
return sub;
|
|
2580
2981
|
}
|
|
2581
|
-
async function buildScope(doc, parentScope = {}, base = location.href) {
|
|
2982
|
+
async function buildScope(doc, parentScope = {}, base = location.href, ctx) {
|
|
2983
|
+
const dispatchRoot = () => ctx?.root ?? null;
|
|
2582
2984
|
const raw = {};
|
|
2583
|
-
for (const [key, val] of Object.entries(parentScope)) {
|
|
2584
|
-
raw[key] = val;
|
|
2585
|
-
}
|
|
2586
2985
|
const defs = doc.state ?? {};
|
|
2986
|
+
const linked = isReactive(parentScope);
|
|
2987
|
+
for (const key of Object.keys(parentScope)) {
|
|
2988
|
+
if (linked && !(key in defs)) {
|
|
2989
|
+
Object.defineProperty(raw, key, {
|
|
2990
|
+
configurable: true,
|
|
2991
|
+
enumerable: true,
|
|
2992
|
+
get: () => parentScope[key],
|
|
2993
|
+
set: (value) => {
|
|
2994
|
+
parentScope[key] = value;
|
|
2995
|
+
}
|
|
2996
|
+
});
|
|
2997
|
+
} else {
|
|
2998
|
+
raw[key] = parentScope[key];
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
2587
3001
|
const imports = doc.imports ?? {};
|
|
2588
|
-
for (const [,
|
|
2589
|
-
if (isPrototypeDef(
|
|
2590
|
-
const mapped = imports[
|
|
3002
|
+
for (const [, def] of Object.entries(defs)) {
|
|
3003
|
+
if (isPrototypeDef(def) && !def.$src) {
|
|
3004
|
+
const mapped = imports[def.$prototype];
|
|
2591
3005
|
if (mapped) {
|
|
2592
3006
|
if (!mapped.endsWith(".class.json")) {
|
|
2593
|
-
console.warn(`Jx: import "${
|
|
3007
|
+
console.warn(`Jx: import "${def.$prototype}" must map to a .class.json path, got "${mapped}"`);
|
|
2594
3008
|
continue;
|
|
2595
3009
|
}
|
|
2596
|
-
|
|
3010
|
+
def.$src = mapped;
|
|
2597
3011
|
}
|
|
2598
3012
|
}
|
|
2599
3013
|
}
|
|
2600
|
-
for (const [key,
|
|
2601
|
-
if (typeof
|
|
2602
|
-
if (!
|
|
2603
|
-
raw[key] =
|
|
3014
|
+
for (const [key, def] of Object.entries(defs)) {
|
|
3015
|
+
if (typeof def === "string") {
|
|
3016
|
+
if (!def.includes("${")) {
|
|
3017
|
+
raw[key] = def;
|
|
2604
3018
|
}
|
|
2605
3019
|
continue;
|
|
2606
3020
|
}
|
|
2607
|
-
if (typeof
|
|
2608
|
-
raw[key] =
|
|
3021
|
+
if (typeof def === "number" || typeof def === "boolean" || def === null) {
|
|
3022
|
+
raw[key] = def;
|
|
2609
3023
|
continue;
|
|
2610
3024
|
}
|
|
2611
|
-
if (Array.isArray(
|
|
2612
|
-
raw[key] =
|
|
3025
|
+
if (Array.isArray(def)) {
|
|
3026
|
+
raw[key] = def;
|
|
2613
3027
|
continue;
|
|
2614
3028
|
}
|
|
2615
|
-
if (typeof
|
|
2616
|
-
if (
|
|
3029
|
+
if (typeof def === "object") {
|
|
3030
|
+
if (def.$prototype) {
|
|
2617
3031
|
continue;
|
|
2618
3032
|
}
|
|
2619
|
-
if (isExpressionDef(
|
|
3033
|
+
if (isExpressionDef(def)) {
|
|
2620
3034
|
continue;
|
|
2621
3035
|
}
|
|
2622
|
-
if (isServerFnDef(
|
|
3036
|
+
if (isServerFnDef(def)) {
|
|
2623
3037
|
continue;
|
|
2624
3038
|
}
|
|
2625
|
-
if ("default" in
|
|
2626
|
-
raw[key] =
|
|
3039
|
+
if ("default" in def) {
|
|
3040
|
+
raw[key] = def.default;
|
|
2627
3041
|
continue;
|
|
2628
3042
|
}
|
|
2629
|
-
if (hasSchemaKeywords(
|
|
3043
|
+
if (hasSchemaKeywords(def)) {
|
|
2630
3044
|
continue;
|
|
2631
3045
|
}
|
|
2632
|
-
raw[key] =
|
|
3046
|
+
raw[key] = def;
|
|
2633
3047
|
}
|
|
2634
3048
|
}
|
|
2635
3049
|
const state = reactive(raw);
|
|
2636
|
-
for (const [key,
|
|
2637
|
-
if (typeof
|
|
2638
|
-
state[key] = computed(() => evaluateTemplate(
|
|
3050
|
+
for (const [key, def] of Object.entries(defs)) {
|
|
3051
|
+
if (typeof def === "string" && def.includes("${")) {
|
|
3052
|
+
state[key] = computed(() => evaluateTemplate(def, state));
|
|
2639
3053
|
}
|
|
2640
3054
|
}
|
|
2641
|
-
for (const [key,
|
|
2642
|
-
if (isExpressionDef(
|
|
2643
|
-
const node =
|
|
2644
|
-
if (isNamedFormulaDef(
|
|
2645
|
-
const params =
|
|
3055
|
+
for (const [key, def] of Object.entries(defs)) {
|
|
3056
|
+
if (isExpressionDef(def)) {
|
|
3057
|
+
const node = def.$expression;
|
|
3058
|
+
if (isNamedFormulaDef(def)) {
|
|
3059
|
+
const params = def.parameters;
|
|
2646
3060
|
state[key] = (...argValues) => {
|
|
2647
3061
|
const args = {};
|
|
2648
3062
|
for (const [i, p] of params.entries()) {
|
|
@@ -2662,11 +3076,11 @@ async function buildScope(doc, parentScope = {}, base = location.href) {
|
|
|
2662
3076
|
}
|
|
2663
3077
|
}
|
|
2664
3078
|
}
|
|
2665
|
-
for (const [key,
|
|
2666
|
-
if (hasStructuredBody(
|
|
2667
|
-
const { body } =
|
|
2668
|
-
if (Array.isArray(
|
|
2669
|
-
const params =
|
|
3079
|
+
for (const [key, def] of Object.entries(defs)) {
|
|
3080
|
+
if (hasStructuredBody(def)) {
|
|
3081
|
+
const { body } = def;
|
|
3082
|
+
if (Array.isArray(def.parameters) && def.parameters.length > 0) {
|
|
3083
|
+
const params = def.parameters;
|
|
2670
3084
|
state[key] = (...argValues) => {
|
|
2671
3085
|
const args = {};
|
|
2672
3086
|
for (const [i, p] of params.entries()) {
|
|
@@ -2676,34 +3090,35 @@ async function buildScope(doc, parentScope = {}, base = location.href) {
|
|
|
2676
3090
|
}
|
|
2677
3091
|
args[name] = argValues[i] === undefined && typeof p === "object" && p !== null && "default" in p ? p.default : argValues[i];
|
|
2678
3092
|
}
|
|
2679
|
-
return runStatements(body, state, null, { args });
|
|
3093
|
+
return runStatements(body, state, null, { args, target: dispatchRoot });
|
|
2680
3094
|
};
|
|
2681
3095
|
} else {
|
|
2682
3096
|
const handler = (s, event) => {
|
|
2683
|
-
runStatements(body, s, event ?? null);
|
|
3097
|
+
runStatements(body, s, event ?? null, { target: dispatchRoot });
|
|
2684
3098
|
};
|
|
2685
3099
|
state[key] = handler;
|
|
2686
3100
|
}
|
|
2687
|
-
} else if (isFunctionDef(
|
|
2688
|
-
state[key] = await resolveFunction(
|
|
3101
|
+
} else if (isFunctionDef(def)) {
|
|
3102
|
+
state[key] = await resolveFunction(def, state, key, base);
|
|
2689
3103
|
}
|
|
2690
3104
|
}
|
|
2691
|
-
for (const [key,
|
|
2692
|
-
if (isPrototypeDef(
|
|
2693
|
-
state[key] = await resolvePrototype(
|
|
3105
|
+
for (const [key, def] of Object.entries(defs)) {
|
|
3106
|
+
if (isPrototypeDef(def)) {
|
|
3107
|
+
state[key] = await resolvePrototype(def, state, key, base, ctx);
|
|
2694
3108
|
}
|
|
2695
3109
|
}
|
|
2696
|
-
if (!_serverFnConfig.skip) {
|
|
2697
|
-
for (const [key,
|
|
2698
|
-
if (isServerFnDef(
|
|
2699
|
-
state[key] = await resolveServerFunction(
|
|
3110
|
+
if (!(ctx?.skipServerFunctions ?? _serverFnConfig.skip)) {
|
|
3111
|
+
for (const [key, def] of Object.entries(defs)) {
|
|
3112
|
+
if (isServerFnDef(def)) {
|
|
3113
|
+
state[key] = await resolveServerFunction(def, state, key, base);
|
|
2700
3114
|
}
|
|
2701
3115
|
}
|
|
2702
3116
|
}
|
|
3117
|
+
const rootMedia = ctx?.media ?? _rootMedia;
|
|
2703
3118
|
if (doc.$media) {
|
|
2704
3119
|
state["$media"] = doc.$media;
|
|
2705
|
-
} else if (!state["$media"] && Object.keys(
|
|
2706
|
-
state["$media"] =
|
|
3120
|
+
} else if (!state["$media"] && Object.keys(rootMedia).length > 0) {
|
|
3121
|
+
state["$media"] = rootMedia;
|
|
2707
3122
|
}
|
|
2708
3123
|
return state;
|
|
2709
3124
|
}
|
|
@@ -2747,36 +3162,72 @@ function evaluateAttrTemplate(str, state) {
|
|
|
2747
3162
|
return fn(state, $map, $map?.item, $map?.index);
|
|
2748
3163
|
}
|
|
2749
3164
|
var _moduleCache = new Map;
|
|
2750
|
-
|
|
2751
|
-
|
|
3165
|
+
var _moduleLoaders = new Map;
|
|
3166
|
+
function preloadModule(specifier, mod) {
|
|
3167
|
+
if (typeof mod === "function") {
|
|
3168
|
+
_moduleCache.delete(specifier);
|
|
3169
|
+
_moduleLoaders.set(specifier, mod);
|
|
3170
|
+
return;
|
|
3171
|
+
}
|
|
3172
|
+
_moduleLoaders.delete(specifier);
|
|
3173
|
+
_moduleCache.set(specifier, mod);
|
|
3174
|
+
}
|
|
3175
|
+
function seededModule(src) {
|
|
3176
|
+
const cached = _moduleCache.get(src);
|
|
3177
|
+
if (cached) {
|
|
3178
|
+
return cached;
|
|
3179
|
+
}
|
|
3180
|
+
const pending = _moduleLoaders.get(src);
|
|
3181
|
+
if (!pending) {
|
|
3182
|
+
return;
|
|
3183
|
+
}
|
|
3184
|
+
if (typeof pending !== "function") {
|
|
3185
|
+
return pending;
|
|
3186
|
+
}
|
|
3187
|
+
const load = Promise.resolve(pending()).then((mod) => {
|
|
3188
|
+
_moduleCache.set(src, mod);
|
|
3189
|
+
_moduleLoaders.delete(src);
|
|
3190
|
+
return mod;
|
|
3191
|
+
}, (error) => {
|
|
3192
|
+
_moduleLoaders.set(src, pending);
|
|
3193
|
+
throw error;
|
|
3194
|
+
});
|
|
3195
|
+
_moduleLoaders.set(src, load);
|
|
3196
|
+
return load;
|
|
3197
|
+
}
|
|
3198
|
+
async function resolveFunction(def, state, key, base) {
|
|
3199
|
+
if (def.body && def.$src) {
|
|
2752
3200
|
throw new Error(`Jx: '${key}' declares both body and $src — these are mutually exclusive`);
|
|
2753
3201
|
}
|
|
2754
|
-
if (!
|
|
2755
|
-
const params = resolveParamNames(
|
|
3202
|
+
if (!def.body && !def.$src) {
|
|
3203
|
+
const params = resolveParamNames(def);
|
|
2756
3204
|
const noop = new Function(...params, "");
|
|
2757
3205
|
Object.defineProperty(noop, "name", {
|
|
2758
3206
|
configurable: true,
|
|
2759
|
-
value:
|
|
3207
|
+
value: def.name ?? key
|
|
2760
3208
|
});
|
|
2761
3209
|
return noop;
|
|
2762
3210
|
}
|
|
2763
3211
|
let fn;
|
|
2764
|
-
if (typeof
|
|
2765
|
-
const params = resolveParamNames(
|
|
2766
|
-
fn = new Function(...params,
|
|
3212
|
+
if (typeof def.body === "string") {
|
|
3213
|
+
const params = resolveParamNames(def);
|
|
3214
|
+
fn = new Function(...params, def.body);
|
|
2767
3215
|
Object.defineProperty(fn, "name", {
|
|
2768
3216
|
configurable: true,
|
|
2769
|
-
value:
|
|
3217
|
+
value: def.name ?? key
|
|
2770
3218
|
});
|
|
2771
3219
|
} else {
|
|
2772
|
-
const src =
|
|
3220
|
+
const src = def.$src;
|
|
2773
3221
|
if (!src) {
|
|
2774
3222
|
throw new Error(`Jx: '${key}' has neither body nor $src`);
|
|
2775
3223
|
}
|
|
2776
|
-
const exportName =
|
|
3224
|
+
const exportName = def.$export ?? key;
|
|
2777
3225
|
let mod;
|
|
2778
|
-
|
|
2779
|
-
|
|
3226
|
+
const seeded = seededModule(src);
|
|
3227
|
+
if (seeded instanceof Promise) {
|
|
3228
|
+
mod = await seeded;
|
|
3229
|
+
} else if (seeded) {
|
|
3230
|
+
mod = seeded;
|
|
2780
3231
|
} else {
|
|
2781
3232
|
if (base) {
|
|
2782
3233
|
const resolvedSrc = new URL(src, base).href;
|
|
@@ -2796,11 +3247,11 @@ async function resolveFunction(def2, state, key, base) {
|
|
|
2796
3247
|
}
|
|
2797
3248
|
fn = candidate;
|
|
2798
3249
|
}
|
|
2799
|
-
const hasParams = (
|
|
3250
|
+
const hasParams = (def.parameters ?? def.arguments ?? []).length > 0;
|
|
2800
3251
|
let isComputed = false;
|
|
2801
3252
|
if (!hasParams) {
|
|
2802
|
-
if (typeof
|
|
2803
|
-
isComputed = bodyReturnsValue(
|
|
3253
|
+
if (typeof def.body === "string") {
|
|
3254
|
+
isComputed = bodyReturnsValue(def.body);
|
|
2804
3255
|
} else if (fn) {
|
|
2805
3256
|
isComputed = fn.length <= 1 && bodyReturnsValue(fn.toString());
|
|
2806
3257
|
}
|
|
@@ -2810,8 +3261,8 @@ async function resolveFunction(def2, state, key, base) {
|
|
|
2810
3261
|
}
|
|
2811
3262
|
return fn;
|
|
2812
3263
|
}
|
|
2813
|
-
function resolveParamNames(
|
|
2814
|
-
const names =
|
|
3264
|
+
function resolveParamNames(def) {
|
|
3265
|
+
const names = def.parameters ? paramNames(def.parameters) : def.arguments ?? [];
|
|
2815
3266
|
return names.length > 0 && names[0] === "state" ? names : ["state", ...names];
|
|
2816
3267
|
}
|
|
2817
3268
|
var RESERVED_KEYS = new Set([
|
|
@@ -2860,19 +3311,19 @@ function elementNamespace(tagName, inherited) {
|
|
|
2860
3311
|
}
|
|
2861
3312
|
return inherited ?? null;
|
|
2862
3313
|
}
|
|
2863
|
-
function renderNode(
|
|
3314
|
+
function renderNode(def, state, options) {
|
|
2864
3315
|
const path = options?._path ?? [];
|
|
2865
|
-
if (typeof
|
|
2866
|
-
const textNode = document.createTextNode(String(
|
|
2867
|
-
if (typeof
|
|
3316
|
+
if (typeof def === "string" || typeof def === "number" || typeof def === "boolean") {
|
|
3317
|
+
const textNode = document.createTextNode(String(def));
|
|
3318
|
+
if (typeof def === "string" && isTemplateString(def)) {
|
|
2868
3319
|
effect(() => {
|
|
2869
|
-
textNode.textContent = evaluateTemplate(
|
|
3320
|
+
textNode.textContent = evaluateTemplate(def, state);
|
|
2870
3321
|
});
|
|
2871
3322
|
}
|
|
2872
3323
|
return textNode;
|
|
2873
3324
|
}
|
|
2874
3325
|
let localState = state;
|
|
2875
|
-
for (const [key, val] of Object.entries(
|
|
3326
|
+
for (const [key, val] of Object.entries(def)) {
|
|
2876
3327
|
if (key.startsWith("$") && !RESERVED_KEYS.has(key)) {
|
|
2877
3328
|
if (localState === state) {
|
|
2878
3329
|
localState = Object.create(state);
|
|
@@ -2880,38 +3331,41 @@ function renderNode(def2, state, options) {
|
|
|
2880
3331
|
localState[key] = isRefObj(val) ? resolveRef(val.$ref, state) : val;
|
|
2881
3332
|
}
|
|
2882
3333
|
}
|
|
2883
|
-
if ("$ref" in
|
|
2884
|
-
const refTarget = String(
|
|
3334
|
+
if ("$ref" in def && !def.tagName) {
|
|
3335
|
+
const refTarget = String(def.$ref ?? "");
|
|
2885
3336
|
if (!warnedRefChildren.has(refTarget)) {
|
|
2886
3337
|
warnedRefChildren.add(refTarget);
|
|
2887
3338
|
console.warn(`Jx: a $ref child ("${refTarget}") is not a supported component instance; register the ` + `component in $elements and use its custom-element tag instead (spec §13).`);
|
|
2888
3339
|
}
|
|
2889
3340
|
}
|
|
2890
|
-
const tagName = resolveTagName(
|
|
3341
|
+
const tagName = resolveTagName(def.tagName, localState);
|
|
2891
3342
|
const isCustomEl = tagName.includes("-") && customElements.get(tagName);
|
|
2892
|
-
if (
|
|
2893
|
-
return renderCustomElementWithProps(
|
|
3343
|
+
if (def.$props && isCustomEl) {
|
|
3344
|
+
return renderCustomElementWithProps(def, localState, options, path);
|
|
2894
3345
|
}
|
|
2895
|
-
if (
|
|
3346
|
+
if (def.$props) {
|
|
2896
3347
|
if (tagName.includes("-")) {
|
|
2897
|
-
return renderCustomElementWithProps(
|
|
3348
|
+
return renderCustomElementWithProps(def, localState, options, path);
|
|
2898
3349
|
}
|
|
2899
|
-
const { $props: _$props, ...rest } =
|
|
2900
|
-
return renderNode(rest, mergeProps(
|
|
3350
|
+
const { $props: _$props, ...rest } = def;
|
|
3351
|
+
return renderNode(rest, mergeProps(def, localState), options);
|
|
2901
3352
|
}
|
|
2902
|
-
if (
|
|
2903
|
-
return renderSwitch(
|
|
3353
|
+
if (def.$switch) {
|
|
3354
|
+
return renderSwitch(def, localState, options);
|
|
2904
3355
|
}
|
|
2905
3356
|
const ns = elementNamespace(tagName, options?._ns);
|
|
2906
3357
|
const childNs = tagName === "foreignObject" ? null : ns;
|
|
2907
3358
|
const el = ns ? document.createElementNS(ns, tagName) : document.createElement(tagName);
|
|
2908
3359
|
if (options?.onNodeCreated) {
|
|
2909
|
-
options.onNodeCreated(el, path,
|
|
3360
|
+
options.onNodeCreated(el, path, def, localState);
|
|
3361
|
+
}
|
|
3362
|
+
applyProperties(el, def, localState);
|
|
3363
|
+
if (def.style && tagName.includes("-")) {
|
|
3364
|
+
callSiteStyles.set(el, def.style);
|
|
2910
3365
|
}
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
const kids = def2.children;
|
|
3366
|
+
applyStyle(el, def.style ?? {}, localState["$media"] ?? {}, localState);
|
|
3367
|
+
applyAttributes(el, def.attributes ?? {}, localState);
|
|
3368
|
+
const kids = def.children;
|
|
2915
3369
|
if (isMappedArray(kids)) {
|
|
2916
3370
|
const arrOpts = options || childNs ? { ...options, _ns: childNs, _path: [...path, "children"] } : undefined;
|
|
2917
3371
|
renderMappedArrayInto(el, kids, localState, arrOpts);
|
|
@@ -2928,49 +3382,58 @@ function renderNode(def2, state, options) {
|
|
|
2928
3382
|
}
|
|
2929
3383
|
return el;
|
|
2930
3384
|
}
|
|
2931
|
-
function applyProperties(el,
|
|
2932
|
-
for (const [key, val] of Object.entries(
|
|
3385
|
+
function applyProperties(el, def, state) {
|
|
3386
|
+
for (const [key, val] of Object.entries(def)) {
|
|
2933
3387
|
if (RESERVED_KEYS.has(key)) {
|
|
2934
3388
|
continue;
|
|
2935
3389
|
}
|
|
2936
3390
|
if (key.startsWith("$")) {
|
|
2937
3391
|
continue;
|
|
2938
3392
|
}
|
|
2939
|
-
if (key.startsWith("on")) {
|
|
2940
|
-
|
|
2941
|
-
const handler = resolveRef(val.$ref, state);
|
|
2942
|
-
if (typeof handler === "function") {
|
|
2943
|
-
const scope = state;
|
|
2944
|
-
const handlerFn = handler;
|
|
2945
|
-
el.addEventListener(key.slice(2), (e) => handlerFn(scope, e));
|
|
2946
|
-
}
|
|
2947
|
-
continue;
|
|
2948
|
-
}
|
|
2949
|
-
if (hasStructuredBody(val)) {
|
|
2950
|
-
const { body } = val;
|
|
2951
|
-
const scope = state;
|
|
2952
|
-
el.addEventListener(key.slice(2), (e) => {
|
|
2953
|
-
runStatements(body, scope, e);
|
|
2954
|
-
});
|
|
2955
|
-
continue;
|
|
2956
|
-
}
|
|
2957
|
-
if (isFunctionDef(val) && typeof val.body === "string") {
|
|
2958
|
-
const params = resolveParamNames(val);
|
|
2959
|
-
const fn = new Function(...params, val.body);
|
|
2960
|
-
const scope = state;
|
|
2961
|
-
el.addEventListener(key.slice(2), (e) => fn(scope, e));
|
|
2962
|
-
continue;
|
|
2963
|
-
}
|
|
2964
|
-
if (isExpressionDef(val)) {
|
|
2965
|
-
const node = val.$expression;
|
|
2966
|
-
const scope = state;
|
|
2967
|
-
el.addEventListener(key.slice(2), (e) => evaluateExpression(node, scope, e));
|
|
2968
|
-
continue;
|
|
2969
|
-
}
|
|
3393
|
+
if (key.startsWith("on") && bindHandler(el, key, val, state)) {
|
|
3394
|
+
continue;
|
|
2970
3395
|
}
|
|
2971
3396
|
bindProperty(el, key, val, state);
|
|
2972
3397
|
}
|
|
2973
3398
|
}
|
|
3399
|
+
function bindHandler(el, key, val, state) {
|
|
3400
|
+
const type = key.slice(2);
|
|
3401
|
+
const scope = state;
|
|
3402
|
+
if (isRefObj(val)) {
|
|
3403
|
+
const handler = resolveRef(val.$ref, state);
|
|
3404
|
+
if (typeof handler === "function") {
|
|
3405
|
+
const handlerFn = handler;
|
|
3406
|
+
el.addEventListener(type, (e) => handlerFn(scope, e));
|
|
3407
|
+
}
|
|
3408
|
+
return true;
|
|
3409
|
+
}
|
|
3410
|
+
if (hasStructuredBody(val)) {
|
|
3411
|
+
const { body } = val;
|
|
3412
|
+
el.addEventListener(type, (e) => {
|
|
3413
|
+
runStatements(body, scope, e);
|
|
3414
|
+
});
|
|
3415
|
+
return true;
|
|
3416
|
+
}
|
|
3417
|
+
if (isFunctionDef(val) && typeof val.body === "string") {
|
|
3418
|
+
const params = resolveParamNames(val);
|
|
3419
|
+
const fn = new Function(...params, val.body);
|
|
3420
|
+
el.addEventListener(type, (e) => fn(scope, e));
|
|
3421
|
+
return true;
|
|
3422
|
+
}
|
|
3423
|
+
if (isExpressionDef(val)) {
|
|
3424
|
+
const node = val.$expression;
|
|
3425
|
+
el.addEventListener(type, (e) => evaluateExpression(node, scope, e));
|
|
3426
|
+
return true;
|
|
3427
|
+
}
|
|
3428
|
+
return false;
|
|
3429
|
+
}
|
|
3430
|
+
function bindDefinitionHandlers(host, def, state) {
|
|
3431
|
+
for (const [key, val] of Object.entries(def)) {
|
|
3432
|
+
if (key.startsWith("on") && !RESERVED_KEYS.has(key)) {
|
|
3433
|
+
bindHandler(host, key, val, state);
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
2974
3437
|
function bindProperty(el, key, val, state) {
|
|
2975
3438
|
const target = el;
|
|
2976
3439
|
const boundProp = boundPropKey(key, val, state);
|
|
@@ -2984,6 +3447,9 @@ function bindProperty(el, key, val, state) {
|
|
|
2984
3447
|
node.setAttribute("class", resolved == null ? "" : String(resolved));
|
|
2985
3448
|
return;
|
|
2986
3449
|
}
|
|
3450
|
+
if (target[key] === resolved) {
|
|
3451
|
+
return;
|
|
3452
|
+
}
|
|
2987
3453
|
target[key] = resolved;
|
|
2988
3454
|
};
|
|
2989
3455
|
if (isRefObj(val)) {
|
|
@@ -3005,142 +3471,287 @@ function bindProperty(el, key, val, state) {
|
|
|
3005
3471
|
}
|
|
3006
3472
|
write(asAsset(val));
|
|
3007
3473
|
}
|
|
3008
|
-
function
|
|
3009
|
-
const
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3474
|
+
function cssomSink(sheet, detach) {
|
|
3475
|
+
const entries = [];
|
|
3476
|
+
return {
|
|
3477
|
+
detach,
|
|
3478
|
+
insert(texts) {
|
|
3479
|
+
const rules = [];
|
|
3480
|
+
for (const text of texts) {
|
|
3481
|
+
const index = sheet.cssRules.length;
|
|
3482
|
+
try {
|
|
3483
|
+
sheet.insertRule(text, index);
|
|
3484
|
+
} catch {
|
|
3485
|
+
continue;
|
|
3486
|
+
}
|
|
3487
|
+
const rule = sheet.cssRules[index];
|
|
3488
|
+
if (rule) {
|
|
3489
|
+
rules.push(rule);
|
|
3018
3490
|
}
|
|
3019
3491
|
}
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3492
|
+
const inserted = { rules, texts };
|
|
3493
|
+
entries.push(inserted);
|
|
3494
|
+
return inserted;
|
|
3495
|
+
},
|
|
3496
|
+
remove(inserted) {
|
|
3497
|
+
const at = entries.indexOf(inserted);
|
|
3498
|
+
if (at !== -1) {
|
|
3499
|
+
entries.splice(at, 1);
|
|
3028
3500
|
}
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3501
|
+
if (inserted.rules.length === 0) {
|
|
3502
|
+
return;
|
|
3503
|
+
}
|
|
3504
|
+
const list = [...sheet.cssRules];
|
|
3505
|
+
const indices = inserted.rules.map((rule) => list.indexOf(rule)).filter((index) => index >= 0).toSorted((a, b) => b - a);
|
|
3506
|
+
for (const index of indices) {
|
|
3507
|
+
sheet.deleteRule(index);
|
|
3508
|
+
}
|
|
3509
|
+
inserted.rules.length = 0;
|
|
3510
|
+
},
|
|
3511
|
+
replaceAll(texts) {
|
|
3512
|
+
entries.length = 0;
|
|
3513
|
+
entries.push({ rules: [], texts });
|
|
3514
|
+
sheet.replaceSync(texts.join(`
|
|
3515
|
+
`));
|
|
3516
|
+
},
|
|
3517
|
+
text() {
|
|
3518
|
+
return entries.flatMap((entry) => entry.texts.join(`
|
|
3519
|
+
`)).join(`
|
|
3520
|
+
`);
|
|
3036
3521
|
}
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3522
|
+
};
|
|
3523
|
+
}
|
|
3524
|
+
function textSink(tag) {
|
|
3525
|
+
const entries = [];
|
|
3526
|
+
const write = () => {
|
|
3527
|
+
tag.textContent = entries.map((entry) => entry.texts.join(`
|
|
3528
|
+
`)).join(`
|
|
3529
|
+
`);
|
|
3530
|
+
};
|
|
3531
|
+
return {
|
|
3532
|
+
detach() {
|
|
3533
|
+
tag.remove();
|
|
3534
|
+
},
|
|
3535
|
+
insert(texts) {
|
|
3536
|
+
const inserted = { rules: [], texts };
|
|
3537
|
+
entries.push(inserted);
|
|
3538
|
+
write();
|
|
3539
|
+
return inserted;
|
|
3540
|
+
},
|
|
3541
|
+
remove(inserted) {
|
|
3542
|
+
const index = entries.indexOf(inserted);
|
|
3543
|
+
if (index !== -1) {
|
|
3544
|
+
entries.splice(index, 1);
|
|
3545
|
+
write();
|
|
3045
3546
|
}
|
|
3046
|
-
}
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
});
|
|
3050
|
-
|
|
3051
|
-
|
|
3052
|
-
|
|
3053
|
-
|
|
3547
|
+
},
|
|
3548
|
+
replaceAll(texts) {
|
|
3549
|
+
entries.length = 0;
|
|
3550
|
+
entries.push({ rules: [], texts });
|
|
3551
|
+
write();
|
|
3552
|
+
},
|
|
3553
|
+
text() {
|
|
3554
|
+
return tag.textContent ?? "";
|
|
3054
3555
|
}
|
|
3556
|
+
};
|
|
3557
|
+
}
|
|
3558
|
+
function openSink(doc) {
|
|
3559
|
+
const view = doc.defaultView;
|
|
3560
|
+
const SheetConstructor = view?.CSSStyleSheet;
|
|
3561
|
+
if (typeof SheetConstructor === "function" && Array.isArray(doc.adoptedStyleSheets)) {
|
|
3562
|
+
try {
|
|
3563
|
+
const sheet = new SheetConstructor;
|
|
3564
|
+
doc.adoptedStyleSheets = [...doc.adoptedStyleSheets, sheet];
|
|
3565
|
+
return cssomSink(sheet, () => {
|
|
3566
|
+
doc.adoptedStyleSheets = doc.adoptedStyleSheets.filter((s) => s !== sheet);
|
|
3567
|
+
});
|
|
3568
|
+
} catch {}
|
|
3055
3569
|
}
|
|
3056
|
-
const
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3570
|
+
const tag = doc.createElement("style");
|
|
3571
|
+
tag.dataset.jxSheet = "";
|
|
3572
|
+
(doc.head ?? doc.documentElement).append(tag);
|
|
3573
|
+
return tag.sheet ? cssomSink(tag.sheet, () => tag.remove()) : textSink(tag);
|
|
3574
|
+
}
|
|
3575
|
+
var sheetStates = new WeakMap;
|
|
3576
|
+
function sheetStateFor(doc) {
|
|
3577
|
+
const existing = sheetStates.get(doc);
|
|
3578
|
+
if (existing) {
|
|
3579
|
+
return existing;
|
|
3580
|
+
}
|
|
3581
|
+
const created = {
|
|
3582
|
+
hoisted: new Map,
|
|
3583
|
+
interned: new Map,
|
|
3584
|
+
scratch: null,
|
|
3585
|
+
scratchOwners: new Map,
|
|
3586
|
+
serial: 0,
|
|
3587
|
+
shared: openSink(doc)
|
|
3588
|
+
};
|
|
3589
|
+
sheetStates.set(doc, created);
|
|
3590
|
+
return created;
|
|
3591
|
+
}
|
|
3592
|
+
var elementStyles = new WeakMap;
|
|
3593
|
+
var SCOPE_TOKEN = "\x01jx-scope\x01";
|
|
3594
|
+
function rewriteScratch(state) {
|
|
3595
|
+
if (!state.scratch) {
|
|
3060
3596
|
return;
|
|
3061
3597
|
}
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
const
|
|
3066
|
-
if (
|
|
3067
|
-
|
|
3068
|
-
`;
|
|
3069
|
-
}
|
|
3070
|
-
function emitNested(scope, rules) {
|
|
3071
|
-
const props = toCSSText(rules);
|
|
3072
|
-
if (props) {
|
|
3073
|
-
css += `${scope} { ${props} }
|
|
3074
|
-
`;
|
|
3075
|
-
}
|
|
3076
|
-
for (const [sel, sub] of Object.entries(rules)) {
|
|
3077
|
-
if (sub === null || typeof sub !== "object" || Array.isArray(sub)) {
|
|
3078
|
-
continue;
|
|
3079
|
-
}
|
|
3080
|
-
if (sel.startsWith("@")) {
|
|
3081
|
-
continue;
|
|
3082
|
-
}
|
|
3083
|
-
const resolved = sel.startsWith("&") ? sel.replace("&", scope) : sel.startsWith("[") ? `${scope}${sel}` : sel.startsWith(":") || sel.startsWith(".") ? `${scope}${sel}` : `${scope} ${sel}`;
|
|
3084
|
-
emitNested(resolved, sub);
|
|
3085
|
-
}
|
|
3086
|
-
}
|
|
3087
|
-
for (const [sel, rules] of Object.entries(nested)) {
|
|
3088
|
-
const resolved = sel.startsWith("&") ? sel.replace("&", `[data-jx="${uid}"]`) : sel.startsWith("[") ? `[data-jx="${uid}"]${sel}` : sel.startsWith(":") || sel.startsWith(".") ? `[data-jx="${uid}"]${sel}` : `[data-jx="${uid}"] ${sel}`;
|
|
3089
|
-
emitNested(resolved, rules);
|
|
3598
|
+
state.scratch.replaceAll([...state.scratchOwners.values()].flat());
|
|
3599
|
+
}
|
|
3600
|
+
function releaseInterned(state, table, key) {
|
|
3601
|
+
const entry = table.get(key);
|
|
3602
|
+
if (!entry) {
|
|
3603
|
+
return;
|
|
3090
3604
|
}
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
}
|
|
3096
|
-
if (sel.startsWith("@")) {
|
|
3097
|
-
continue;
|
|
3098
|
-
}
|
|
3099
|
-
const resolved = sel.startsWith("&") ? sel.replace("&", parentSel) : sel.startsWith("[") ? `${parentSel}${sel}` : sel.startsWith(":") || sel.startsWith(".") ? `${parentSel}${sel}` : `${parentSel} ${sel}`;
|
|
3100
|
-
const props = toCSSText(sub);
|
|
3101
|
-
if (props) {
|
|
3102
|
-
css += `${atRule} { ${resolved} { ${props} } }
|
|
3103
|
-
`;
|
|
3104
|
-
}
|
|
3105
|
-
emitMediaNested(atRule, resolved, sub);
|
|
3106
|
-
}
|
|
3605
|
+
entry.refs -= 1;
|
|
3606
|
+
if (entry.refs <= 0) {
|
|
3607
|
+
table.delete(key);
|
|
3608
|
+
state.shared.remove(entry.inserted);
|
|
3107
3609
|
}
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
const scope = `[data-jx="${uid}"]`;
|
|
3115
|
-
const scheme = query === null ? null : pureSchemeOf(query);
|
|
3116
|
-
if (scheme) {
|
|
3117
|
-
const { auto, forced } = schemeSelectors(scope, scheme);
|
|
3118
|
-
css += `${atRule} { ${auto} { ${toCSSText(rules)} } }
|
|
3119
|
-
`;
|
|
3120
|
-
emitMediaNested(atRule, auto, rules);
|
|
3121
|
-
emitNested(forced, rules);
|
|
3122
|
-
} else {
|
|
3123
|
-
css += `${atRule} { ${scope} { ${toCSSText(rules)} } }
|
|
3124
|
-
`;
|
|
3125
|
-
emitMediaNested(atRule, scope, rules);
|
|
3126
|
-
}
|
|
3610
|
+
}
|
|
3611
|
+
function retainInterned(state, table, key, texts) {
|
|
3612
|
+
const existing = table.get(key);
|
|
3613
|
+
if (existing) {
|
|
3614
|
+
existing.refs += 1;
|
|
3615
|
+
return;
|
|
3127
3616
|
}
|
|
3128
|
-
|
|
3129
|
-
tag.textContent = css;
|
|
3130
|
-
tag.dataset.jxOwner = uid;
|
|
3131
|
-
document.head.append(tag);
|
|
3132
|
-
elementStyleTags.set(el, tag);
|
|
3617
|
+
table.set(key, { inserted: state.shared.insert(texts), refs: 1 });
|
|
3133
3618
|
}
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3619
|
+
function releaseElementStyles(el, only) {
|
|
3620
|
+
const entry = elementStyles.get(el);
|
|
3621
|
+
if (!entry || only !== undefined && entry !== only) {
|
|
3622
|
+
return;
|
|
3623
|
+
}
|
|
3624
|
+
elementStyles.delete(el);
|
|
3625
|
+
entry.stop?.();
|
|
3626
|
+
for (const name of entry.vars) {
|
|
3627
|
+
el.style.removeProperty(name);
|
|
3140
3628
|
}
|
|
3141
|
-
el.style.cssText = "";
|
|
3142
3629
|
delete el.dataset.jx;
|
|
3143
|
-
|
|
3630
|
+
if (sheetStates.get(entry.doc) !== entry.state) {
|
|
3631
|
+
return;
|
|
3632
|
+
}
|
|
3633
|
+
const { state } = entry;
|
|
3634
|
+
if (entry.interned === null) {
|
|
3635
|
+
if (state.scratchOwners.delete(el)) {
|
|
3636
|
+
rewriteScratch(state);
|
|
3637
|
+
}
|
|
3638
|
+
} else {
|
|
3639
|
+
releaseInterned(state, state.interned, entry.interned);
|
|
3640
|
+
}
|
|
3641
|
+
for (const key of entry.hoisted) {
|
|
3642
|
+
releaseInterned(state, state.hoisted, key);
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
function resetDocumentStyles(doc = document) {
|
|
3646
|
+
const state = sheetStates.get(doc);
|
|
3647
|
+
if (!state) {
|
|
3648
|
+
return;
|
|
3649
|
+
}
|
|
3650
|
+
sheetStates.delete(doc);
|
|
3651
|
+
for (const el of state.scratchOwners.keys()) {
|
|
3652
|
+
elementStyles.delete(el);
|
|
3653
|
+
delete el.dataset.jx;
|
|
3654
|
+
}
|
|
3655
|
+
state.scratchOwners.clear();
|
|
3656
|
+
state.interned.clear();
|
|
3657
|
+
state.hoisted.clear();
|
|
3658
|
+
state.shared.detach();
|
|
3659
|
+
state.scratch?.detach();
|
|
3660
|
+
}
|
|
3661
|
+
function declaresDisplay(style) {
|
|
3662
|
+
return Boolean(style) && typeof style === "object" && "display" in style;
|
|
3663
|
+
}
|
|
3664
|
+
var callSiteStyles = new WeakMap;
|
|
3665
|
+
function mergeStyle(base, over) {
|
|
3666
|
+
if (!over) {
|
|
3667
|
+
return base;
|
|
3668
|
+
}
|
|
3669
|
+
const out = { ...base };
|
|
3670
|
+
for (const [key, value] of Object.entries(over)) {
|
|
3671
|
+
const prior = out[key];
|
|
3672
|
+
out[key] = prior !== null && typeof prior === "object" && value !== null && typeof value === "object" && !Array.isArray(value) ? mergeStyle(prior, value) : value;
|
|
3673
|
+
}
|
|
3674
|
+
return out;
|
|
3675
|
+
}
|
|
3676
|
+
function applyStyle(el, styleDef, mediaQueries = {}, state = {}) {
|
|
3677
|
+
applyStyleInto(el, styleDef, mediaQueries, state, false);
|
|
3678
|
+
}
|
|
3679
|
+
function reapplyStyle(el, styleDef, mediaQueries = {}, state = {}) {
|
|
3680
|
+
applyStyleInto(el, styleDef ?? {}, mediaQueries, state, true);
|
|
3681
|
+
}
|
|
3682
|
+
function applyStyleInto(el, styleDef, mediaQueries, state, live) {
|
|
3683
|
+
releaseElementStyles(el);
|
|
3684
|
+
const doc = el.ownerDocument ?? document;
|
|
3685
|
+
const sheetState = sheetStateFor(doc);
|
|
3686
|
+
const transposeSelector = (_canvasDelinkPopovers || _canvasDelinkCommands) && canvasStamped(el) ? (selector) => transposeCanvasOverlaySelector(selector, {
|
|
3687
|
+
dialog: el.tagName === "DIALOG"
|
|
3688
|
+
}) : (selector) => selector;
|
|
3689
|
+
let serial = -1;
|
|
3690
|
+
let indirect = 0;
|
|
3691
|
+
const sources = [];
|
|
3692
|
+
const rules = buildStyleRules(styleDef, {
|
|
3693
|
+
mediaQueries,
|
|
3694
|
+
resolveValue: (property, value, target) => {
|
|
3695
|
+
if (target === "self" && property.startsWith("--")) {
|
|
3696
|
+
sources.push({ name: property, value });
|
|
3697
|
+
return null;
|
|
3698
|
+
}
|
|
3699
|
+
if (serial < 0) {
|
|
3700
|
+
({ serial } = sheetState);
|
|
3701
|
+
sheetState.serial += 1;
|
|
3702
|
+
}
|
|
3703
|
+
const name = `--jx-r${serial}-${indirect}`;
|
|
3704
|
+
indirect += 1;
|
|
3705
|
+
sources.push({ name, value });
|
|
3706
|
+
return `var(${name})`;
|
|
3707
|
+
},
|
|
3708
|
+
scope: SCOPE_TOKEN,
|
|
3709
|
+
transposeSelector,
|
|
3710
|
+
transposeValue: canvasStyleValue
|
|
3711
|
+
});
|
|
3712
|
+
if (rules.length === 0 && sources.length === 0) {
|
|
3713
|
+
return;
|
|
3714
|
+
}
|
|
3715
|
+
const scoped = rules.filter((rule) => rule.target !== "unscoped");
|
|
3716
|
+
const unscoped = rules.filter((rule) => rule.target === "unscoped");
|
|
3717
|
+
for (const rule of unscoped) {
|
|
3718
|
+
retainInterned(sheetState, sheetState.hoisted, rule.text, [rule.text]);
|
|
3719
|
+
}
|
|
3720
|
+
const uid = `jx-${hashCss(scoped.map((rule) => rule.key).join("|"))}`;
|
|
3721
|
+
const texts = scoped.map((rule) => rule.text.replaceAll(SCOPE_TOKEN, `[data-jx="${uid}"]`));
|
|
3722
|
+
if (texts.length > 0) {
|
|
3723
|
+
el.dataset.jx = uid;
|
|
3724
|
+
if (live) {
|
|
3725
|
+
sheetState.scratch ??= openSink(doc);
|
|
3726
|
+
sheetState.scratchOwners.set(el, texts);
|
|
3727
|
+
rewriteScratch(sheetState);
|
|
3728
|
+
} else {
|
|
3729
|
+
retainInterned(sheetState, sheetState.interned, uid, texts);
|
|
3730
|
+
}
|
|
3731
|
+
}
|
|
3732
|
+
const entry = {
|
|
3733
|
+
doc,
|
|
3734
|
+
hoisted: unscoped.map((rule) => rule.text),
|
|
3735
|
+
interned: texts.length > 0 && !live ? uid : null,
|
|
3736
|
+
state: sheetState,
|
|
3737
|
+
stop: null,
|
|
3738
|
+
uid,
|
|
3739
|
+
vars: sources.map((source) => source.name)
|
|
3740
|
+
};
|
|
3741
|
+
if (sources.length > 0) {
|
|
3742
|
+
const scope = effectScope();
|
|
3743
|
+
scope.run(() => {
|
|
3744
|
+
for (const { name, value } of sources) {
|
|
3745
|
+
effect(() => {
|
|
3746
|
+
const resolved = isRefObj(value) ? resolveRef(value.$ref, state) : evaluateTemplate(value, state);
|
|
3747
|
+
el.style.setProperty(name, canvasStyleValue(String(resolved ?? "")));
|
|
3748
|
+
});
|
|
3749
|
+
}
|
|
3750
|
+
});
|
|
3751
|
+
entry.stop = () => scope.stop();
|
|
3752
|
+
}
|
|
3753
|
+
elementStyles.set(el, entry);
|
|
3754
|
+
onScopeDispose(() => releaseElementStyles(el, entry), true);
|
|
3144
3755
|
}
|
|
3145
3756
|
var ENUMERATED_ATTRS = new Set(["contenteditable", "draggable", "spellcheck"]);
|
|
3146
3757
|
function booleanAttrValue(name, value) {
|
|
@@ -3154,6 +3765,10 @@ function applyAttributes(el, attrs, state) {
|
|
|
3154
3765
|
for (const [k, v] of Object.entries(attrs)) {
|
|
3155
3766
|
const attr = canvasAttrName(el, k);
|
|
3156
3767
|
const write = (resolved) => {
|
|
3768
|
+
if (resolved === null || resolved === undefined) {
|
|
3769
|
+
el.removeAttribute(attr);
|
|
3770
|
+
return;
|
|
3771
|
+
}
|
|
3157
3772
|
if (typeof resolved === "boolean") {
|
|
3158
3773
|
const text = booleanAttrValue(attr, resolved);
|
|
3159
3774
|
if (text === null) {
|
|
@@ -3163,7 +3778,7 @@ function applyAttributes(el, attrs, state) {
|
|
|
3163
3778
|
}
|
|
3164
3779
|
return;
|
|
3165
3780
|
}
|
|
3166
|
-
el.setAttribute(attr, canvasAssetValue(el.tagName, k, String(resolved
|
|
3781
|
+
el.setAttribute(attr, canvasAssetValue(el.tagName, k, String(resolved)));
|
|
3167
3782
|
};
|
|
3168
3783
|
if (isRefObj(v)) {
|
|
3169
3784
|
effect(() => write(resolveRef(v.$ref, state)));
|
|
@@ -3178,8 +3793,70 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
3178
3793
|
const path = options?._path ?? [];
|
|
3179
3794
|
const anchor = document.createComment("jx-array");
|
|
3180
3795
|
parentEl.append(anchor);
|
|
3181
|
-
const { items: itemsSrc, map: mapDef, filter: filterRef, sort: sortRef } = arrayDef;
|
|
3182
|
-
|
|
3796
|
+
const { items: itemsSrc, map: mapDef, filter: filterRef, sort: sortRef, key: keyRef } = arrayDef;
|
|
3797
|
+
const keyPointer = isRefObj(keyRef) ? keyRef.$ref : null;
|
|
3798
|
+
const instancePath = _instancePath;
|
|
3799
|
+
let warned = false;
|
|
3800
|
+
const warnOnce = (message) => {
|
|
3801
|
+
if (!warned) {
|
|
3802
|
+
warned = true;
|
|
3803
|
+
console.warn(`Jx $map: ${message}`);
|
|
3804
|
+
}
|
|
3805
|
+
};
|
|
3806
|
+
let rows = [];
|
|
3807
|
+
const teardown = (row) => {
|
|
3808
|
+
row.scope.stop();
|
|
3809
|
+
row.node.remove();
|
|
3810
|
+
};
|
|
3811
|
+
const createRow = (key, item, index) => {
|
|
3812
|
+
const map = shallowReactive({ index, item });
|
|
3813
|
+
const child = Object.create(state);
|
|
3814
|
+
child.$map = map;
|
|
3815
|
+
Object.defineProperty(child, "$map/item", { enumerable: true, get: () => map.item });
|
|
3816
|
+
Object.defineProperty(child, "$map/index", { enumerable: true, get: () => map.index });
|
|
3817
|
+
const scope = effectScope(true);
|
|
3818
|
+
const childOpts = options ? { ...options, _path: [...path, "map", index] } : undefined;
|
|
3819
|
+
const node = scope.run(() => renderNode(mapDef, child, childOpts));
|
|
3820
|
+
return { key, map, node, scope };
|
|
3821
|
+
};
|
|
3822
|
+
const reconcile = (list, keys) => {
|
|
3823
|
+
const previous = new Map;
|
|
3824
|
+
for (const row of rows) {
|
|
3825
|
+
previous.set(row.key, row);
|
|
3826
|
+
}
|
|
3827
|
+
const next = [];
|
|
3828
|
+
for (let index = 0;index < list.length; index++) {
|
|
3829
|
+
const key = keys[index];
|
|
3830
|
+
const item = list[index];
|
|
3831
|
+
const existing = previous.get(key);
|
|
3832
|
+
if (existing) {
|
|
3833
|
+
previous.delete(key);
|
|
3834
|
+
if (existing.map.item !== item) {
|
|
3835
|
+
existing.map.item = item;
|
|
3836
|
+
}
|
|
3837
|
+
if (existing.map.index !== index) {
|
|
3838
|
+
existing.map.index = index;
|
|
3839
|
+
options?.onNodeMoved?.(existing.node, [...path, "map", index]);
|
|
3840
|
+
}
|
|
3841
|
+
next.push(existing);
|
|
3842
|
+
} else {
|
|
3843
|
+
next.push(createRow(key, item, index));
|
|
3844
|
+
}
|
|
3845
|
+
}
|
|
3846
|
+
for (const row of previous.values()) {
|
|
3847
|
+
teardown(row);
|
|
3848
|
+
}
|
|
3849
|
+
let cursor = rows.find((row) => !previous.has(row.key))?.node ?? anchor;
|
|
3850
|
+
for (const row of next) {
|
|
3851
|
+
if (row.node === cursor) {
|
|
3852
|
+
cursor = cursor.nextSibling ?? anchor;
|
|
3853
|
+
continue;
|
|
3854
|
+
}
|
|
3855
|
+
cursor.before(row.node);
|
|
3856
|
+
}
|
|
3857
|
+
rows = next;
|
|
3858
|
+
};
|
|
3859
|
+
const update = () => {
|
|
3183
3860
|
let items = isRefObj(itemsSrc) ? resolveRef(itemsSrc.$ref, state) : itemsSrc;
|
|
3184
3861
|
if (Array.isArray(items) && isRefObj(filterRef)) {
|
|
3185
3862
|
const fn = resolveRef(filterRef.$ref, state);
|
|
@@ -3193,30 +3870,65 @@ function renderMappedArrayInto(parentEl, arrayDef, state, options) {
|
|
|
3193
3870
|
items = [...items].toSorted(fn);
|
|
3194
3871
|
}
|
|
3195
3872
|
}
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
child["$map/item"] = item;
|
|
3206
|
-
child["$map/index"] = index;
|
|
3207
|
-
const childOpts = options ? { ...options, _path: [...path, "map", index] } : undefined;
|
|
3208
|
-
const node = renderNode(mapDef, child, childOpts);
|
|
3209
|
-
anchor.before(node);
|
|
3210
|
-
nodes.push(node);
|
|
3873
|
+
const list = Array.isArray(items) && mapDef ? items : [];
|
|
3874
|
+
const keys = list.map((item, index) => mappedRowKey(keyPointer, item, index, warnOnce));
|
|
3875
|
+
const seen = new Set;
|
|
3876
|
+
for (let i = 0;i < keys.length; i++) {
|
|
3877
|
+
if (seen.has(keys[i])) {
|
|
3878
|
+
warnOnce(`duplicate key ${String(keys[i])} — every occurrence after the first is rebuilt on each change`);
|
|
3879
|
+
keys[i] = { duplicate: i };
|
|
3880
|
+
} else {
|
|
3881
|
+
seen.add(keys[i]);
|
|
3211
3882
|
}
|
|
3212
|
-
}
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3883
|
+
}
|
|
3884
|
+
pauseTracking();
|
|
3885
|
+
try {
|
|
3886
|
+
underInstancePath(reexpand(instancePath), () => reconcile(list, keys));
|
|
3887
|
+
} finally {
|
|
3888
|
+
resetTracking();
|
|
3889
|
+
}
|
|
3890
|
+
};
|
|
3891
|
+
let queued = false;
|
|
3892
|
+
let stopped = false;
|
|
3893
|
+
const runner = effect(update, {
|
|
3894
|
+
scheduler: () => {
|
|
3895
|
+
if (queued) {
|
|
3896
|
+
return;
|
|
3217
3897
|
}
|
|
3218
|
-
|
|
3898
|
+
queued = true;
|
|
3899
|
+
queueMicrotask(() => {
|
|
3900
|
+
queued = false;
|
|
3901
|
+
if (!stopped) {
|
|
3902
|
+
runner();
|
|
3903
|
+
}
|
|
3904
|
+
});
|
|
3905
|
+
}
|
|
3219
3906
|
});
|
|
3907
|
+
onScopeDispose(() => {
|
|
3908
|
+
stopped = true;
|
|
3909
|
+
for (const row of rows) {
|
|
3910
|
+
teardown(row);
|
|
3911
|
+
}
|
|
3912
|
+
rows = [];
|
|
3913
|
+
}, true);
|
|
3914
|
+
}
|
|
3915
|
+
function mappedRowKey(pointer, item, index, warnOnce) {
|
|
3916
|
+
if (pointer === null) {
|
|
3917
|
+
return index;
|
|
3918
|
+
}
|
|
3919
|
+
if (pointer === "$map/item") {
|
|
3920
|
+
return item;
|
|
3921
|
+
}
|
|
3922
|
+
if (pointer.startsWith("$map/item/")) {
|
|
3923
|
+
const key = readPath(item, pointer.slice("$map/item/".length));
|
|
3924
|
+
if (key === undefined || key === null) {
|
|
3925
|
+
warnOnce(`key "${pointer}" is empty for some items — those rows fall back to their index`);
|
|
3926
|
+
return index;
|
|
3927
|
+
}
|
|
3928
|
+
return key;
|
|
3929
|
+
}
|
|
3930
|
+
warnOnce(`key "${pointer}" is not a $map/item pointer — rows fall back to their index`);
|
|
3931
|
+
return index;
|
|
3220
3932
|
}
|
|
3221
3933
|
function resolveTagName(tagName, scope) {
|
|
3222
3934
|
if (typeof tagName === "string") {
|
|
@@ -3232,65 +3944,87 @@ function resolveTagName(tagName, scope) {
|
|
|
3232
3944
|
const key = evaluateOperand(expression.target, scope, null);
|
|
3233
3945
|
return expression.cases[String(key)] ?? expression.default;
|
|
3234
3946
|
}
|
|
3235
|
-
function renderSwitch(
|
|
3947
|
+
function renderSwitch(def, state, options) {
|
|
3236
3948
|
const path = options?._path ?? [];
|
|
3237
|
-
const container = document.createElement(resolveTagName(
|
|
3949
|
+
const container = document.createElement(resolveTagName(def.tagName, state));
|
|
3950
|
+
const instancePath = _instancePath;
|
|
3238
3951
|
if (options?.onNodeCreated) {
|
|
3239
|
-
options.onNodeCreated(container, path,
|
|
3952
|
+
options.onNodeCreated(container, path, def, state);
|
|
3240
3953
|
}
|
|
3241
|
-
applyProperties(container,
|
|
3242
|
-
applyStyle(container,
|
|
3243
|
-
applyAttributes(container,
|
|
3954
|
+
applyProperties(container, def, state);
|
|
3955
|
+
applyStyle(container, def.style ?? {}, state["$media"] ?? {}, state);
|
|
3956
|
+
applyAttributes(container, def.attributes ?? {}, state);
|
|
3244
3957
|
let generation = 0;
|
|
3958
|
+
let live = null;
|
|
3959
|
+
let renderedKey = null;
|
|
3960
|
+
const retire = () => {
|
|
3961
|
+
live?.stop();
|
|
3962
|
+
live = null;
|
|
3963
|
+
};
|
|
3245
3964
|
effect(() => {
|
|
3246
|
-
|
|
3247
|
-
|
|
3965
|
+
if (!isRefObj(def.$switch)) {
|
|
3966
|
+
retire();
|
|
3967
|
+
container.replaceChildren();
|
|
3968
|
+
generation += 1;
|
|
3248
3969
|
return;
|
|
3249
3970
|
}
|
|
3250
|
-
const key = resolveRef(
|
|
3251
|
-
|
|
3971
|
+
const key = String(resolveRef(def.$switch.$ref, state));
|
|
3972
|
+
if (key === renderedKey) {
|
|
3973
|
+
return;
|
|
3974
|
+
}
|
|
3975
|
+
renderedKey = key;
|
|
3976
|
+
retire();
|
|
3977
|
+
container.replaceChildren();
|
|
3978
|
+
generation += 1;
|
|
3979
|
+
const caseDef = def.cases?.[key];
|
|
3252
3980
|
if (!caseDef) {
|
|
3253
3981
|
return;
|
|
3254
3982
|
}
|
|
3983
|
+
const gen = generation;
|
|
3984
|
+
const scope = effectScope(true);
|
|
3985
|
+
live = scope;
|
|
3986
|
+
const childOpts = options ? { ...options, _path: [...path, "cases", key] } : undefined;
|
|
3255
3987
|
if (isRefObj(caseDef)) {
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
const { href } = new URL(caseDef.$ref, location.href);
|
|
3259
|
-
resolve(href).then(async (doc) => {
|
|
3988
|
+
const { href } = new URL(caseDef.$ref, options?._ctx?.base ?? location.href);
|
|
3989
|
+
resolve(href, options?._ctx).then(async (doc) => {
|
|
3260
3990
|
if (gen !== generation) {
|
|
3261
3991
|
return;
|
|
3262
3992
|
}
|
|
3263
|
-
const childScope = await buildScope(doc, {}, href);
|
|
3993
|
+
const childScope = await buildScope(doc, {}, href, options?._ctx);
|
|
3264
3994
|
if (gen !== generation) {
|
|
3265
3995
|
return;
|
|
3266
3996
|
}
|
|
3267
3997
|
container.replaceChildren();
|
|
3268
|
-
|
|
3269
|
-
container.append(renderNode(doc, childScope, childOpts2));
|
|
3998
|
+
underInstancePath(reexpand(instancePath), () => scope.run(() => container.append(renderNode(doc, childScope, childOpts))));
|
|
3270
3999
|
}).catch((error) => console.error("Jx $switch: failed to load external case", caseDef.$ref, error));
|
|
3271
4000
|
return;
|
|
3272
4001
|
}
|
|
3273
|
-
|
|
3274
|
-
|
|
4002
|
+
pauseTracking();
|
|
4003
|
+
try {
|
|
4004
|
+
underInstancePath(reexpand(instancePath), () => scope.run(() => container.append(renderNode(caseDef, state, childOpts))));
|
|
4005
|
+
} finally {
|
|
4006
|
+
resetTracking();
|
|
4007
|
+
}
|
|
3275
4008
|
});
|
|
4009
|
+
onScopeDispose(retire, true);
|
|
3276
4010
|
return container;
|
|
3277
4011
|
}
|
|
3278
|
-
async function resolvePrototype(
|
|
3279
|
-
if (
|
|
3280
|
-
return resolveExternalPrototype(
|
|
4012
|
+
async function resolvePrototype(def, state, key, base, ctx) {
|
|
4013
|
+
if (def.$src) {
|
|
4014
|
+
return resolveExternalPrototype(def, state, key, base);
|
|
3281
4015
|
}
|
|
3282
|
-
switch (
|
|
4016
|
+
switch (def.$prototype) {
|
|
3283
4017
|
case "Request": {
|
|
3284
4018
|
const s = ref(null);
|
|
3285
|
-
const debounceMs =
|
|
4019
|
+
const debounceMs = def.debounce ?? 0;
|
|
3286
4020
|
let debounceTimer = null;
|
|
3287
|
-
if (!
|
|
4021
|
+
if (!def.manual && !(ctx?.skipAutoRequests ?? _autoRequestConfig.skip)) {
|
|
3288
4022
|
effect(() => {
|
|
3289
4023
|
let url;
|
|
3290
|
-
if (isTemplateString(
|
|
3291
|
-
url = evaluateTemplate(
|
|
4024
|
+
if (isTemplateString(def.url)) {
|
|
4025
|
+
url = evaluateTemplate(def.url, state);
|
|
3292
4026
|
} else {
|
|
3293
|
-
({ url } =
|
|
4027
|
+
({ url } = def);
|
|
3294
4028
|
}
|
|
3295
4029
|
if (!url || url === "undefined" || url.includes("undefined")) {
|
|
3296
4030
|
return;
|
|
@@ -3303,11 +4037,11 @@ async function resolvePrototype(def2, state, key, base) {
|
|
|
3303
4037
|
}
|
|
3304
4038
|
});
|
|
3305
4039
|
const doFetch = () => fetch(url, {
|
|
3306
|
-
method:
|
|
4040
|
+
method: def.method ?? "GET",
|
|
3307
4041
|
signal: controller.signal,
|
|
3308
|
-
...
|
|
3309
|
-
...
|
|
3310
|
-
body: typeof
|
|
4042
|
+
...def.headers && { headers: def.headers },
|
|
4043
|
+
...def.body && {
|
|
4044
|
+
body: typeof def.body === "object" ? JSON.stringify(def.body) : def.body
|
|
3311
4045
|
}
|
|
3312
4046
|
}).then((r) => r.ok ? r.json() : Promise.reject(r.statusText)).then((d) => {
|
|
3313
4047
|
s.value = d;
|
|
@@ -3328,7 +4062,7 @@ async function resolvePrototype(def2, state, key, base) {
|
|
|
3328
4062
|
case "URLSearchParams": {
|
|
3329
4063
|
return computed(() => {
|
|
3330
4064
|
const p = {};
|
|
3331
|
-
for (const [k, v] of Object.entries(
|
|
4065
|
+
for (const [k, v] of Object.entries(def)) {
|
|
3332
4066
|
if (k !== "$prototype") {
|
|
3333
4067
|
p[k] = isRefObj(v) ? resolveRef(v.$ref, state) : isTemplateString(v) ? evaluateTemplate(v, state) : v;
|
|
3334
4068
|
}
|
|
@@ -3338,14 +4072,14 @@ async function resolvePrototype(def2, state, key, base) {
|
|
|
3338
4072
|
}
|
|
3339
4073
|
case "LocalStorage":
|
|
3340
4074
|
case "SessionStorage": {
|
|
3341
|
-
const store =
|
|
3342
|
-
const k =
|
|
4075
|
+
const store = def.$prototype === "LocalStorage" ? localStorage : sessionStorage;
|
|
4076
|
+
const k = def.key ?? key;
|
|
3343
4077
|
let init;
|
|
3344
4078
|
try {
|
|
3345
4079
|
const s = store.getItem(k);
|
|
3346
|
-
init = s !== null ? JSON.parse(s) :
|
|
4080
|
+
init = s !== null ? JSON.parse(s) : def.default ?? null;
|
|
3347
4081
|
} catch {
|
|
3348
|
-
init =
|
|
4082
|
+
init = def.default ?? null;
|
|
3349
4083
|
}
|
|
3350
4084
|
const storageState = ref(init);
|
|
3351
4085
|
effect(() => {
|
|
@@ -3363,7 +4097,7 @@ async function resolvePrototype(def2, state, key, base) {
|
|
|
3363
4097
|
return storageState;
|
|
3364
4098
|
}
|
|
3365
4099
|
case "Cookie": {
|
|
3366
|
-
const name =
|
|
4100
|
+
const name = def.name ?? key;
|
|
3367
4101
|
const read = () => {
|
|
3368
4102
|
const raw = readCookie(document.cookie, name);
|
|
3369
4103
|
if (raw === null) {
|
|
@@ -3375,9 +4109,9 @@ async function resolvePrototype(def2, state, key, base) {
|
|
|
3375
4109
|
return raw;
|
|
3376
4110
|
}
|
|
3377
4111
|
};
|
|
3378
|
-
const cookieState = ref(read() ??
|
|
4112
|
+
const cookieState = ref(read() ?? def.default ?? null);
|
|
3379
4113
|
effect(() => {
|
|
3380
|
-
document.cookie = serializeCookie(name, cookieState.value,
|
|
4114
|
+
document.cookie = serializeCookie(name, cookieState.value, def);
|
|
3381
4115
|
});
|
|
3382
4116
|
return cookieState;
|
|
3383
4117
|
}
|
|
@@ -3390,7 +4124,7 @@ async function resolvePrototype(def2, state, key, base) {
|
|
|
3390
4124
|
keyPath = "id",
|
|
3391
4125
|
autoIncrement = true,
|
|
3392
4126
|
indexes = []
|
|
3393
|
-
} =
|
|
4127
|
+
} = def;
|
|
3394
4128
|
if (!database || !store) {
|
|
3395
4129
|
throw new Error(`Jx: IndexedDB entry '${key}' requires database and store`);
|
|
3396
4130
|
}
|
|
@@ -3420,28 +4154,28 @@ async function resolvePrototype(def2, state, key, base) {
|
|
|
3420
4154
|
return idbState;
|
|
3421
4155
|
}
|
|
3422
4156
|
case "Set": {
|
|
3423
|
-
return new Set(Array.isArray(
|
|
4157
|
+
return new Set(Array.isArray(def.default) ? def.default : []);
|
|
3424
4158
|
}
|
|
3425
4159
|
case "Map": {
|
|
3426
|
-
return new Map(Object.entries(isJsonObject(
|
|
4160
|
+
return new Map(Object.entries(isJsonObject(def.default) ? def.default : {}));
|
|
3427
4161
|
}
|
|
3428
4162
|
case "FormData": {
|
|
3429
4163
|
const fd = new FormData;
|
|
3430
|
-
for (const [k, v] of Object.entries(
|
|
4164
|
+
for (const [k, v] of Object.entries(def.fields ?? {})) {
|
|
3431
4165
|
fd.append(k, v);
|
|
3432
4166
|
}
|
|
3433
4167
|
return fd;
|
|
3434
4168
|
}
|
|
3435
4169
|
case "Blob": {
|
|
3436
|
-
return new Blob(
|
|
3437
|
-
type: typeof
|
|
4170
|
+
return new Blob(def.parts ?? [], {
|
|
4171
|
+
type: typeof def.type === "string" ? def.type : "text/plain"
|
|
3438
4172
|
});
|
|
3439
4173
|
}
|
|
3440
4174
|
case "ReadableStream": {
|
|
3441
4175
|
return null;
|
|
3442
4176
|
}
|
|
3443
4177
|
default: {
|
|
3444
|
-
console.warn(`Jx: unknown $prototype "${
|
|
4178
|
+
console.warn(`Jx: unknown $prototype "${def.$prototype}" for "${key}". Did you mean to add '$src'?`);
|
|
3445
4179
|
return ref(null);
|
|
3446
4180
|
}
|
|
3447
4181
|
}
|
|
@@ -3458,17 +4192,20 @@ var EXTERNAL_RESERVED = new Set([
|
|
|
3458
4192
|
"arguments",
|
|
3459
4193
|
"name"
|
|
3460
4194
|
]);
|
|
3461
|
-
async function resolveExternalPrototype(
|
|
3462
|
-
const src =
|
|
4195
|
+
async function resolveExternalPrototype(def, state, key, base) {
|
|
4196
|
+
const src = def.$src;
|
|
3463
4197
|
if (!src || !src.endsWith(".class.json")) {
|
|
3464
|
-
throw new Error(`Jx: $prototype "${
|
|
4198
|
+
throw new Error(`Jx: $prototype "${def.$prototype}" requires a .class.json $src, got "${src}". Wrap the class in a .class.json schema with $implementation.`);
|
|
3465
4199
|
}
|
|
3466
|
-
return resolveClassJson(
|
|
4200
|
+
return resolveClassJson(def, state, key, base);
|
|
3467
4201
|
}
|
|
3468
|
-
async function importAndInstantiate(
|
|
4202
|
+
async function importAndInstantiate(def, src, exportName, base) {
|
|
3469
4203
|
let mod;
|
|
3470
|
-
|
|
3471
|
-
|
|
4204
|
+
const seeded = seededModule(src);
|
|
4205
|
+
if (seeded instanceof Promise) {
|
|
4206
|
+
mod = await seeded;
|
|
4207
|
+
} else if (seeded) {
|
|
4208
|
+
mod = seeded;
|
|
3472
4209
|
} else {
|
|
3473
4210
|
try {
|
|
3474
4211
|
mod = await import(src);
|
|
@@ -3490,7 +4227,7 @@ async function importAndInstantiate(def2, src, exportName, base) {
|
|
|
3490
4227
|
throw new TypeError(`Jx: "${exportName}" from "${src}" is not a class`);
|
|
3491
4228
|
}
|
|
3492
4229
|
const config = {};
|
|
3493
|
-
for (const [k, v] of Object.entries(
|
|
4230
|
+
for (const [k, v] of Object.entries(def)) {
|
|
3494
4231
|
if (!EXTERNAL_RESERVED.has(k)) {
|
|
3495
4232
|
config[k] = v;
|
|
3496
4233
|
}
|
|
@@ -3513,15 +4250,15 @@ async function importAndInstantiate(def2, src, exportName, base) {
|
|
|
3513
4250
|
}
|
|
3514
4251
|
return s;
|
|
3515
4252
|
}
|
|
3516
|
-
async function resolveClassJson(
|
|
3517
|
-
const src =
|
|
4253
|
+
async function resolveClassJson(def, state, key, base) {
|
|
4254
|
+
const src = def.$src;
|
|
3518
4255
|
if (!src) {
|
|
3519
4256
|
throw new Error(`Jx: class entry '${key}' has no $src`);
|
|
3520
4257
|
}
|
|
3521
4258
|
let classDef;
|
|
3522
4259
|
const isBareSpecifier = !src.startsWith(".") && !src.startsWith("/") && !src.startsWith("http") && !src.startsWith("file:");
|
|
3523
4260
|
if (isBareSpecifier) {
|
|
3524
|
-
return resolveViaDevProxy(
|
|
4261
|
+
return resolveViaDevProxy(def, state, key, base);
|
|
3525
4262
|
}
|
|
3526
4263
|
try {
|
|
3527
4264
|
const url = base ? new URL(src, base).href : src;
|
|
@@ -3531,25 +4268,25 @@ async function resolveClassJson(def2, state, key, base) {
|
|
|
3531
4268
|
}
|
|
3532
4269
|
classDef = await res.json();
|
|
3533
4270
|
} catch {
|
|
3534
|
-
return resolveViaDevProxy(
|
|
4271
|
+
return resolveViaDevProxy(def, state, key, base);
|
|
3535
4272
|
}
|
|
3536
4273
|
if (classDef.$implementation) {
|
|
3537
4274
|
const schemaStr = JSON.stringify(classDef);
|
|
3538
4275
|
if (schemaStr.includes('"#/$context/')) {
|
|
3539
|
-
return resolveViaDevProxy(
|
|
4276
|
+
return resolveViaDevProxy(def, state, key, base);
|
|
3540
4277
|
}
|
|
3541
4278
|
const schemaUrl = base ? new URL(src, base).href : new URL(src, location.href).href;
|
|
3542
4279
|
const implSrc = new URL(classDef.$implementation, schemaUrl).href;
|
|
3543
|
-
const exportName =
|
|
4280
|
+
const exportName = def.$export ?? classDef.title ?? def.$prototype;
|
|
3544
4281
|
try {
|
|
3545
|
-
return await importAndInstantiate(
|
|
4282
|
+
return await importAndInstantiate(def, implSrc, exportName, base);
|
|
3546
4283
|
} catch {
|
|
3547
|
-
return resolveViaDevProxy(
|
|
4284
|
+
return resolveViaDevProxy(def, state, key, base);
|
|
3548
4285
|
}
|
|
3549
4286
|
}
|
|
3550
4287
|
const DynClass = classFromSchema(classDef);
|
|
3551
4288
|
const config = {};
|
|
3552
|
-
for (const [k, v] of Object.entries(
|
|
4289
|
+
for (const [k, v] of Object.entries(def)) {
|
|
3553
4290
|
if (!EXTERNAL_RESERVED.has(k)) {
|
|
3554
4291
|
config[k] = v;
|
|
3555
4292
|
}
|
|
@@ -3636,9 +4373,9 @@ function classFromSchema(classDef) {
|
|
|
3636
4373
|
const dynCtor = DynClass;
|
|
3637
4374
|
return dynCtor;
|
|
3638
4375
|
}
|
|
3639
|
-
async function resolveViaDevProxy(
|
|
4376
|
+
async function resolveViaDevProxy(def, state, key, base) {
|
|
3640
4377
|
const config = {};
|
|
3641
|
-
for (const [k, v] of Object.entries(
|
|
4378
|
+
for (const [k, v] of Object.entries(def)) {
|
|
3642
4379
|
if (!EXTERNAL_RESERVED.has(k)) {
|
|
3643
4380
|
config[k] = v;
|
|
3644
4381
|
}
|
|
@@ -3647,9 +4384,9 @@ async function resolveViaDevProxy(def2, state, key, base) {
|
|
|
3647
4384
|
const doResolve = (resolvedConfig) => fetch(resolveProxyPath("/__jx_resolve__"), {
|
|
3648
4385
|
body: JSON.stringify({
|
|
3649
4386
|
$base: base,
|
|
3650
|
-
$export:
|
|
3651
|
-
$prototype:
|
|
3652
|
-
$src:
|
|
4387
|
+
$export: def.$export,
|
|
4388
|
+
$prototype: def.$prototype,
|
|
4389
|
+
$src: def.$src,
|
|
3653
4390
|
...resolvedConfig
|
|
3654
4391
|
}),
|
|
3655
4392
|
headers: { "Content-Type": "application/json" },
|
|
@@ -3678,12 +4415,15 @@ async function resolveViaDevProxy(def2, state, key, base) {
|
|
|
3678
4415
|
}
|
|
3679
4416
|
return s;
|
|
3680
4417
|
}
|
|
3681
|
-
async function resolveServerFunction(
|
|
3682
|
-
const src =
|
|
3683
|
-
const exportName =
|
|
4418
|
+
async function resolveServerFunction(def, state, key, base) {
|
|
4419
|
+
const src = def.$src;
|
|
4420
|
+
const exportName = def.$export;
|
|
3684
4421
|
let mod;
|
|
3685
|
-
|
|
3686
|
-
|
|
4422
|
+
const seeded = seededModule(src);
|
|
4423
|
+
if (seeded instanceof Promise) {
|
|
4424
|
+
mod = await seeded;
|
|
4425
|
+
} else if (seeded) {
|
|
4426
|
+
mod = seeded;
|
|
3687
4427
|
} else {
|
|
3688
4428
|
try {
|
|
3689
4429
|
mod = await import(src);
|
|
@@ -3693,10 +4433,10 @@ async function resolveServerFunction(def2, state, key, base) {
|
|
|
3693
4433
|
const resolvedSrc = new URL(src, base).href;
|
|
3694
4434
|
mod = await import(resolvedSrc);
|
|
3695
4435
|
} catch {
|
|
3696
|
-
return resolveServerFunctionViaProxy(
|
|
4436
|
+
return resolveServerFunctionViaProxy(def, state, key, base);
|
|
3697
4437
|
}
|
|
3698
4438
|
} else {
|
|
3699
|
-
return resolveServerFunctionViaProxy(
|
|
4439
|
+
return resolveServerFunctionViaProxy(def, state, key, base);
|
|
3700
4440
|
}
|
|
3701
4441
|
}
|
|
3702
4442
|
_moduleCache.set(src, mod);
|
|
@@ -3709,7 +4449,7 @@ async function resolveServerFunction(def2, state, key, base) {
|
|
|
3709
4449
|
throw new TypeError(`Jx: "${exportName}" from "${src}" is not a function`);
|
|
3710
4450
|
}
|
|
3711
4451
|
const fn = candidate;
|
|
3712
|
-
const rawArgs =
|
|
4452
|
+
const rawArgs = def.arguments ?? {};
|
|
3713
4453
|
const hasReactiveArg = Object.values(rawArgs).some((v) => isRefObj(v));
|
|
3714
4454
|
const resolveArgs = () => {
|
|
3715
4455
|
const args = {};
|
|
@@ -3732,8 +4472,8 @@ async function resolveServerFunction(def2, state, key, base) {
|
|
|
3732
4472
|
}
|
|
3733
4473
|
return s;
|
|
3734
4474
|
}
|
|
3735
|
-
async function resolveServerFunctionViaProxy(
|
|
3736
|
-
const rawArgs =
|
|
4475
|
+
async function resolveServerFunctionViaProxy(def, state, key, base) {
|
|
4476
|
+
const rawArgs = def.arguments ?? {};
|
|
3737
4477
|
const hasReactiveArg = Object.values(rawArgs).some((v) => isRefObj(v));
|
|
3738
4478
|
const resolveArgs = () => {
|
|
3739
4479
|
const args = {};
|
|
@@ -3745,8 +4485,8 @@ async function resolveServerFunctionViaProxy(def2, state, key, base) {
|
|
|
3745
4485
|
const doResolve = (args) => fetch(resolveProxyPath("/__jx_server__"), {
|
|
3746
4486
|
body: JSON.stringify({
|
|
3747
4487
|
$base: base,
|
|
3748
|
-
$export:
|
|
3749
|
-
$src:
|
|
4488
|
+
$export: def.$export,
|
|
4489
|
+
$src: def.$src,
|
|
3750
4490
|
arguments: args
|
|
3751
4491
|
}),
|
|
3752
4492
|
headers: { "Content-Type": "application/json" },
|
|
@@ -3777,8 +4517,8 @@ function resolveRef(refPath, state) {
|
|
|
3777
4517
|
if (typeof refPath !== "string") {
|
|
3778
4518
|
return refPath;
|
|
3779
4519
|
}
|
|
3780
|
-
if (refPath.startsWith("$map/")) {
|
|
3781
|
-
const parts = refPath.split("/");
|
|
4520
|
+
if (refPath.startsWith("$map/") || refPath.startsWith("#/$map/")) {
|
|
4521
|
+
const parts = (refPath.startsWith("#/") ? refPath.slice(2) : refPath).split("/");
|
|
3782
4522
|
const [, key] = parts;
|
|
3783
4523
|
const map = state.$map;
|
|
3784
4524
|
const base = map?.[key] ?? state[`$map/${key}`];
|
|
@@ -3801,12 +4541,41 @@ function resolveRef(refPath, state) {
|
|
|
3801
4541
|
function isRefObj(v) {
|
|
3802
4542
|
return isRef(v);
|
|
3803
4543
|
}
|
|
3804
|
-
function isNestedSelector(k) {
|
|
3805
|
-
return k.startsWith(":") || k.startsWith(".") || k.startsWith("&") || k.startsWith("[");
|
|
3806
|
-
}
|
|
3807
4544
|
function getPath2(obj, path) {
|
|
3808
4545
|
return readPath(obj, path);
|
|
3809
4546
|
}
|
|
4547
|
+
function absorbAttribute(state, name, value, defaults) {
|
|
4548
|
+
const camelKey = name.replaceAll(/-([a-z])/g, (_, c) => c.toUpperCase());
|
|
4549
|
+
const current = state[camelKey];
|
|
4550
|
+
if (typeof current === "boolean") {
|
|
4551
|
+
state[camelKey] = value !== null && value !== "false";
|
|
4552
|
+
return;
|
|
4553
|
+
}
|
|
4554
|
+
if (value === null) {
|
|
4555
|
+
const declared = defaults?.get(camelKey);
|
|
4556
|
+
state[camelKey] = declared === undefined ? typeof current === "number" ? 0 : "" : declared;
|
|
4557
|
+
return;
|
|
4558
|
+
}
|
|
4559
|
+
state[camelKey] = typeof current === "number" ? Number(value) : value;
|
|
4560
|
+
}
|
|
4561
|
+
function declaredDefaults(def) {
|
|
4562
|
+
const out = new Map;
|
|
4563
|
+
for (const [key, entry] of Object.entries(def.state ?? {})) {
|
|
4564
|
+
if (entry !== null && typeof entry === "object") {
|
|
4565
|
+
const obj = entry;
|
|
4566
|
+
if ("default" in obj) {
|
|
4567
|
+
out.set(key, obj["default"]);
|
|
4568
|
+
continue;
|
|
4569
|
+
}
|
|
4570
|
+
if (COMPUTED_STATE_KEYS.some((marker) => (marker in obj))) {
|
|
4571
|
+
continue;
|
|
4572
|
+
}
|
|
4573
|
+
}
|
|
4574
|
+
out.set(key, entry);
|
|
4575
|
+
}
|
|
4576
|
+
return out;
|
|
4577
|
+
}
|
|
4578
|
+
var COMPUTED_STATE_KEYS = ["$expression", "$prototype", "$ref", "$src"];
|
|
3810
4579
|
var _privatePropWarned = new Set;
|
|
3811
4580
|
function instanceSupplies(el, key) {
|
|
3812
4581
|
if (Object.hasOwn(el, key)) {
|
|
@@ -3829,9 +4598,9 @@ function refusePrivateProp(key, where) {
|
|
|
3829
4598
|
}
|
|
3830
4599
|
return true;
|
|
3831
4600
|
}
|
|
3832
|
-
function mergeProps(
|
|
4601
|
+
function mergeProps(def, parentState) {
|
|
3833
4602
|
const child = Object.create(parentState);
|
|
3834
|
-
for (const [k, v] of Object.entries(
|
|
4603
|
+
for (const [k, v] of Object.entries(def.$props ?? {})) {
|
|
3835
4604
|
if (refusePrivateProp(k, "$props")) {
|
|
3836
4605
|
continue;
|
|
3837
4606
|
}
|
|
@@ -3839,15 +4608,32 @@ function mergeProps(def2, parentState) {
|
|
|
3839
4608
|
}
|
|
3840
4609
|
return child;
|
|
3841
4610
|
}
|
|
3842
|
-
function toCSSText(rules) {
|
|
3843
|
-
return Object.entries(rules).filter(([k, v]) => !isNestedSelector(k) && (v === null || typeof v !== "object")).map(([p, v]) => `${camelToKebab(p)}: ${canvasStyleValue(String(v))}`).join("; ");
|
|
3844
|
-
}
|
|
3845
4611
|
var _rootMedia = {};
|
|
3846
4612
|
var _elementDefs = new Map;
|
|
4613
|
+
async function redefineElement(doc, baseUrl) {
|
|
4614
|
+
const base = baseUrl ?? location.href;
|
|
4615
|
+
const { tagName } = doc;
|
|
4616
|
+
if (!tagName || !tagName.includes("-")) {
|
|
4617
|
+
throw new Error(`Jx redefineElement: tagName "${tagName}" must contain a hyphen`);
|
|
4618
|
+
}
|
|
4619
|
+
if (!customElements.get(tagName)) {
|
|
4620
|
+
await defineElement(doc, base);
|
|
4621
|
+
return;
|
|
4622
|
+
}
|
|
4623
|
+
if (doc.$elements) {
|
|
4624
|
+
await registerElements(doc.$elements, base);
|
|
4625
|
+
}
|
|
4626
|
+
const before = _elementDefs.get(tagName)?.doc.observedAttributes ?? [];
|
|
4627
|
+
const after = doc.observedAttributes ?? [];
|
|
4628
|
+
if (JSON.stringify(before) !== JSON.stringify(after)) {
|
|
4629
|
+
console.warn(`Jx redefineElement: <${tagName}> keeps observedAttributes [${before.join(", ")}] as first defined; [${after.join(", ")}] takes effect only in a fresh realm`);
|
|
4630
|
+
}
|
|
4631
|
+
_elementDefs.set(tagName, { base, doc });
|
|
4632
|
+
}
|
|
3847
4633
|
function setRootMedia(map) {
|
|
3848
4634
|
_rootMedia = map ?? {};
|
|
3849
4635
|
}
|
|
3850
|
-
async function registerElements(elements, base) {
|
|
4636
|
+
async function registerElements(elements, base, ctx) {
|
|
3851
4637
|
for (const entry of elements) {
|
|
3852
4638
|
if (typeof entry === "string") {
|
|
3853
4639
|
try {
|
|
@@ -3862,7 +4648,7 @@ async function registerElements(elements, base) {
|
|
|
3862
4648
|
continue;
|
|
3863
4649
|
}
|
|
3864
4650
|
const { href } = new URL(entry.$ref, base);
|
|
3865
|
-
const doc = await resolve(href);
|
|
4651
|
+
const doc = await resolve(href, ctx);
|
|
3866
4652
|
if (!doc.tagName || !doc.tagName.includes("-")) {
|
|
3867
4653
|
continue;
|
|
3868
4654
|
}
|
|
@@ -3870,11 +4656,70 @@ async function registerElements(elements, base) {
|
|
|
3870
4656
|
continue;
|
|
3871
4657
|
}
|
|
3872
4658
|
if (doc.$elements) {
|
|
3873
|
-
await registerElements(doc.$elements, href);
|
|
4659
|
+
await registerElements(doc.$elements, href, ctx);
|
|
3874
4660
|
}
|
|
3875
4661
|
await defineElement(doc, href);
|
|
3876
4662
|
}
|
|
3877
4663
|
}
|
|
4664
|
+
var MAX_COMPONENT_NESTING = 32;
|
|
4665
|
+
var ROOT_INSTANCE_PATH = { expansion: 0, frames: [] };
|
|
4666
|
+
var _instancePath = ROOT_INSTANCE_PATH;
|
|
4667
|
+
function underInstancePath(path, fn) {
|
|
4668
|
+
const was = _instancePath;
|
|
4669
|
+
_instancePath = path;
|
|
4670
|
+
try {
|
|
4671
|
+
return fn();
|
|
4672
|
+
} finally {
|
|
4673
|
+
_instancePath = was;
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
function reexpand(path) {
|
|
4677
|
+
return { expansion: path.frames.length, frames: path.frames };
|
|
4678
|
+
}
|
|
4679
|
+
function samePropValue(a, b) {
|
|
4680
|
+
if (Object.is(a, b)) {
|
|
4681
|
+
return true;
|
|
4682
|
+
}
|
|
4683
|
+
if (!isPlainData(a) || !isPlainData(b)) {
|
|
4684
|
+
return false;
|
|
4685
|
+
}
|
|
4686
|
+
try {
|
|
4687
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
4688
|
+
} catch {
|
|
4689
|
+
return false;
|
|
4690
|
+
}
|
|
4691
|
+
}
|
|
4692
|
+
function isPlainData(value) {
|
|
4693
|
+
if (typeof value !== "object" || value === null) {
|
|
4694
|
+
return false;
|
|
4695
|
+
}
|
|
4696
|
+
const raw = toRaw(value);
|
|
4697
|
+
if (Array.isArray(raw)) {
|
|
4698
|
+
return true;
|
|
4699
|
+
}
|
|
4700
|
+
const proto = Object.getPrototypeOf(raw);
|
|
4701
|
+
return proto === Object.prototype || proto === null;
|
|
4702
|
+
}
|
|
4703
|
+
function sameFrame(a, b) {
|
|
4704
|
+
if (a.tag !== b.tag) {
|
|
4705
|
+
return false;
|
|
4706
|
+
}
|
|
4707
|
+
const keys = Object.keys(a.props);
|
|
4708
|
+
if (keys.length !== Object.keys(b.props).length) {
|
|
4709
|
+
return false;
|
|
4710
|
+
}
|
|
4711
|
+
return keys.every((key) => Object.hasOwn(b.props, key) && samePropValue(a.props[key], b.props[key]));
|
|
4712
|
+
}
|
|
4713
|
+
function extendInstancePath(path, frame) {
|
|
4714
|
+
const chain = [...path.frames.map((f) => f.tag), frame.tag].join(" → ");
|
|
4715
|
+
if (path.frames.slice(path.expansion).some((f) => sameFrame(f, frame))) {
|
|
4716
|
+
throw new Error(`Component <${frame.tag}> renders itself: ${chain}. A component cannot appear inside its own ` + `definition with the same props — the expansion would never end.`);
|
|
4717
|
+
}
|
|
4718
|
+
if (path.frames.length >= MAX_COMPONENT_NESTING) {
|
|
4719
|
+
throw new Error(`Component nesting exceeds ${MAX_COMPONENT_NESTING} levels: ${chain}. A component that renders itself with changing props needs a case that stops.`);
|
|
4720
|
+
}
|
|
4721
|
+
return { expansion: path.expansion, frames: [...path.frames, frame] };
|
|
4722
|
+
}
|
|
3878
4723
|
var _definedSources = new Set;
|
|
3879
4724
|
async function defineElement(source, baseUrl) {
|
|
3880
4725
|
let base = baseUrl;
|
|
@@ -3900,8 +4745,9 @@ async function defineElement(source, baseUrl) {
|
|
|
3900
4745
|
await registerElements(source_.$elements, base);
|
|
3901
4746
|
}
|
|
3902
4747
|
_elementDefs.set(tagName, { base, doc: source_ });
|
|
3903
|
-
const
|
|
3904
|
-
const
|
|
4748
|
+
const initialDef = source_;
|
|
4749
|
+
const initialBase = base;
|
|
4750
|
+
const observedAttrs = initialDef.observedAttributes ?? [];
|
|
3905
4751
|
const ElementClass = class extends HTMLElement {
|
|
3906
4752
|
_jxInitialized = false;
|
|
3907
4753
|
_state = null;
|
|
@@ -3916,7 +4762,18 @@ async function defineElement(source, baseUrl) {
|
|
|
3916
4762
|
return;
|
|
3917
4763
|
}
|
|
3918
4764
|
this._jxInitialized = true;
|
|
3919
|
-
const
|
|
4765
|
+
const enclosingPath = _instancePath;
|
|
4766
|
+
const supplied = {};
|
|
4767
|
+
const live = _elementDefs.get(tagName) ?? { base: initialBase, doc: initialDef };
|
|
4768
|
+
const def = live.doc;
|
|
4769
|
+
const defBase = live.base;
|
|
4770
|
+
const state = await buildScope(def, {}, defBase, { base: defBase, media: null, root: this });
|
|
4771
|
+
for (const attr of observedAttrs) {
|
|
4772
|
+
if (this.hasAttribute(attr)) {
|
|
4773
|
+
absorbAttribute(state, attr, this.getAttribute(attr));
|
|
4774
|
+
supplied[attr] = this.getAttribute(attr);
|
|
4775
|
+
}
|
|
4776
|
+
}
|
|
3920
4777
|
const propsAttr = this.dataset.jxProps;
|
|
3921
4778
|
if (propsAttr) {
|
|
3922
4779
|
try {
|
|
@@ -3925,8 +4782,9 @@ async function defineElement(source, baseUrl) {
|
|
|
3925
4782
|
if (refusePrivateProp(key, "data-jx-props")) {
|
|
3926
4783
|
continue;
|
|
3927
4784
|
}
|
|
3928
|
-
if (key in (
|
|
4785
|
+
if (key in (def.state ?? {})) {
|
|
3929
4786
|
state[key] = val;
|
|
4787
|
+
supplied[key] = val;
|
|
3930
4788
|
}
|
|
3931
4789
|
}
|
|
3932
4790
|
} catch {}
|
|
@@ -3939,20 +4797,39 @@ async function defineElement(source, baseUrl) {
|
|
|
3939
4797
|
this.removeAttribute(name);
|
|
3940
4798
|
continue;
|
|
3941
4799
|
}
|
|
3942
|
-
if (key in (
|
|
4800
|
+
if (key in (def.state ?? {})) {
|
|
3943
4801
|
state[key] = this.getAttribute(name);
|
|
4802
|
+
supplied[key] = this.getAttribute(name);
|
|
3944
4803
|
this.removeAttribute(name);
|
|
3945
4804
|
}
|
|
3946
4805
|
}
|
|
3947
|
-
for (const key of Object.keys(
|
|
4806
|
+
for (const key of Object.keys(def.state ?? {})) {
|
|
3948
4807
|
if (isPrivateStateKey(key)) {
|
|
3949
4808
|
continue;
|
|
3950
4809
|
}
|
|
3951
4810
|
if (key in this && this[key] !== undefined && instanceSupplies(this, key)) {
|
|
3952
4811
|
state[key] = this[key];
|
|
4812
|
+
supplied[key] = this[key];
|
|
3953
4813
|
}
|
|
3954
4814
|
}
|
|
3955
|
-
|
|
4815
|
+
let ownPath;
|
|
4816
|
+
try {
|
|
4817
|
+
ownPath = extendInstancePath(enclosingPath, { props: supplied, tag: tagName });
|
|
4818
|
+
} catch (error) {
|
|
4819
|
+
this.replaceChildren();
|
|
4820
|
+
if (!this.isConnected) {
|
|
4821
|
+
return;
|
|
4822
|
+
}
|
|
4823
|
+
console.error(`Jx: <${tagName}> was not rendered:`, error);
|
|
4824
|
+
this.dispatchEvent(new ErrorEvent("jx-error", {
|
|
4825
|
+
bubbles: true,
|
|
4826
|
+
composed: true,
|
|
4827
|
+
error,
|
|
4828
|
+
message: error instanceof Error ? error.message : String(error)
|
|
4829
|
+
}));
|
|
4830
|
+
return;
|
|
4831
|
+
}
|
|
4832
|
+
for (const key of Object.keys(def.state ?? {})) {
|
|
3956
4833
|
if (isPrivateStateKey(key)) {
|
|
3957
4834
|
continue;
|
|
3958
4835
|
}
|
|
@@ -3969,22 +4846,30 @@ async function defineElement(source, baseUrl) {
|
|
|
3969
4846
|
this._state = state;
|
|
3970
4847
|
const slottedChildren = [...this.childNodes];
|
|
3971
4848
|
this.replaceChildren();
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
}
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
if (!Array.isArray(
|
|
3978
|
-
bindProperty(this, "textContent",
|
|
3979
|
-
}
|
|
3980
|
-
const children = Array.isArray(
|
|
3981
|
-
|
|
3982
|
-
|
|
4849
|
+
const defStyle = declaresDisplay(def.style) ? def.style : { display: "block", ...def.style };
|
|
4850
|
+
const hostStyle = mergeStyle(defStyle, callSiteStyles.get(this));
|
|
4851
|
+
applyStyle(this, hostStyle, state["$media"] ?? {}, state);
|
|
4852
|
+
applyAttributes(this, def.attributes ?? {}, state);
|
|
4853
|
+
bindDefinitionHandlers(this, def, state);
|
|
4854
|
+
if (!Array.isArray(def.children) && def.textContent !== undefined) {
|
|
4855
|
+
bindProperty(this, "textContent", def.textContent, state);
|
|
4856
|
+
}
|
|
4857
|
+
const children = Array.isArray(def.children) ? def.children : [];
|
|
4858
|
+
const wasInside = _canvasInsideStampedHost;
|
|
4859
|
+
_canvasInsideStampedHost ||= this.dataset.jxPath !== undefined;
|
|
4860
|
+
try {
|
|
4861
|
+
underInstancePath(ownPath, () => {
|
|
4862
|
+
for (const childDef of children) {
|
|
4863
|
+
this.append(renderNode(childDef, state));
|
|
4864
|
+
}
|
|
4865
|
+
});
|
|
4866
|
+
} finally {
|
|
4867
|
+
_canvasInsideStampedHost = wasInside;
|
|
3983
4868
|
}
|
|
3984
4869
|
distributeSlots(this, slottedChildren);
|
|
3985
4870
|
const { onMount } = state;
|
|
3986
4871
|
if (typeof onMount === "function") {
|
|
3987
|
-
queueMicrotask(() => onMount(state));
|
|
4872
|
+
queueMicrotask(() => onMount(state, this));
|
|
3988
4873
|
}
|
|
3989
4874
|
}
|
|
3990
4875
|
disconnectedCallback() {
|
|
@@ -4001,25 +4886,17 @@ async function defineElement(source, baseUrl) {
|
|
|
4001
4886
|
if (!this._state || oldVal === newVal) {
|
|
4002
4887
|
return;
|
|
4003
4888
|
}
|
|
4004
|
-
|
|
4005
|
-
const current = this._state[camelKey];
|
|
4006
|
-
if (typeof current === "number") {
|
|
4007
|
-
this._state[camelKey] = Number(newVal);
|
|
4008
|
-
} else if (typeof current === "boolean") {
|
|
4009
|
-
this._state[camelKey] = newVal !== null && newVal !== "false";
|
|
4010
|
-
} else {
|
|
4011
|
-
this._state[camelKey] = newVal;
|
|
4012
|
-
}
|
|
4889
|
+
absorbAttribute(this._state, name, newVal, declaredDefaults(_elementDefs.get(tagName)?.doc ?? initialDef));
|
|
4013
4890
|
}
|
|
4014
4891
|
};
|
|
4015
4892
|
customElements.define(tagName, ElementClass);
|
|
4016
4893
|
}
|
|
4017
|
-
function renderCustomElementWithProps(
|
|
4018
|
-
const el = document.createElement(resolveTagName(
|
|
4894
|
+
function renderCustomElementWithProps(def, state, options, path) {
|
|
4895
|
+
const el = document.createElement(resolveTagName(def.tagName, state));
|
|
4019
4896
|
if (options?.onNodeCreated) {
|
|
4020
|
-
options.onNodeCreated(el, path ?? [],
|
|
4897
|
+
options.onNodeCreated(el, path ?? [], def, state);
|
|
4021
4898
|
}
|
|
4022
|
-
for (const [key, val] of Object.entries(
|
|
4899
|
+
for (const [key, val] of Object.entries(def.$props ?? {})) {
|
|
4023
4900
|
if (refusePrivateProp(key, "$props")) {
|
|
4024
4901
|
continue;
|
|
4025
4902
|
}
|
|
@@ -4040,19 +4917,25 @@ function renderCustomElementWithProps(def2, state, options, path) {
|
|
|
4040
4917
|
write(val);
|
|
4041
4918
|
}
|
|
4042
4919
|
}
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4920
|
+
if (def.style) {
|
|
4921
|
+
callSiteStyles.set(el, def.style);
|
|
4922
|
+
}
|
|
4923
|
+
applyStyle(el, def.style ?? {}, state["$media"] ?? {}, state);
|
|
4924
|
+
applyAttributes(el, def.attributes ?? {}, state);
|
|
4925
|
+
applyProperties(el, def, state);
|
|
4926
|
+
const children = Array.isArray(def.children) ? def.children : [];
|
|
4046
4927
|
for (let i = 0;i < children.length; i++) {
|
|
4928
|
+
const child = children[i];
|
|
4047
4929
|
const childOpts = options && path ? { ...options, _path: [...path, "children", i] } : undefined;
|
|
4048
|
-
|
|
4930
|
+
if (isMappedArray(child)) {
|
|
4931
|
+
renderMappedArrayInto(el, child, state, childOpts);
|
|
4932
|
+
} else {
|
|
4933
|
+
el.append(renderNode(child, state, childOpts));
|
|
4934
|
+
}
|
|
4049
4935
|
}
|
|
4050
4936
|
return el;
|
|
4051
4937
|
}
|
|
4052
4938
|
function distributeSlots(host, slottedChildren) {
|
|
4053
|
-
if (slottedChildren.length === 0) {
|
|
4054
|
-
return;
|
|
4055
|
-
}
|
|
4056
4939
|
const slots = host.querySelectorAll("slot");
|
|
4057
4940
|
if (slots.length === 0) {
|
|
4058
4941
|
return;
|
|
@@ -4073,12 +4956,7 @@ function distributeSlots(host, slottedChildren) {
|
|
|
4073
4956
|
for (const slot of slots) {
|
|
4074
4957
|
const name = slot.getAttribute("name");
|
|
4075
4958
|
const matches = name ? named.get(name) ?? [] : unnamed;
|
|
4076
|
-
|
|
4077
|
-
slot.replaceChildren();
|
|
4078
|
-
for (const child of matches) {
|
|
4079
|
-
slot.append(child);
|
|
4080
|
-
}
|
|
4081
|
-
}
|
|
4959
|
+
slot.replaceWith(...matches.length > 0 ? matches : [...slot.childNodes]);
|
|
4082
4960
|
}
|
|
4083
4961
|
}
|
|
4084
4962
|
|
|
@@ -4124,14 +5002,18 @@ function mountedRefFor(value, entryDir, mount) {
|
|
|
4124
5002
|
}
|
|
4125
5003
|
|
|
4126
5004
|
// src/canvas/path-mapping.ts
|
|
5005
|
+
function jxPathSelector(serialized) {
|
|
5006
|
+
const escaped = serialized.replaceAll("\\", String.raw`\\`).replaceAll("'", String.raw`\'`);
|
|
5007
|
+
return `[data-jx-path='${escaped}']`;
|
|
5008
|
+
}
|
|
4127
5009
|
function wrapsPageContent(path, prefix) {
|
|
4128
5010
|
if (!prefix) {
|
|
4129
5011
|
return false;
|
|
4130
5012
|
}
|
|
4131
5013
|
return path.length <= prefix.length && path.every((seg, i) => prefix[i] === seg);
|
|
4132
5014
|
}
|
|
4133
|
-
function classifyRenderNode(path,
|
|
4134
|
-
const marker = ctx.layoutWrapped && typeof
|
|
5015
|
+
function classifyRenderNode(path, def, ctx) {
|
|
5016
|
+
const marker = ctx.layoutWrapped && typeof def === "object" ? def?.$__layout : undefined;
|
|
4135
5017
|
if (marker) {
|
|
4136
5018
|
const origin = typeof marker === "object" ? marker : {};
|
|
4137
5019
|
return {
|
|
@@ -4150,7 +5032,7 @@ function classifyRenderNode(path, def2, ctx) {
|
|
|
4150
5032
|
mappedPath = typeof containerIdx === "number" ? ["children", containerIdx - (ctx.pageContentOffset ?? 0), ...rest.slice(1)] : ["children", ...rest];
|
|
4151
5033
|
}
|
|
4152
5034
|
}
|
|
4153
|
-
if (
|
|
5035
|
+
if (ctx.arrayPaths.size > 0) {
|
|
4154
5036
|
let changed = true;
|
|
4155
5037
|
while (changed) {
|
|
4156
5038
|
changed = false;
|
|
@@ -4172,57 +5054,160 @@ function parseJxPath(serialized) {
|
|
|
4172
5054
|
return JSON.parse(serialized);
|
|
4173
5055
|
}
|
|
4174
5056
|
|
|
5057
|
+
// src/canvas/iframe-position.ts
|
|
5058
|
+
function isIslandBoundary(el) {
|
|
5059
|
+
if (el.dataset.jxDefinitionRoot !== undefined) {
|
|
5060
|
+
return false;
|
|
5061
|
+
}
|
|
5062
|
+
return el.getAttribute("contenteditable") === "false" || el.tagName.includes("-");
|
|
5063
|
+
}
|
|
5064
|
+
function activeBlockAt(node, isEditable) {
|
|
5065
|
+
let el = node instanceof Element ? node : node?.parentElement ?? null;
|
|
5066
|
+
while (el) {
|
|
5067
|
+
if (el instanceof HTMLElement) {
|
|
5068
|
+
if (el.dataset.jxPath && isEditable(el)) {
|
|
5069
|
+
return { el, path: parseJxPath(el.dataset.jxPath) };
|
|
5070
|
+
}
|
|
5071
|
+
if (isIslandBoundary(el)) {
|
|
5072
|
+
return null;
|
|
5073
|
+
}
|
|
5074
|
+
}
|
|
5075
|
+
el = el.parentElement;
|
|
5076
|
+
}
|
|
5077
|
+
return null;
|
|
5078
|
+
}
|
|
5079
|
+
function elementForPath(container, path) {
|
|
5080
|
+
const el = container.querySelector(jxPathSelector(serializeJxPath(path)));
|
|
5081
|
+
return el instanceof HTMLElement ? el : null;
|
|
5082
|
+
}
|
|
5083
|
+
function blockTextLength(block) {
|
|
5084
|
+
return block.textContent?.length ?? 0;
|
|
5085
|
+
}
|
|
5086
|
+
function offsetOf(block, node, offset) {
|
|
5087
|
+
if (!block.contains(node)) {
|
|
5088
|
+
return null;
|
|
5089
|
+
}
|
|
5090
|
+
const range = block.ownerDocument.createRange();
|
|
5091
|
+
range.setStart(block, 0);
|
|
5092
|
+
try {
|
|
5093
|
+
range.setEnd(node, offset);
|
|
5094
|
+
} catch {
|
|
5095
|
+
return null;
|
|
5096
|
+
}
|
|
5097
|
+
return range.toString().length;
|
|
5098
|
+
}
|
|
5099
|
+
function domPositionAt(block, offset) {
|
|
5100
|
+
const target = Math.max(0, Math.min(offset, blockTextLength(block)));
|
|
5101
|
+
const walker = block.ownerDocument.createTreeWalker(block, NodeFilter.SHOW_TEXT);
|
|
5102
|
+
let seen = 0;
|
|
5103
|
+
let last = null;
|
|
5104
|
+
let current = walker.nextNode();
|
|
5105
|
+
while (current) {
|
|
5106
|
+
const len = current.length;
|
|
5107
|
+
if (seen + len >= target) {
|
|
5108
|
+
return { node: current, offset: target - seen };
|
|
5109
|
+
}
|
|
5110
|
+
seen += len;
|
|
5111
|
+
last = current;
|
|
5112
|
+
current = walker.nextNode();
|
|
5113
|
+
}
|
|
5114
|
+
return last ? { node: last, offset: last.length } : { node: block, offset: 0 };
|
|
5115
|
+
}
|
|
5116
|
+
function toDocPos(node, offset, isEditable) {
|
|
5117
|
+
const block = activeBlockAt(node, isEditable);
|
|
5118
|
+
if (!block || !node) {
|
|
5119
|
+
return null;
|
|
5120
|
+
}
|
|
5121
|
+
const charOffset = offsetOf(block.el, node, offset);
|
|
5122
|
+
return charOffset === null ? null : { offset: charOffset, path: block.path };
|
|
5123
|
+
}
|
|
5124
|
+
function toDomPosition(container, pos) {
|
|
5125
|
+
const el = elementForPath(container, pos.path);
|
|
5126
|
+
return el ? domPositionAt(el, pos.offset) : null;
|
|
5127
|
+
}
|
|
5128
|
+
function isAtBlockStart(pos) {
|
|
5129
|
+
return pos.offset <= 0;
|
|
5130
|
+
}
|
|
5131
|
+
function samePath(a, b) {
|
|
5132
|
+
return serializeJxPath(a.path) === serializeJxPath(b.path);
|
|
5133
|
+
}
|
|
5134
|
+
function blocksInOrder(container, isEditable) {
|
|
5135
|
+
const out = [];
|
|
5136
|
+
for (const el of container.querySelectorAll("[data-jx-path]")) {
|
|
5137
|
+
if (isEditable(el) && !sealedInIsland(el, container)) {
|
|
5138
|
+
out.push(el);
|
|
5139
|
+
}
|
|
5140
|
+
}
|
|
5141
|
+
return out;
|
|
5142
|
+
}
|
|
5143
|
+
function sealedInIsland(el, container) {
|
|
5144
|
+
let cur = el.parentElement;
|
|
5145
|
+
while (cur && cur !== container) {
|
|
5146
|
+
if (isIslandBoundary(cur)) {
|
|
5147
|
+
return true;
|
|
5148
|
+
}
|
|
5149
|
+
cur = cur.parentElement;
|
|
5150
|
+
}
|
|
5151
|
+
return false;
|
|
5152
|
+
}
|
|
5153
|
+
function adjacentBlock(container, path, direction, isEditable) {
|
|
5154
|
+
const blocks = blocksInOrder(container, isEditable);
|
|
5155
|
+
const key = serializeJxPath(path);
|
|
5156
|
+
const index = blocks.findIndex((el) => el.dataset.jxPath === key);
|
|
5157
|
+
const neighbour = index === -1 ? undefined : blocks[index + direction];
|
|
5158
|
+
return neighbour ? { el: neighbour, path: parseJxPath(neighbour.dataset.jxPath) } : null;
|
|
5159
|
+
}
|
|
5160
|
+
|
|
4175
5161
|
// ../site/src/site-style.ts
|
|
4176
5162
|
var SITE_STYLE_ID = "jx-site-style";
|
|
4177
|
-
function
|
|
4178
|
-
return Object.entries(props).map(([key, value]) => `${camelToKebab(key)}: ${transpose(String(value))}`).join("; ");
|
|
4179
|
-
}
|
|
4180
|
-
function buildSiteStyleCSS(siteStyle, mediaQueries, transpose) {
|
|
5163
|
+
function buildSiteStyleCSS(siteStyle, mediaQueries, transpose, resolveValue) {
|
|
4181
5164
|
const rules = [];
|
|
5165
|
+
const push = (style, selector) => {
|
|
5166
|
+
for (const rule of buildStyleRules(style, {
|
|
5167
|
+
mediaQueries,
|
|
5168
|
+
scope: selector,
|
|
5169
|
+
transposeValue: transpose,
|
|
5170
|
+
...resolveValue ? { resolveValue: (property, value) => resolveValue(property, value, selector) } : {}
|
|
5171
|
+
})) {
|
|
5172
|
+
rules.push(rule.text);
|
|
5173
|
+
}
|
|
5174
|
+
};
|
|
4182
5175
|
const rootProps = {};
|
|
4183
5176
|
const bodyProps = {};
|
|
4184
5177
|
const condBlocks = [];
|
|
5178
|
+
const selectorBlocks = [];
|
|
4185
5179
|
for (const [key, value] of Object.entries(siteStyle)) {
|
|
4186
5180
|
if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
4187
5181
|
if (key.startsWith("@")) {
|
|
4188
5182
|
condBlocks.push([key, value]);
|
|
5183
|
+
} else if (!key.startsWith("--")) {
|
|
5184
|
+
selectorBlocks.push([key, value]);
|
|
4189
5185
|
}
|
|
4190
5186
|
continue;
|
|
4191
5187
|
}
|
|
4192
|
-
if (
|
|
5188
|
+
if (isNestedSelectorKey(key) || key.startsWith("@")) {
|
|
4193
5189
|
continue;
|
|
4194
5190
|
}
|
|
4195
|
-
if (key.startsWith("--")) {
|
|
5191
|
+
if (key.startsWith("--") || key === "colorScheme" || key === "color-scheme") {
|
|
4196
5192
|
rootProps[key] = value;
|
|
4197
5193
|
} else {
|
|
4198
5194
|
bodyProps[key] = value;
|
|
4199
5195
|
}
|
|
4200
5196
|
}
|
|
4201
|
-
|
|
4202
|
-
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
if (
|
|
4212
|
-
|
|
5197
|
+
push(rootProps, ":root");
|
|
5198
|
+
push(bodyProps, "body");
|
|
5199
|
+
for (const [key, block] of selectorBlocks) {
|
|
5200
|
+
if (key.startsWith("&")) {
|
|
5201
|
+
push({ [key]: block }, ":root");
|
|
5202
|
+
} else {
|
|
5203
|
+
push(block, key);
|
|
5204
|
+
}
|
|
5205
|
+
}
|
|
5206
|
+
for (const [atKey, block] of condBlocks) {
|
|
5207
|
+
if (isDeclarationAtRule(atKey) || isKeyframesAtRule(atKey)) {
|
|
5208
|
+
push({ [atKey]: block }, null);
|
|
5209
|
+
continue;
|
|
4213
5210
|
}
|
|
4214
|
-
const scheme = pureSchemeOf(query);
|
|
4215
|
-
const emit = (selector, props) => {
|
|
4216
|
-
if (!props) {
|
|
4217
|
-
return;
|
|
4218
|
-
}
|
|
4219
|
-
if (scheme) {
|
|
4220
|
-
const { auto, forced } = schemeSelectors(selector, scheme);
|
|
4221
|
-
rules.push(`@media ${query} { ${auto} { ${props} } }`, `${forced} { ${props} }`);
|
|
4222
|
-
} else {
|
|
4223
|
-
rules.push(`@media ${query} { ${selector} { ${props} } }`);
|
|
4224
|
-
}
|
|
4225
|
-
};
|
|
4226
5211
|
const condRoot = {};
|
|
4227
5212
|
const condBody = {};
|
|
4228
5213
|
const condSubs = [];
|
|
@@ -4239,14 +5224,14 @@ function buildSiteStyleCSS(siteStyle, mediaQueries, transpose) {
|
|
|
4239
5224
|
condBody[k] = v;
|
|
4240
5225
|
}
|
|
4241
5226
|
}
|
|
4242
|
-
|
|
4243
|
-
|
|
5227
|
+
push({ [atKey]: condRoot }, ":root");
|
|
5228
|
+
push({ [atKey]: condBody }, "body");
|
|
4244
5229
|
for (const [sel, sub] of condSubs) {
|
|
4245
|
-
|
|
5230
|
+
push({ [atKey]: sub }, sel);
|
|
4246
5231
|
}
|
|
4247
5232
|
}
|
|
4248
|
-
if (Object.values(mediaQueries).some((q) => pureSchemeOf(q) !== null)) {
|
|
4249
|
-
rules.push(":root { color-scheme: light dark }");
|
|
5233
|
+
if (Object.values(mediaQueries).some((q) => pureSchemeOf(q) !== null) && !("colorScheme" in siteStyle)) {
|
|
5234
|
+
rules.push(":root { color-scheme: light dark }", `:root:where([${COLOR_SCHEME_ATTR}="light"]) { color-scheme: light }`, `:root:where([${COLOR_SCHEME_ATTR}="dark"]) { color-scheme: dark }`);
|
|
4250
5235
|
}
|
|
4251
5236
|
return rules.join(`
|
|
4252
5237
|
`);
|
|
@@ -4386,6 +5371,196 @@ function syncEditModeCss(doc, mode) {
|
|
|
4386
5371
|
style.textContent = EDIT_PLACEHOLDER_CSS;
|
|
4387
5372
|
doc.head.append(style);
|
|
4388
5373
|
}
|
|
5374
|
+
var CANVAS_OVERLAY_STYLE_ID = "jx-canvas-overlay-css";
|
|
5375
|
+
var CANVAS_OVERLAY_CSS = `
|
|
5376
|
+
/* The UA rule a de-popovered element lost, re-supplied at UA-EQUIVALENT PRECEDENCE.
|
|
5377
|
+
|
|
5378
|
+
The cascade layer is the mechanism and it is the whole point. An unlayered author declaration
|
|
5379
|
+
beats a layered one whatever its specificity, and every declaration applyStyle emits is an
|
|
5380
|
+
unlayered rule in an adopted sheet. That is exactly how author origin beats UA origin on the
|
|
5381
|
+
shipped page, so the canvas reproduces the real cascade rather than an approximation of it.
|
|
5382
|
+
|
|
5383
|
+
This used to read "a base declaration is written as an INLINE style", which was true and is the
|
|
5384
|
+
reason the guarantee survived the move: inline beat layered harder still, and unlayered beats it
|
|
5385
|
+
by the same rule one step down. Jx emits no layer of its own, which is what keeps that true.
|
|
5386
|
+
|
|
5387
|
+
Deliberately NOT forced with a priority flag. A popover whose base rule sets display is laid out
|
|
5388
|
+
on every page whether open or not; that is a real defect, @jxsuite/schema/overlays reports it as
|
|
5389
|
+
base-display, and the canvas's job is to SHOW it, not to hide it behind a stronger rule. */
|
|
5390
|
+
@layer jx-canvas-ua {
|
|
5391
|
+
[data-jx-popover]:not([data-jx-popover-open]) {
|
|
5392
|
+
display: none;
|
|
5393
|
+
}
|
|
5394
|
+
dialog[data-jx-dialog-open] {
|
|
5395
|
+
display: block;
|
|
5396
|
+
}
|
|
5397
|
+
}
|
|
5398
|
+
/* SHOWN IN PLACE, and the position declaration is what makes that true.
|
|
5399
|
+
|
|
5400
|
+
Dropping the popover attribute drops the UA rule that made the panel fixed, so a panel that never
|
|
5401
|
+
set position itself — every one in the fleet — lands in normal flow at its document position,
|
|
5402
|
+
contributes to #jx-canvas-root's scrollHeight, and the host grows the artboard to fit it. That is
|
|
5403
|
+
the whole geometry fix, and it is why an open panel is reachable at all.
|
|
5404
|
+
|
|
5405
|
+
The two alignment declarations are the other half, and they were found by measuring rather than
|
|
5406
|
+
by reasoning. Every drawer in the fleet is declared inside its header's flex row, so in flow it
|
|
5407
|
+
becomes a FLEX ITEM: align-items:center on the row centres a 904px panel on a 64px header and
|
|
5408
|
+
half of it sits above the artboard at a negative offset, where it contributes nothing to the
|
|
5409
|
+
scrollable overflow the host measures. Pinned to the start and refused any flex sizing, the same
|
|
5410
|
+
panel hangs down from its own position and the artboard grows by its full height.
|
|
5411
|
+
|
|
5412
|
+
Forced, because a panel that DOES set position: fixed would otherwise keep it and be laid out
|
|
5413
|
+
against the frame's own viewport — which in a de-linked mode is the document's full height, so a
|
|
5414
|
+
drawer pinned with inset: 0 lands halfway down a long page and a short component frame clips it.
|
|
5415
|
+
This is a presentation override for a canvas affordance, the same kind as the layout-region
|
|
5416
|
+
dimming in EDIT_PLACEHOLDER_CSS, and it is NOT the same move as forcing display: that would hide
|
|
5417
|
+
a real defect in the document (base-display), while this hides nothing — Preview renders the
|
|
5418
|
+
panel natively, top layer and all. */
|
|
5419
|
+
[data-jx-popover][data-jx-popover-open] {
|
|
5420
|
+
position: relative !important;
|
|
5421
|
+
inset: auto !important;
|
|
5422
|
+
align-self: start !important;
|
|
5423
|
+
flex: none !important;
|
|
5424
|
+
outline: 1px dashed color-mix(in srgb, #808080 55%, transparent);
|
|
5425
|
+
outline-offset: 2px;
|
|
5426
|
+
}
|
|
5427
|
+
[data-jx-popover][data-jx-popover-open]::before {
|
|
5428
|
+
content: "POPOVER \\00B7 SHOWN IN PLACE";
|
|
5429
|
+
position: absolute;
|
|
5430
|
+
top: 0;
|
|
5431
|
+
left: 0;
|
|
5432
|
+
z-index: 2;
|
|
5433
|
+
padding: 1px 5px;
|
|
5434
|
+
border-radius: 0 0 3px 0;
|
|
5435
|
+
background: color-mix(in srgb, #808080 78%, transparent);
|
|
5436
|
+
color: #fff;
|
|
5437
|
+
font: 700 9px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
5438
|
+
letter-spacing: 0.08em;
|
|
5439
|
+
pointer-events: none;
|
|
5440
|
+
}
|
|
5441
|
+
dialog[data-jx-dialog-open] {
|
|
5442
|
+
position: relative !important;
|
|
5443
|
+
inset: auto !important;
|
|
5444
|
+
align-self: start !important;
|
|
5445
|
+
flex: none !important;
|
|
5446
|
+
outline: 1px dashed color-mix(in srgb, #808080 55%, transparent);
|
|
5447
|
+
outline-offset: 2px;
|
|
5448
|
+
}
|
|
5449
|
+
dialog[data-jx-dialog-open]::before {
|
|
5450
|
+
content: "DIALOG \\00B7 SHOWN IN PLACE";
|
|
5451
|
+
position: absolute;
|
|
5452
|
+
top: 0;
|
|
5453
|
+
left: 0;
|
|
5454
|
+
z-index: 2;
|
|
5455
|
+
padding: 1px 5px;
|
|
5456
|
+
border-radius: 0 0 3px 0;
|
|
5457
|
+
background: color-mix(in srgb, #808080 78%, transparent);
|
|
5458
|
+
color: #fff;
|
|
5459
|
+
font: 700 9px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
5460
|
+
letter-spacing: 0.08em;
|
|
5461
|
+
pointer-events: none;
|
|
5462
|
+
}
|
|
5463
|
+
`;
|
|
5464
|
+
function syncCanvasOverlayCss(doc, mode) {
|
|
5465
|
+
const existing = doc.head.querySelector(`#${CANVAS_OVERLAY_STYLE_ID}`);
|
|
5466
|
+
if (mode === "preview") {
|
|
5467
|
+
existing?.remove();
|
|
5468
|
+
return;
|
|
5469
|
+
}
|
|
5470
|
+
if (existing) {
|
|
5471
|
+
return;
|
|
5472
|
+
}
|
|
5473
|
+
const style = doc.createElement("style");
|
|
5474
|
+
style.id = CANVAS_OVERLAY_STYLE_ID;
|
|
5475
|
+
style.textContent = CANVAS_OVERLAY_CSS;
|
|
5476
|
+
doc.head.append(style);
|
|
5477
|
+
}
|
|
5478
|
+
var DIFF_MARK_STYLE_ID = "jx-canvas-diff-css";
|
|
5479
|
+
var DIFF_MARK_CSS = `
|
|
5480
|
+
[data-jx-diff] {
|
|
5481
|
+
position: relative;
|
|
5482
|
+
border-left-width: 3px;
|
|
5483
|
+
border-left-color: currentColor;
|
|
5484
|
+
}
|
|
5485
|
+
[data-jx-diff]::before {
|
|
5486
|
+
position: absolute;
|
|
5487
|
+
top: 0;
|
|
5488
|
+
left: -3px;
|
|
5489
|
+
width: 3px;
|
|
5490
|
+
content: "";
|
|
5491
|
+
}
|
|
5492
|
+
[data-jx-diff="added"] {
|
|
5493
|
+
border-left-style: solid;
|
|
5494
|
+
border-left-color: #0a7c42;
|
|
5495
|
+
background: color-mix(in srgb, #0a7c42 12%, transparent);
|
|
5496
|
+
}
|
|
5497
|
+
[data-jx-diff="removed"] {
|
|
5498
|
+
border-left-style: double;
|
|
5499
|
+
border-left-color: #c9252d;
|
|
5500
|
+
background: color-mix(in srgb, #c9252d 12%, transparent);
|
|
5501
|
+
}
|
|
5502
|
+
[data-jx-diff="modified-before"] {
|
|
5503
|
+
border-left-style: dashed;
|
|
5504
|
+
border-left-color: #c9252d;
|
|
5505
|
+
background: color-mix(in srgb, #c9252d 8%, transparent);
|
|
5506
|
+
}
|
|
5507
|
+
[data-jx-diff="modified-after"] {
|
|
5508
|
+
border-left-style: dashed;
|
|
5509
|
+
border-left-color: #0a7c42;
|
|
5510
|
+
background: color-mix(in srgb, #0a7c42 8%, transparent);
|
|
5511
|
+
}
|
|
5512
|
+
[data-jx-diff-within] {
|
|
5513
|
+
border-left: 3px dotted color-mix(in srgb, #808080 60%, transparent);
|
|
5514
|
+
}
|
|
5515
|
+
@media (forced-colors: active) {
|
|
5516
|
+
[data-jx-diff],
|
|
5517
|
+
[data-jx-diff-within] {
|
|
5518
|
+
background: none;
|
|
5519
|
+
border-left-color: CanvasText;
|
|
5520
|
+
}
|
|
5521
|
+
}
|
|
5522
|
+
`;
|
|
5523
|
+
function syncDiffCss(doc, on) {
|
|
5524
|
+
const existing = doc.head.querySelector(`#${DIFF_MARK_STYLE_ID}`);
|
|
5525
|
+
if (!on) {
|
|
5526
|
+
existing?.remove();
|
|
5527
|
+
return;
|
|
5528
|
+
}
|
|
5529
|
+
if (existing) {
|
|
5530
|
+
return;
|
|
5531
|
+
}
|
|
5532
|
+
const style = doc.createElement("style");
|
|
5533
|
+
style.id = DIFF_MARK_STYLE_ID;
|
|
5534
|
+
style.textContent = DIFF_MARK_CSS;
|
|
5535
|
+
doc.head.append(style);
|
|
5536
|
+
}
|
|
5537
|
+
function applyDiffMarks(container, marks) {
|
|
5538
|
+
for (const stale of container.querySelectorAll("[data-jx-diff], [data-jx-diff-within]")) {
|
|
5539
|
+
if (stale instanceof HTMLElement) {
|
|
5540
|
+
delete stale.dataset.jxDiff;
|
|
5541
|
+
delete stale.dataset.jxDiffWithin;
|
|
5542
|
+
}
|
|
5543
|
+
}
|
|
5544
|
+
if (!marks?.length) {
|
|
5545
|
+
return;
|
|
5546
|
+
}
|
|
5547
|
+
for (const mark of marks) {
|
|
5548
|
+
const exact = elementForPath(container, mark.path);
|
|
5549
|
+
if (exact) {
|
|
5550
|
+
exact.dataset.jxDiff = mark.kind;
|
|
5551
|
+
continue;
|
|
5552
|
+
}
|
|
5553
|
+
let { path } = mark;
|
|
5554
|
+
while (path.length >= 2) {
|
|
5555
|
+
path = path.slice(0, -2);
|
|
5556
|
+
const ancestor = elementForPath(container, path);
|
|
5557
|
+
if (ancestor) {
|
|
5558
|
+
ancestor.dataset.jxDiffWithin = "";
|
|
5559
|
+
break;
|
|
5560
|
+
}
|
|
5561
|
+
}
|
|
5562
|
+
}
|
|
5563
|
+
}
|
|
4389
5564
|
function syncPreviewShell(doc, mode) {
|
|
4390
5565
|
doc.documentElement.toggleAttribute("data-jx-preview", mode === "preview");
|
|
4391
5566
|
}
|
|
@@ -4528,6 +5703,30 @@ function applyPreviewColorScheme(doc, scheme) {
|
|
|
4528
5703
|
delete doc.documentElement.dataset.colorScheme;
|
|
4529
5704
|
}
|
|
4530
5705
|
}
|
|
5706
|
+
function applyCanvasPopoverOpen(root, path) {
|
|
5707
|
+
for (const el of root.querySelectorAll("[data-jx-popover-open]")) {
|
|
5708
|
+
delete el.dataset.jxPopoverOpen;
|
|
5709
|
+
}
|
|
5710
|
+
if (path === null) {
|
|
5711
|
+
return;
|
|
5712
|
+
}
|
|
5713
|
+
const target = root.querySelector(`[data-jx-popover]${jxPathSelector(path)}`);
|
|
5714
|
+
if (target) {
|
|
5715
|
+
target.dataset.jxPopoverOpen = "";
|
|
5716
|
+
}
|
|
5717
|
+
}
|
|
5718
|
+
function applyCanvasDialogOpen(root, path) {
|
|
5719
|
+
for (const el of root.querySelectorAll("[data-jx-dialog-open]")) {
|
|
5720
|
+
delete el.dataset.jxDialogOpen;
|
|
5721
|
+
}
|
|
5722
|
+
if (path === null) {
|
|
5723
|
+
return;
|
|
5724
|
+
}
|
|
5725
|
+
const target = root.querySelector(`dialog${jxPathSelector(path)}`);
|
|
5726
|
+
if (target) {
|
|
5727
|
+
target.dataset.jxDialogOpen = "";
|
|
5728
|
+
}
|
|
5729
|
+
}
|
|
4531
5730
|
function injectHead(doc, assets = null) {
|
|
4532
5731
|
const head = doc.$head;
|
|
4533
5732
|
if (!Array.isArray(head)) {
|
|
@@ -4570,11 +5769,11 @@ function injectHead(doc, assets = null) {
|
|
|
4570
5769
|
function makeStamper(ctx) {
|
|
4571
5770
|
const islands = [];
|
|
4572
5771
|
const insideIsland = (path) => islands.some((island) => path.length > island.length && island.every((seg, i) => path[i] === seg));
|
|
4573
|
-
return (created, path,
|
|
5772
|
+
return (created, path, def) => {
|
|
4574
5773
|
if (!(created instanceof HTMLElement)) {
|
|
4575
5774
|
return;
|
|
4576
5775
|
}
|
|
4577
|
-
const isDefinitionRoot = path.length === 0 &&
|
|
5776
|
+
const isDefinitionRoot = path.length === 0 && def?.tagName?.includes("-");
|
|
4578
5777
|
if (isDefinitionRoot) {
|
|
4579
5778
|
created.dataset.jxDefinitionRoot = "";
|
|
4580
5779
|
}
|
|
@@ -4583,7 +5782,7 @@ function makeStamper(ctx) {
|
|
|
4583
5782
|
created.contentEditable = "false";
|
|
4584
5783
|
islands.push(path);
|
|
4585
5784
|
}
|
|
4586
|
-
const classified = classifyRenderNode(path,
|
|
5785
|
+
const classified = classifyRenderNode(path, def, ctx);
|
|
4587
5786
|
if (classified.kind === "layout") {
|
|
4588
5787
|
created.dataset.jxLayoutPath = serializeJxPath(classified.layoutPath);
|
|
4589
5788
|
if (classified.layoutFile) {
|
|
@@ -4634,36 +5833,32 @@ async function renderResolvedDocument(opts) {
|
|
|
4634
5833
|
setSkipAutoRequests(opts.mode !== "preview" && !opts.allowAutoRequests);
|
|
4635
5834
|
setCanvasViewportTranspose(true);
|
|
4636
5835
|
setCanvasDelinkAnchors(opts.mode !== "preview");
|
|
5836
|
+
setCanvasDelinkPopovers(opts.mode !== "preview");
|
|
5837
|
+
setCanvasDelinkCommands(opts.mode !== "preview");
|
|
4637
5838
|
setStampPropBindings(opts.mode === "design" || opts.mode === "edit");
|
|
4638
5839
|
applySiteStyle(opts.siteStyle, opts.doc.$media ?? {});
|
|
4639
5840
|
injectHead(opts.doc, assets);
|
|
4640
5841
|
syncEditModeCss(opts.container.ownerDocument, opts.mode);
|
|
5842
|
+
syncCanvasOverlayCss(opts.container.ownerDocument, opts.mode);
|
|
4641
5843
|
syncPreviewShell(opts.container.ownerDocument, opts.mode);
|
|
4642
5844
|
syncStylebookCss(opts.container.ownerDocument, opts.mode);
|
|
5845
|
+
syncDiffCss(opts.container.ownerDocument, Boolean(opts.diffMarks?.length));
|
|
4643
5846
|
setRootMedia(opts.doc.$media ?? {});
|
|
4644
5847
|
await registerElements2(opts.doc, opts.docBase);
|
|
4645
5848
|
const $defs = await buildScope(opts.doc, {}, opts.docBase);
|
|
4646
5849
|
const onNodeCreated = makeStamper(opts.mapperCtx);
|
|
4647
5850
|
const { result: el, stop } = runScoped(() => renderNode(opts.doc, $defs, { _path: [], onNodeCreated }));
|
|
4648
5851
|
opts.container.replaceChildren(el);
|
|
5852
|
+
applyCanvasPopoverOpen(opts.container, opts.popoverOpen ?? null);
|
|
5853
|
+
applyCanvasDialogOpen(opts.container, opts.dialogOpen ?? null);
|
|
4649
5854
|
syncEditableRoot(opts.container, opts.mode);
|
|
5855
|
+
applyDiffMarks(opts.container, opts.diffMarks ?? null);
|
|
4650
5856
|
return {
|
|
4651
5857
|
ctx: { defs: $defs, docBase: opts.docBase, mapperCtx: opts.mapperCtx, mode: opts.mode },
|
|
4652
5858
|
dispose: stop
|
|
4653
5859
|
};
|
|
4654
5860
|
}
|
|
4655
5861
|
|
|
4656
|
-
// src/utils/geometry.ts
|
|
4657
|
-
function rectOf(el) {
|
|
4658
|
-
return el.getBoundingClientRect();
|
|
4659
|
-
}
|
|
4660
|
-
function rectOfRange(r) {
|
|
4661
|
-
return r.getBoundingClientRect();
|
|
4662
|
-
}
|
|
4663
|
-
function elementAtPoint(x, y, root = document) {
|
|
4664
|
-
return root.elementFromPoint(x, y);
|
|
4665
|
-
}
|
|
4666
|
-
|
|
4667
5862
|
// src/state.ts
|
|
4668
5863
|
function getNodeAtPath(doc, path) {
|
|
4669
5864
|
let node = doc;
|
|
@@ -4811,41 +6006,35 @@ var elements_meta_default = {
|
|
|
4811
6006
|
{
|
|
4812
6007
|
tag: "strong",
|
|
4813
6008
|
label: "Bold",
|
|
4814
|
-
icon: "sp-icon-text-bold",
|
|
4815
6009
|
command: "bold"
|
|
4816
6010
|
},
|
|
4817
6011
|
{
|
|
4818
6012
|
tag: "em",
|
|
4819
6013
|
label: "Italic",
|
|
4820
|
-
icon: "sp-icon-text-italic",
|
|
4821
6014
|
command: "italic"
|
|
4822
6015
|
},
|
|
4823
6016
|
{
|
|
4824
6017
|
tag: "u",
|
|
4825
6018
|
label: "Underline",
|
|
4826
|
-
icon: "sp-icon-text-underline",
|
|
4827
6019
|
command: "underline"
|
|
4828
6020
|
},
|
|
4829
6021
|
{
|
|
4830
6022
|
tag: "del",
|
|
4831
6023
|
label: "Strikethrough",
|
|
4832
|
-
icon: "sp-icon-text-strikethrough",
|
|
4833
6024
|
command: "strikethrough"
|
|
4834
6025
|
},
|
|
4835
6026
|
{
|
|
4836
6027
|
tag: "sup",
|
|
4837
6028
|
label: "Superscript",
|
|
4838
|
-
icon: "sp-icon-text-superscript",
|
|
4839
6029
|
command: "superscript"
|
|
4840
6030
|
},
|
|
4841
6031
|
{
|
|
4842
6032
|
tag: "sub",
|
|
4843
6033
|
label: "Subscript",
|
|
4844
|
-
icon: "sp-icon-text-subscript",
|
|
4845
6034
|
command: "subscript"
|
|
4846
6035
|
},
|
|
4847
|
-
{ tag: "code", label: "Code",
|
|
4848
|
-
{ tag: "a", label: "Link",
|
|
6036
|
+
{ tag: "code", label: "Code", command: "code" },
|
|
6037
|
+
{ tag: "a", label: "Link", command: "link" }
|
|
4849
6038
|
]
|
|
4850
6039
|
},
|
|
4851
6040
|
h1: {
|
|
@@ -4855,17 +6044,15 @@ var elements_meta_default = {
|
|
|
4855
6044
|
{
|
|
4856
6045
|
tag: "strong",
|
|
4857
6046
|
label: "Bold",
|
|
4858
|
-
icon: "sp-icon-text-bold",
|
|
4859
6047
|
command: "bold"
|
|
4860
6048
|
},
|
|
4861
6049
|
{
|
|
4862
6050
|
tag: "em",
|
|
4863
6051
|
label: "Italic",
|
|
4864
|
-
icon: "sp-icon-text-italic",
|
|
4865
6052
|
command: "italic"
|
|
4866
6053
|
},
|
|
4867
|
-
{ tag: "code", label: "Code",
|
|
4868
|
-
{ tag: "a", label: "Link",
|
|
6054
|
+
{ tag: "code", label: "Code", command: "code" },
|
|
6055
|
+
{ tag: "a", label: "Link", command: "link" }
|
|
4869
6056
|
]
|
|
4870
6057
|
},
|
|
4871
6058
|
h2: {
|
|
@@ -5088,16 +6275,14 @@ var elements_meta_default = {
|
|
|
5088
6275
|
{
|
|
5089
6276
|
tag: "strong",
|
|
5090
6277
|
label: "Bold",
|
|
5091
|
-
icon: "sp-icon-text-bold",
|
|
5092
6278
|
command: "bold"
|
|
5093
6279
|
},
|
|
5094
6280
|
{
|
|
5095
6281
|
tag: "em",
|
|
5096
6282
|
label: "Italic",
|
|
5097
|
-
icon: "sp-icon-text-italic",
|
|
5098
6283
|
command: "italic"
|
|
5099
6284
|
},
|
|
5100
|
-
{ tag: "code", label: "Code",
|
|
6285
|
+
{ tag: "code", label: "Code", command: "code" }
|
|
5101
6286
|
]
|
|
5102
6287
|
},
|
|
5103
6288
|
span: {
|
|
@@ -5526,7 +6711,7 @@ function findTemplateExpressions(text) {
|
|
|
5526
6711
|
|
|
5527
6712
|
// src/editor/editable-tags.ts
|
|
5528
6713
|
var EXCLUDED = new Set(["pre"]);
|
|
5529
|
-
var BUILTIN_EDITABLE_TAGS = new Set(Object.entries(elements_meta_default.$defs).filter(([tag,
|
|
6714
|
+
var BUILTIN_EDITABLE_TAGS = new Set(Object.entries(elements_meta_default.$defs).filter(([tag, def]) => !EXCLUDED.has(tag) && (def.$inlineChildren?.length ?? 0) > 0).map(([tag]) => tag));
|
|
5530
6715
|
function isEditableTag(tag, verdicts) {
|
|
5531
6716
|
const declared = verdicts?.[tag.toLowerCase()];
|
|
5532
6717
|
return declared ?? BUILTIN_EDITABLE_TAGS.has(tag.toLowerCase());
|
|
@@ -5978,18 +7163,64 @@ function nearestHit(target) {
|
|
|
5978
7163
|
}
|
|
5979
7164
|
return measureHit(el, el.dataset.jxPath);
|
|
5980
7165
|
}
|
|
7166
|
+
function isRendered(el) {
|
|
7167
|
+
const check = el.checkVisibility;
|
|
7168
|
+
return typeof check === "function" ? check.call(el, { checkVisibilityCSS: true }) : true;
|
|
7169
|
+
}
|
|
5981
7170
|
function measureHits(paths, doc = document) {
|
|
5982
|
-
const
|
|
7171
|
+
const hits = [];
|
|
7172
|
+
const hidden = [];
|
|
5983
7173
|
for (const path of paths) {
|
|
5984
|
-
const
|
|
5985
|
-
|
|
5986
|
-
|
|
5987
|
-
|
|
7174
|
+
const el = doc.querySelector(jxPathSelector(serializeJxPath(path)));
|
|
7175
|
+
if (!el) {
|
|
7176
|
+
continue;
|
|
7177
|
+
}
|
|
7178
|
+
if (isRendered(el)) {
|
|
5988
7179
|
const r = rectOf(el);
|
|
5989
|
-
|
|
7180
|
+
hits.push({ path, rect: { height: r.height, width: r.width, x: r.x, y: r.y } });
|
|
7181
|
+
} else {
|
|
7182
|
+
hidden.push(path);
|
|
5990
7183
|
}
|
|
5991
7184
|
}
|
|
5992
|
-
return
|
|
7185
|
+
return { hidden, hits };
|
|
7186
|
+
}
|
|
7187
|
+
var INVOKER_ACTIONS = new Set(["toggle", "show", "hide"]);
|
|
7188
|
+
function postPopoverInvoke(target, channel) {
|
|
7189
|
+
if (!(target instanceof Element)) {
|
|
7190
|
+
return;
|
|
7191
|
+
}
|
|
7192
|
+
const invoker = target.closest("[popovertarget]");
|
|
7193
|
+
const id = invoker?.getAttribute("popovertarget");
|
|
7194
|
+
if (!invoker || !id) {
|
|
7195
|
+
return;
|
|
7196
|
+
}
|
|
7197
|
+
const panels = invoker.ownerDocument.querySelectorAll("[data-jx-popover]");
|
|
7198
|
+
const panel = [...panels].find((el) => el.id === id);
|
|
7199
|
+
const serialized = panel?.dataset.jxPath;
|
|
7200
|
+
if (!serialized) {
|
|
7201
|
+
return;
|
|
7202
|
+
}
|
|
7203
|
+
const raw = invoker.getAttribute("popovertargetaction") ?? "toggle";
|
|
7204
|
+
const action = INVOKER_ACTIONS.has(raw) ? raw : "toggle";
|
|
7205
|
+
channel.post({ action, kind: "popoverTargetClick", targetPath: parseJxPath(serialized) });
|
|
7206
|
+
}
|
|
7207
|
+
function postCommandInvoke(target, channel) {
|
|
7208
|
+
if (!(target instanceof Element)) {
|
|
7209
|
+
return;
|
|
7210
|
+
}
|
|
7211
|
+
const invoker = target.closest("[data-jx-commandfor]");
|
|
7212
|
+
const id = invoker?.dataset["jxCommandfor"];
|
|
7213
|
+
const command = invoker?.getAttribute("command")?.trim().toLowerCase() ?? "";
|
|
7214
|
+
if (!invoker || !id || !command) {
|
|
7215
|
+
return;
|
|
7216
|
+
}
|
|
7217
|
+
const overlays = invoker.ownerDocument.querySelectorAll("[data-jx-popover], dialog[data-jx-path]");
|
|
7218
|
+
const overlay = [...overlays].find((el) => el.id === id);
|
|
7219
|
+
const serialized = overlay?.dataset.jxPath;
|
|
7220
|
+
if (!serialized) {
|
|
7221
|
+
return;
|
|
7222
|
+
}
|
|
7223
|
+
channel.post({ command, kind: "commandTargetClick", targetPath: parseJxPath(serialized) });
|
|
5993
7224
|
}
|
|
5994
7225
|
function startInteraction(channel, doc = document, deps) {
|
|
5995
7226
|
let lastHoverKey = null;
|
|
@@ -6020,6 +7251,8 @@ function startInteraction(channel, doc = document, deps) {
|
|
|
6020
7251
|
kind: "hit"
|
|
6021
7252
|
});
|
|
6022
7253
|
}
|
|
7254
|
+
postPopoverInvoke(e.target, channel);
|
|
7255
|
+
postCommandInvoke(e.target, channel);
|
|
6023
7256
|
};
|
|
6024
7257
|
const reportHover = (el) => {
|
|
6025
7258
|
if (isPreview()) {
|
|
@@ -6251,112 +7484,6 @@ function scrollDirection(y, viewportH, band = AUTO_SCROLL_BAND) {
|
|
|
6251
7484
|
return 0;
|
|
6252
7485
|
}
|
|
6253
7486
|
|
|
6254
|
-
// src/canvas/iframe-position.ts
|
|
6255
|
-
function isIslandBoundary(el) {
|
|
6256
|
-
if (el.dataset.jxDefinitionRoot !== undefined) {
|
|
6257
|
-
return false;
|
|
6258
|
-
}
|
|
6259
|
-
return el.getAttribute("contenteditable") === "false" || el.tagName.includes("-");
|
|
6260
|
-
}
|
|
6261
|
-
function activeBlockAt(node, isEditable) {
|
|
6262
|
-
let el = node instanceof Element ? node : node?.parentElement ?? null;
|
|
6263
|
-
while (el) {
|
|
6264
|
-
if (el instanceof HTMLElement) {
|
|
6265
|
-
if (el.dataset.jxPath && isEditable(el)) {
|
|
6266
|
-
return { el, path: parseJxPath(el.dataset.jxPath) };
|
|
6267
|
-
}
|
|
6268
|
-
if (isIslandBoundary(el)) {
|
|
6269
|
-
return null;
|
|
6270
|
-
}
|
|
6271
|
-
}
|
|
6272
|
-
el = el.parentElement;
|
|
6273
|
-
}
|
|
6274
|
-
return null;
|
|
6275
|
-
}
|
|
6276
|
-
function elementForPath(container, path) {
|
|
6277
|
-
const serialized = serializeJxPath(path);
|
|
6278
|
-
const esc = serialized.replaceAll("\\", String.raw`\\`).replaceAll("'", String.raw`\'`);
|
|
6279
|
-
const el = container.querySelector(`[data-jx-path='${esc}']`);
|
|
6280
|
-
return el instanceof HTMLElement ? el : null;
|
|
6281
|
-
}
|
|
6282
|
-
function blockTextLength(block) {
|
|
6283
|
-
return block.textContent?.length ?? 0;
|
|
6284
|
-
}
|
|
6285
|
-
function offsetOf(block, node, offset) {
|
|
6286
|
-
if (!block.contains(node)) {
|
|
6287
|
-
return null;
|
|
6288
|
-
}
|
|
6289
|
-
const range = block.ownerDocument.createRange();
|
|
6290
|
-
range.setStart(block, 0);
|
|
6291
|
-
try {
|
|
6292
|
-
range.setEnd(node, offset);
|
|
6293
|
-
} catch {
|
|
6294
|
-
return null;
|
|
6295
|
-
}
|
|
6296
|
-
return range.toString().length;
|
|
6297
|
-
}
|
|
6298
|
-
function domPositionAt(block, offset) {
|
|
6299
|
-
const target = Math.max(0, Math.min(offset, blockTextLength(block)));
|
|
6300
|
-
const walker = block.ownerDocument.createTreeWalker(block, NodeFilter.SHOW_TEXT);
|
|
6301
|
-
let seen = 0;
|
|
6302
|
-
let last = null;
|
|
6303
|
-
let current = walker.nextNode();
|
|
6304
|
-
while (current) {
|
|
6305
|
-
const len = current.length;
|
|
6306
|
-
if (seen + len >= target) {
|
|
6307
|
-
return { node: current, offset: target - seen };
|
|
6308
|
-
}
|
|
6309
|
-
seen += len;
|
|
6310
|
-
last = current;
|
|
6311
|
-
current = walker.nextNode();
|
|
6312
|
-
}
|
|
6313
|
-
return last ? { node: last, offset: last.length } : { node: block, offset: 0 };
|
|
6314
|
-
}
|
|
6315
|
-
function toDocPos(node, offset, isEditable) {
|
|
6316
|
-
const block = activeBlockAt(node, isEditable);
|
|
6317
|
-
if (!block || !node) {
|
|
6318
|
-
return null;
|
|
6319
|
-
}
|
|
6320
|
-
const charOffset = offsetOf(block.el, node, offset);
|
|
6321
|
-
return charOffset === null ? null : { offset: charOffset, path: block.path };
|
|
6322
|
-
}
|
|
6323
|
-
function toDomPosition(container, pos) {
|
|
6324
|
-
const el = elementForPath(container, pos.path);
|
|
6325
|
-
return el ? domPositionAt(el, pos.offset) : null;
|
|
6326
|
-
}
|
|
6327
|
-
function isAtBlockStart(pos) {
|
|
6328
|
-
return pos.offset <= 0;
|
|
6329
|
-
}
|
|
6330
|
-
function samePath(a, b) {
|
|
6331
|
-
return serializeJxPath(a.path) === serializeJxPath(b.path);
|
|
6332
|
-
}
|
|
6333
|
-
function blocksInOrder(container, isEditable) {
|
|
6334
|
-
const out = [];
|
|
6335
|
-
for (const el of container.querySelectorAll("[data-jx-path]")) {
|
|
6336
|
-
if (isEditable(el) && !sealedInIsland(el, container)) {
|
|
6337
|
-
out.push(el);
|
|
6338
|
-
}
|
|
6339
|
-
}
|
|
6340
|
-
return out;
|
|
6341
|
-
}
|
|
6342
|
-
function sealedInIsland(el, container) {
|
|
6343
|
-
let cur = el.parentElement;
|
|
6344
|
-
while (cur && cur !== container) {
|
|
6345
|
-
if (isIslandBoundary(cur)) {
|
|
6346
|
-
return true;
|
|
6347
|
-
}
|
|
6348
|
-
cur = cur.parentElement;
|
|
6349
|
-
}
|
|
6350
|
-
return false;
|
|
6351
|
-
}
|
|
6352
|
-
function adjacentBlock(container, path, direction, isEditable) {
|
|
6353
|
-
const blocks = blocksInOrder(container, isEditable);
|
|
6354
|
-
const key = serializeJxPath(path);
|
|
6355
|
-
const index = blocks.findIndex((el) => el.dataset.jxPath === key);
|
|
6356
|
-
const neighbour = index === -1 ? undefined : blocks[index + direction];
|
|
6357
|
-
return neighbour ? { el: neighbour, path: parseJxPath(neighbour.dataset.jxPath) } : null;
|
|
6358
|
-
}
|
|
6359
|
-
|
|
6360
7487
|
// src/canvas/editable-actions.ts
|
|
6361
7488
|
var DELETE_BACKWARD = new Set([
|
|
6362
7489
|
"deleteContentBackward",
|
|
@@ -6465,7 +7592,7 @@ function restoreDocSelection(container, range) {
|
|
|
6465
7592
|
}
|
|
6466
7593
|
function startEditableRoot(container, deps) {
|
|
6467
7594
|
const doc = container.ownerDocument;
|
|
6468
|
-
let
|
|
7595
|
+
let activeEl = null;
|
|
6469
7596
|
let activeKey = null;
|
|
6470
7597
|
const editingAllowed = () => {
|
|
6471
7598
|
const mode = deps.getMode?.();
|
|
@@ -6480,7 +7607,7 @@ function startEditableRoot(container, deps) {
|
|
|
6480
7607
|
};
|
|
6481
7608
|
const commitTick = () => {
|
|
6482
7609
|
commitTimer = 0;
|
|
6483
|
-
if (!
|
|
7610
|
+
if (!activeEl || !deps.onCommitTick) {
|
|
6484
7611
|
return;
|
|
6485
7612
|
}
|
|
6486
7613
|
const caret = captureDocSelection(container, deps.isEditableBlock);
|
|
@@ -6491,7 +7618,7 @@ function startEditableRoot(container, deps) {
|
|
|
6491
7618
|
};
|
|
6492
7619
|
let composing = false;
|
|
6493
7620
|
const scheduleCommitTick = () => {
|
|
6494
|
-
if (!deps.onCommitTick || !
|
|
7621
|
+
if (!deps.onCommitTick || !activeEl || composing) {
|
|
6495
7622
|
return;
|
|
6496
7623
|
}
|
|
6497
7624
|
cancelCommitTick();
|
|
@@ -6507,15 +7634,15 @@ function startEditableRoot(container, deps) {
|
|
|
6507
7634
|
};
|
|
6508
7635
|
const forget = () => {
|
|
6509
7636
|
cancelCommitTick();
|
|
6510
|
-
|
|
7637
|
+
activeEl = null;
|
|
6511
7638
|
activeKey = null;
|
|
6512
7639
|
};
|
|
6513
7640
|
const deactivate = () => {
|
|
6514
|
-
if (!
|
|
7641
|
+
if (!activeEl) {
|
|
6515
7642
|
return;
|
|
6516
7643
|
}
|
|
6517
7644
|
cancelCommitTick();
|
|
6518
|
-
|
|
7645
|
+
activeEl = null;
|
|
6519
7646
|
activeKey = null;
|
|
6520
7647
|
deps.onDeactivate();
|
|
6521
7648
|
};
|
|
@@ -6535,7 +7662,7 @@ function startEditableRoot(container, deps) {
|
|
|
6535
7662
|
}
|
|
6536
7663
|
const block = activeBlockAt(focus, deps.isEditableBlock);
|
|
6537
7664
|
if (!block) {
|
|
6538
|
-
if (
|
|
7665
|
+
if (activeEl?.contains(focus)) {
|
|
6539
7666
|
deps.onSelectionChange?.();
|
|
6540
7667
|
return;
|
|
6541
7668
|
}
|
|
@@ -6548,7 +7675,7 @@ function startEditableRoot(container, deps) {
|
|
|
6548
7675
|
return;
|
|
6549
7676
|
}
|
|
6550
7677
|
deactivate();
|
|
6551
|
-
|
|
7678
|
+
activeEl = block.el;
|
|
6552
7679
|
activeKey = key;
|
|
6553
7680
|
deps.onActivate(block.el, block.path);
|
|
6554
7681
|
};
|
|
@@ -6584,7 +7711,7 @@ function startEditableRoot(container, deps) {
|
|
|
6584
7711
|
atBlockStart: resolved ? isAtBlockStart(resolved.from) : false,
|
|
6585
7712
|
data: e.data ?? "",
|
|
6586
7713
|
from: resolved?.from ?? null,
|
|
6587
|
-
inPropHost:
|
|
7714
|
+
inPropHost: activeEl !== null && activeKey === null,
|
|
6588
7715
|
inputType: e.inputType,
|
|
6589
7716
|
to: resolved?.to ?? null
|
|
6590
7717
|
});
|
|
@@ -6627,10 +7754,10 @@ function startEditableRoot(container, deps) {
|
|
|
6627
7754
|
let el = e.target instanceof Element ? e.target : null;
|
|
6628
7755
|
while (el && el !== container) {
|
|
6629
7756
|
if (el.dataset?.jxBoundProp) {
|
|
6630
|
-
if (el !==
|
|
7757
|
+
if (el !== activeEl) {
|
|
6631
7758
|
deactivate();
|
|
6632
7759
|
if (deps.onPropActivate(el)) {
|
|
6633
|
-
|
|
7760
|
+
activeEl = el;
|
|
6634
7761
|
activeKey = null;
|
|
6635
7762
|
}
|
|
6636
7763
|
}
|
|
@@ -6891,8 +8018,8 @@ function prepareForEditMode(node) {
|
|
|
6891
8018
|
propsOut[pk] = templateToEditDisplay(pv);
|
|
6892
8019
|
}
|
|
6893
8020
|
} else if (pv && typeof pv === "object" && pv.$ref) {
|
|
6894
|
-
const
|
|
6895
|
-
const label =
|
|
8021
|
+
const ref = pv.$ref;
|
|
8022
|
+
const label = ref.startsWith("#/state/") ? ref.slice(8) : ref;
|
|
6896
8023
|
propsOut[pk] = `{${label}}`;
|
|
6897
8024
|
} else {
|
|
6898
8025
|
propsOut[pk] = pv;
|
|
@@ -6943,8 +8070,8 @@ function prepareForEditMode(node) {
|
|
|
6943
8070
|
const isUrlAttr = ak === "href" || ak === "action";
|
|
6944
8071
|
processed[ak] = isUrlAttr ? "" : templateToEditDisplay(av);
|
|
6945
8072
|
} else if (av && typeof av === "object" && av.$ref) {
|
|
6946
|
-
const
|
|
6947
|
-
const label =
|
|
8073
|
+
const ref = av.$ref;
|
|
8074
|
+
const label = ref.startsWith("#/state/") ? ref.slice(8) : ref;
|
|
6948
8075
|
processed[ak] = `{${label}}`;
|
|
6949
8076
|
} else {
|
|
6950
8077
|
processed[ak] = av;
|
|
@@ -6955,7 +8082,9 @@ function prepareForEditMode(node) {
|
|
|
6955
8082
|
if (v && typeof v === "object") {
|
|
6956
8083
|
const s = {};
|
|
6957
8084
|
for (const [sk, sv] of Object.entries(v)) {
|
|
6958
|
-
|
|
8085
|
+
if (typeof sv !== "string" || !sv.includes("${")) {
|
|
8086
|
+
s[sk] = sv;
|
|
8087
|
+
}
|
|
6959
8088
|
}
|
|
6960
8089
|
out.style = s;
|
|
6961
8090
|
} else {
|
|
@@ -6971,8 +8100,8 @@ function prepareForEditMode(node) {
|
|
|
6971
8100
|
out[k] = isUrlAttr ? "" : templateToEditDisplay(v);
|
|
6972
8101
|
}
|
|
6973
8102
|
} else if (v && typeof v === "object" && v.$ref) {
|
|
6974
|
-
const
|
|
6975
|
-
const label =
|
|
8103
|
+
const ref = v.$ref;
|
|
8104
|
+
const label = ref.startsWith("#/state/") ? ref.slice(8) : ref;
|
|
6976
8105
|
const isMediaSrc = (k === "src" || k === "poster") && mediaTags.has(obj.tagName || "");
|
|
6977
8106
|
if (isMediaSrc) {
|
|
6978
8107
|
needsMediaPlaceholder = true;
|
|
@@ -7700,8 +8829,8 @@ function renderSubtreeIframe(shadowDoc, docPath, ctx) {
|
|
|
7700
8829
|
if (node === undefined) {
|
|
7701
8830
|
throw new Error(`iframe-patch-node-not-found:${docPath.join("/")}`);
|
|
7702
8831
|
}
|
|
7703
|
-
const
|
|
7704
|
-
const { result: rendered, stop } = runScoped(() => renderNode(
|
|
8832
|
+
const def = typeof node === "string" ? node : prepareForEditMode(stripEventHandlers(node));
|
|
8833
|
+
const { result: rendered, stop } = runScoped(() => renderNode(def, ctx.defs, {
|
|
7705
8834
|
_path: docPathToRenderPath(docPath, ctx),
|
|
7706
8835
|
onNodeCreated: makeStamper(ctx.mapperCtx)
|
|
7707
8836
|
}));
|
|
@@ -7717,11 +8846,7 @@ function disposeSubtree(el) {
|
|
|
7717
8846
|
if (!(t instanceof HTMLElement)) {
|
|
7718
8847
|
continue;
|
|
7719
8848
|
}
|
|
7720
|
-
|
|
7721
|
-
if (tag) {
|
|
7722
|
-
tag.remove();
|
|
7723
|
-
elementStyleTags.delete(t);
|
|
7724
|
-
}
|
|
8849
|
+
releaseElementStyles(t);
|
|
7725
8850
|
const stop = elScope.get(t);
|
|
7726
8851
|
if (stop) {
|
|
7727
8852
|
stop();
|
|
@@ -7869,9 +8994,9 @@ function syncPlaceholderClass(el, node) {
|
|
|
7869
8994
|
el.classList.add(placeholder);
|
|
7870
8995
|
}
|
|
7871
8996
|
}
|
|
7872
|
-
function insertAt(parentEl, node,
|
|
7873
|
-
if (
|
|
7874
|
-
|
|
8997
|
+
function insertAt(parentEl, node, ref) {
|
|
8998
|
+
if (ref) {
|
|
8999
|
+
ref.before(node);
|
|
7875
9000
|
} else {
|
|
7876
9001
|
parentEl.append(node);
|
|
7877
9002
|
}
|
|
@@ -7945,7 +9070,10 @@ function editModeStyle(style) {
|
|
|
7945
9070
|
}
|
|
7946
9071
|
const out = {};
|
|
7947
9072
|
for (const [k, v] of Object.entries(style)) {
|
|
7948
|
-
|
|
9073
|
+
if (typeof v === "string" && v.includes("${")) {
|
|
9074
|
+
continue;
|
|
9075
|
+
}
|
|
9076
|
+
out[k] = v;
|
|
7949
9077
|
}
|
|
7950
9078
|
return out;
|
|
7951
9079
|
}
|
|
@@ -7958,8 +9086,8 @@ function textDisplayValue(node) {
|
|
|
7958
9086
|
return v.includes("${") ? templateToEditDisplay(v) : v;
|
|
7959
9087
|
}
|
|
7960
9088
|
if (typeof v === "object" && v.$ref) {
|
|
7961
|
-
const
|
|
7962
|
-
const label =
|
|
9089
|
+
const ref = String(v.$ref);
|
|
9090
|
+
const label = ref.startsWith("#/state/") ? ref.slice(8) : ref;
|
|
7963
9091
|
return `{${label}}`;
|
|
7964
9092
|
}
|
|
7965
9093
|
return String(v);
|
|
@@ -8094,6 +9222,32 @@ function serializeDataScope(defs) {
|
|
|
8094
9222
|
return out;
|
|
8095
9223
|
}
|
|
8096
9224
|
|
|
9225
|
+
// ../ui/src/loaders.ts
|
|
9226
|
+
var KIT_LOADERS = {
|
|
9227
|
+
"jx-ui:/behaviors/color-area.ts": () => (__preload("v17df7b8"), import("./chunks/color-area-v17df7b8.js")),
|
|
9228
|
+
"jx-ui:/behaviors/color-field.ts": () => (__preload("anwybnkn"), import("./chunks/color-field-anwybnkn.js")),
|
|
9229
|
+
"jx-ui:/behaviors/color-slider.ts": () => (__preload("44ez96fc"), import("./chunks/color-slider-44ez96fc.js")),
|
|
9230
|
+
"jx-ui:/behaviors/combobox.ts": () => (__preload("5e7jev23"), import("./chunks/combobox-5e7jev23.js")),
|
|
9231
|
+
"jx-ui:/behaviors/dialog.ts": () => (__preload("s890b918"), import("./chunks/dialog-s890b918.js")),
|
|
9232
|
+
"jx-ui:/behaviors/listbox.ts": () => (__preload("6v2ac08j"), import("./chunks/listbox-6v2ac08j.js")),
|
|
9233
|
+
"jx-ui:/behaviors/menu.ts": () => (__preload("q99sy9rf"), import("./chunks/menu-q99sy9rf.js")),
|
|
9234
|
+
"jx-ui:/behaviors/number-field.ts": () => (__preload("5cndyft8"), import("./chunks/number-field-5cndyft8.js")),
|
|
9235
|
+
"jx-ui:/behaviors/action-group.ts": () => (__preload("sp6tna8v"), import("./chunks/action-group-sp6tna8v.js")),
|
|
9236
|
+
"jx-ui:/behaviors/popover.ts": () => (__preload("47z3ytva"), import("./chunks/popover-47z3ytva.js")),
|
|
9237
|
+
"jx-ui:/behaviors/select.ts": () => (__preload("2r16ez41"), import("./chunks/select-2r16ez41.js")),
|
|
9238
|
+
"jx-ui:/behaviors/split.ts": () => (__preload("g7nm1rgb"), import("./chunks/split-g7nm1rgb.js")),
|
|
9239
|
+
"jx-ui:/behaviors/swatch-group.ts": () => (__preload("t0n6h2rn"), import("./chunks/swatch-group-t0n6h2rn.js")),
|
|
9240
|
+
"jx-ui:/behaviors/tabs.ts": () => (__preload("wbp1cdws"), import("./chunks/tabs-wbp1cdws.js")),
|
|
9241
|
+
"jx-ui:/behaviors/toolbar.ts": () => (__preload("xbh5bhtr"), import("./chunks/toolbar-xbh5bhtr.js")),
|
|
9242
|
+
"jx-ui:/behaviors/tree.ts": () => (__preload("a73p0pqm"), import("./chunks/tree-a73p0pqm.js")),
|
|
9243
|
+
"jx-ui:/behaviors/tooltip.ts": () => (__preload("eptb614w"), import("./chunks/tooltip-eptb614w.js")),
|
|
9244
|
+
"jx-ui:/behaviors/textfield.ts": () => (__preload("abk6qyee"), import("./chunks/textfield-abk6qyee.js")),
|
|
9245
|
+
"jx-ui:/behaviors/toast.ts": () => (__preload("780pvfbv"), import("./chunks/toast-780pvfbv.js")),
|
|
9246
|
+
"jx-ui:/behaviors/toast-host.ts": () => (__preload("3sqv46sn"), import("./chunks/toast-host-3sqv46sn.js")),
|
|
9247
|
+
"jx-ui:/color.ts": () => (__preload("xgg3kfw7"), import("./chunks/color-xgg3kfw7.js")),
|
|
9248
|
+
"jx-ui:/icons.ts": () => (__preload("yy10wk9r"), import("./chunks/icons-yy10wk9r.js"))
|
|
9249
|
+
};
|
|
9250
|
+
|
|
8097
9251
|
// src/services/bundle-base.ts
|
|
8098
9252
|
var base;
|
|
8099
9253
|
function setBundleBase(entryUrl) {
|
|
@@ -8102,6 +9256,9 @@ function setBundleBase(entryUrl) {
|
|
|
8102
9256
|
|
|
8103
9257
|
// src/canvas/iframe-entry.ts
|
|
8104
9258
|
setBundleBase(import.meta.url);
|
|
9259
|
+
for (const [specifier, load] of Object.entries(KIT_LOADERS)) {
|
|
9260
|
+
preloadModule(specifier, load);
|
|
9261
|
+
}
|
|
8105
9262
|
function previewAt(cursor, src, shadowDoc, doc) {
|
|
8106
9263
|
const targetEl = resolveDropTarget(cursor.x, cursor.y, doc);
|
|
8107
9264
|
if (!targetEl) {
|
|
@@ -8147,8 +9304,8 @@ function layoutHitFor(target) {
|
|
|
8147
9304
|
}
|
|
8148
9305
|
var IN_PLACE_KEYS = new Set(["style", "textContent"]);
|
|
8149
9306
|
function patchDisturbsActiveEdit(forwardOps) {
|
|
8150
|
-
const
|
|
8151
|
-
if (!
|
|
9307
|
+
const activePath = getActivePath();
|
|
9308
|
+
if (!activePath) {
|
|
8152
9309
|
return false;
|
|
8153
9310
|
}
|
|
8154
9311
|
for (const op of forwardOps) {
|
|
@@ -8160,14 +9317,14 @@ function patchDisturbsActiveEdit(forwardOps) {
|
|
|
8160
9317
|
affected = op.path;
|
|
8161
9318
|
} else if (op.op === "move-child") {
|
|
8162
9319
|
affected = op.fromParentPath;
|
|
8163
|
-
if (isAncestor(affected,
|
|
9320
|
+
if (isAncestor(affected, activePath) || isAncestor(op.toParentPath, activePath)) {
|
|
8164
9321
|
return true;
|
|
8165
9322
|
}
|
|
8166
9323
|
continue;
|
|
8167
9324
|
} else {
|
|
8168
9325
|
affected = op.parentPath;
|
|
8169
9326
|
}
|
|
8170
|
-
if (isAncestor(affected,
|
|
9327
|
+
if (isAncestor(affected, activePath)) {
|
|
8171
9328
|
return true;
|
|
8172
9329
|
}
|
|
8173
9330
|
}
|
|
@@ -8184,6 +9341,8 @@ function startCanvasIframe(opts) {
|
|
|
8184
9341
|
let shadowDoc = null;
|
|
8185
9342
|
let renderedGen = -1;
|
|
8186
9343
|
let currentMode = "design";
|
|
9344
|
+
let popoverOpen = null;
|
|
9345
|
+
let dialogOpen = null;
|
|
8187
9346
|
let forwardTable = NO_TABLE;
|
|
8188
9347
|
let renderCtx = null;
|
|
8189
9348
|
let dragSrc = null;
|
|
@@ -8264,8 +9423,18 @@ function startCanvasIframe(opts) {
|
|
|
8264
9423
|
const stopImageRetry = installCanvasImageRetry(container);
|
|
8265
9424
|
const MAX_CANVAS_HEIGHT = 30000;
|
|
8266
9425
|
let lastPostedHeight = -1;
|
|
9426
|
+
function openPopoverBottom() {
|
|
9427
|
+
const panels = container.querySelectorAll("[data-jx-popover][data-jx-popover-open], dialog[data-jx-dialog-open]");
|
|
9428
|
+
const root = rectOf(container);
|
|
9429
|
+
let bottom = 0;
|
|
9430
|
+
for (const panel of panels) {
|
|
9431
|
+
bottom = Math.max(bottom, rectOf(panel).bottom - root.top);
|
|
9432
|
+
}
|
|
9433
|
+
return bottom;
|
|
9434
|
+
}
|
|
8267
9435
|
function postContentHeight() {
|
|
8268
|
-
const
|
|
9436
|
+
const content = Math.max(container.scrollHeight, openPopoverBottom());
|
|
9437
|
+
const measured = Math.min(content, MAX_CANVAS_HEIGHT);
|
|
8269
9438
|
if (measured > 0 && Math.abs(measured - lastPostedHeight) >= 1) {
|
|
8270
9439
|
lastPostedHeight = measured;
|
|
8271
9440
|
const root = container.firstElementChild;
|
|
@@ -8313,6 +9482,7 @@ function startCanvasIframe(opts) {
|
|
|
8313
9482
|
const quiet = sample.fonts && sample.animations === 0 && sample.images === 0;
|
|
8314
9483
|
quietFrames = quiet ? changed ? 1 : quietFrames + 1 : 0;
|
|
8315
9484
|
if (quietFrames >= IDLE_QUIET_FRAMES) {
|
|
9485
|
+
postContentHeight();
|
|
8316
9486
|
return;
|
|
8317
9487
|
}
|
|
8318
9488
|
if (Date.now() >= idleDeadline) {
|
|
@@ -8436,11 +9606,8 @@ function startCanvasIframe(opts) {
|
|
|
8436
9606
|
container.ownerDocument.addEventListener("drop", onNativeDrop, true);
|
|
8437
9607
|
const off = channel.onMessage((msg) => {
|
|
8438
9608
|
if (msg.kind === "measure") {
|
|
8439
|
-
|
|
8440
|
-
|
|
8441
|
-
kind: "geometry",
|
|
8442
|
-
reqId: msg.reqId
|
|
8443
|
-
});
|
|
9609
|
+
const { hidden, hits } = measureHits(msg.paths, container.ownerDocument);
|
|
9610
|
+
channel.post({ hidden, hits, kind: "geometry", reqId: msg.reqId });
|
|
8444
9611
|
return;
|
|
8445
9612
|
}
|
|
8446
9613
|
if (msg.kind === "evalExpr") {
|
|
@@ -8449,13 +9616,13 @@ function startCanvasIframe(opts) {
|
|
|
8449
9616
|
return;
|
|
8450
9617
|
}
|
|
8451
9618
|
if (msg.kind === "patch") {
|
|
8452
|
-
const { gen
|
|
8453
|
-
if (
|
|
8454
|
-
channel.post({ gen
|
|
9619
|
+
const { gen } = msg;
|
|
9620
|
+
if (gen < renderedGen) {
|
|
9621
|
+
channel.post({ gen, kind: "patchError", message: "patch-behind-render" });
|
|
8455
9622
|
return;
|
|
8456
9623
|
}
|
|
8457
|
-
if (
|
|
8458
|
-
channel.post({ gen
|
|
9624
|
+
if (gen > renderedGen || !shadowDoc || !renderCtx) {
|
|
9625
|
+
channel.post({ gen, kind: "patchError", message: "patch-ahead-of-render" });
|
|
8459
9626
|
return;
|
|
8460
9627
|
}
|
|
8461
9628
|
const echoed = new Set((msg.echoPaths ?? []).map((p) => serializeJxPath(p)));
|
|
@@ -8467,14 +9634,16 @@ function startCanvasIframe(opts) {
|
|
|
8467
9634
|
}
|
|
8468
9635
|
try {
|
|
8469
9636
|
applyIframePatch(shadowDoc, msg.forwardOps, container, renderCtx, msg.echoPaths);
|
|
9637
|
+
applyCanvasPopoverOpen(container, popoverOpen);
|
|
9638
|
+
applyCanvasDialogOpen(container, dialogOpen);
|
|
8470
9639
|
if (caret) {
|
|
8471
9640
|
restoreDocSelection(container, caret);
|
|
8472
9641
|
}
|
|
8473
|
-
channel.post({ gen
|
|
9642
|
+
channel.post({ gen, kind: "patchComplete" });
|
|
8474
9643
|
armIdleWatch();
|
|
8475
9644
|
} catch (error) {
|
|
8476
9645
|
channel.post({
|
|
8477
|
-
gen
|
|
9646
|
+
gen,
|
|
8478
9647
|
kind: "patchError",
|
|
8479
9648
|
message: String(error?.message ?? error)
|
|
8480
9649
|
});
|
|
@@ -8534,6 +9703,29 @@ function startCanvasIframe(opts) {
|
|
|
8534
9703
|
applyPreviewColorScheme(container.ownerDocument, msg.scheme);
|
|
8535
9704
|
return;
|
|
8536
9705
|
}
|
|
9706
|
+
if (msg.kind === "setPopoverOpen") {
|
|
9707
|
+
if (currentMode === "preview") {
|
|
9708
|
+
return;
|
|
9709
|
+
}
|
|
9710
|
+
popoverOpen = msg.path === null ? null : serializeJxPath(msg.path);
|
|
9711
|
+
applyCanvasPopoverOpen(container, popoverOpen);
|
|
9712
|
+
applyCanvasDialogOpen(container, dialogOpen);
|
|
9713
|
+
postContentHeight();
|
|
9714
|
+
return;
|
|
9715
|
+
}
|
|
9716
|
+
if (msg.kind === "setDialogOpen") {
|
|
9717
|
+
if (currentMode === "preview") {
|
|
9718
|
+
return;
|
|
9719
|
+
}
|
|
9720
|
+
dialogOpen = msg.path === null ? null : serializeJxPath(msg.path);
|
|
9721
|
+
applyCanvasDialogOpen(container, dialogOpen);
|
|
9722
|
+
postContentHeight();
|
|
9723
|
+
return;
|
|
9724
|
+
}
|
|
9725
|
+
if (msg.kind === "redefineElement") {
|
|
9726
|
+
redefineElement(msg.doc, msg.base);
|
|
9727
|
+
return;
|
|
9728
|
+
}
|
|
8537
9729
|
if (msg.kind === "setLocale") {
|
|
8538
9730
|
const root = container.ownerDocument.documentElement;
|
|
8539
9731
|
if (msg.locale === null) {
|
|
@@ -8566,6 +9758,7 @@ function startCanvasIframe(opts) {
|
|
|
8566
9758
|
stopDataScopeWatch?.();
|
|
8567
9759
|
stopDataScopeWatch = null;
|
|
8568
9760
|
handle?.dispose();
|
|
9761
|
+
resetDocumentStyles(container.ownerDocument);
|
|
8569
9762
|
handle = await renderResolvedDocument({
|
|
8570
9763
|
assets: msg.assets ?? null,
|
|
8571
9764
|
container,
|
|
@@ -8578,11 +9771,18 @@ function startCanvasIframe(opts) {
|
|
|
8578
9771
|
pageContentOffset: mapperCtx.pageContentOffset,
|
|
8579
9772
|
pageContentPrefix: mapperCtx.pageContentPrefix
|
|
8580
9773
|
},
|
|
9774
|
+
diffMarks: msg.diffMarks ?? null,
|
|
8581
9775
|
mode: msg.mode,
|
|
9776
|
+
popoverOpen: msg.popoverOpen ? serializeJxPath(msg.popoverOpen) : null,
|
|
9777
|
+
dialogOpen: msg.dialogOpen ? serializeJxPath(msg.dialogOpen) : null,
|
|
8582
9778
|
siteStyle: msg.siteStyle,
|
|
8583
9779
|
...msg.allowAutoRequests ? { allowAutoRequests: true } : {}
|
|
8584
9780
|
});
|
|
8585
9781
|
if (gen === latestGen) {
|
|
9782
|
+
popoverOpen = msg.popoverOpen ? serializeJxPath(msg.popoverOpen) : null;
|
|
9783
|
+
dialogOpen = msg.dialogOpen ? serializeJxPath(msg.dialogOpen) : null;
|
|
9784
|
+
applyCanvasPopoverOpen(container, popoverOpen);
|
|
9785
|
+
applyCanvasDialogOpen(container, dialogOpen);
|
|
8586
9786
|
shadowDoc = rawDoc;
|
|
8587
9787
|
renderCtx = handle.ctx;
|
|
8588
9788
|
renderedGen = gen;
|
|
@@ -8665,5 +9865,5 @@ export {
|
|
|
8665
9865
|
startCanvasIframe
|
|
8666
9866
|
};
|
|
8667
9867
|
|
|
8668
|
-
//# debugId=
|
|
9868
|
+
//# debugId=2FA5492A7FC7235764756E2164756E21
|
|
8669
9869
|
//# sourceMappingURL=iframe-entry.js.map
|