@jxsuite/studio 2.0.0 → 2.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.
Files changed (419) hide show
  1. package/canvas.html +21 -0
  2. package/dist/chunks/Overlay.dev-qfjzkms8.js +23 -0
  3. package/dist/chunks/{Overlay.dev-cszx7yn5.js.map → Overlay.dev-qfjzkms8.js.map} +1 -1
  4. package/dist/chunks/{adapter-z8fkmbmv.js → adapter-qfnesn5v.js} +2 -2
  5. package/dist/chunks/{cf-settings-mmyv436d.js → cf-settings-73sh5z4p.js} +3 -3
  6. package/dist/chunks/{components-0hzentwq.js → components-2bpqp4mq.js} +5 -7
  7. package/dist/chunks/{components-0hzentwq.js.map → components-2bpqp4mq.js.map} +1 -1
  8. package/dist/chunks/content-source-34gnkbnn.js +38 -0
  9. package/dist/chunks/content-source-34gnkbnn.js.map +9 -0
  10. package/dist/chunks/convert-to-repeater-t8kxre5s.js +258 -0
  11. package/dist/chunks/convert-to-repeater-t8kxre5s.js.map +10 -0
  12. package/dist/chunks/extension-sections-6mqydz35.js +301 -0
  13. package/dist/chunks/extension-sections-6mqydz35.js.map +11 -0
  14. package/dist/chunks/files-8kn321h1.js +70 -0
  15. package/dist/chunks/files-8kn321h1.js.map +9 -0
  16. package/dist/chunks/{format-host-2c188n41.js → format-host-mkwsmt8d.js} +3 -3
  17. package/dist/chunks/git-panel-tjbr191d.js +51 -0
  18. package/dist/chunks/git-panel-tjbr191d.js.map +9 -0
  19. package/dist/chunks/{index-baeg2x3y.js → index-7pxchcce.js} +4 -3
  20. package/dist/chunks/{index-baeg2x3y.js.map → index-7pxchcce.js.map} +3 -3
  21. package/dist/chunks/{jx-validate-qx8degj7.js → jx-validate-v6qgknrs.js} +3 -3
  22. package/dist/chunks/layers-panel-87pb25km.js +58 -0
  23. package/dist/chunks/layers-panel-87pb25km.js.map +9 -0
  24. package/dist/chunks/{monaco-setup-zjdp9zdw.js → monaco-setup-e0yh25j4.js} +4 -75
  25. package/dist/chunks/{monaco-setup-zjdp9zdw.js.map → monaco-setup-e0yh25j4.js.map} +3 -4
  26. package/dist/chunks/publish-panel-m0fcgdrt.js +21 -0
  27. package/dist/chunks/publish-panel-m0fcgdrt.js.map +9 -0
  28. package/dist/chunks/quick-search-rhs6cbsb.js +53 -0
  29. package/dist/chunks/quick-search-rhs6cbsb.js.map +9 -0
  30. package/dist/chunks/right-panel-zpdxd98t.js +37 -0
  31. package/dist/chunks/right-panel-zpdxd98t.js.map +9 -0
  32. package/dist/chunks/section-registry-zmckaxf4.js +30 -0
  33. package/dist/chunks/section-registry-zmckaxf4.js.map +9 -0
  34. package/dist/chunks/sp-overlay.dev-9ran0sfq.js +18 -0
  35. package/dist/chunks/sp-overlay.dev-9ran0sfq.js.map +9 -0
  36. package/dist/chunks/sp-popover.dev-rebmdncr.js +9 -0
  37. package/dist/chunks/sp-popover.dev-rebmdncr.js.map +9 -0
  38. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js +15 -0
  39. package/dist/chunks/sp-progress-circle.dev-5vkppfkt.js.map +9 -0
  40. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js +15 -0
  41. package/dist/chunks/sp-tooltip.dev-ykqrg8h5.js.map +9 -0
  42. package/dist/chunks/{sp-tray.dev-pb2fsd65.js → sp-tray.dev-ey59vfh7.js} +10 -8
  43. package/dist/chunks/{sp-tray.dev-pb2fsd65.js.map → sp-tray.dev-ey59vfh7.js.map} +2 -2
  44. package/dist/chunks/{studio-9qr6fq7p.js → studio-0rqqhrdy.js} +10 -378
  45. package/dist/chunks/{studio-9qr6fq7p.js.map → studio-0rqqhrdy.js.map} +4 -14
  46. package/dist/chunks/{studio-5x6tqqec.js → studio-2sj1jj3v.js} +10 -8
  47. package/dist/chunks/{studio-5x6tqqec.js.map → studio-2sj1jj3v.js.map} +2 -2
  48. package/dist/chunks/{studio-h3fw0wn8.js → studio-3fk1ac9z.js} +6 -4
  49. package/dist/chunks/{studio-h3fw0wn8.js.map → studio-3fk1ac9z.js.map} +2 -2
  50. package/dist/chunks/studio-41exgzhq.js +6690 -0
  51. package/dist/chunks/studio-41exgzhq.js.map +38 -0
  52. package/dist/chunks/{studio-7v2bpweq.js → studio-4mqb9a0j.js} +6 -4
  53. package/dist/chunks/{studio-7v2bpweq.js.map → studio-4mqb9a0j.js.map} +2 -2
  54. package/dist/chunks/studio-50k77cca.js +1787 -0
  55. package/dist/chunks/studio-50k77cca.js.map +18 -0
  56. package/dist/chunks/{studio-56v3zwk6.js → studio-6a0h7sne.js} +10 -8
  57. package/dist/chunks/{studio-56v3zwk6.js.map → studio-6a0h7sne.js.map} +2 -2
  58. package/dist/chunks/studio-6f0am8f2.js +53 -0
  59. package/dist/chunks/studio-6f0am8f2.js.map +10 -0
  60. package/dist/chunks/studio-6nmjc5qk.js +7002 -0
  61. package/dist/chunks/studio-6nmjc5qk.js.map +32 -0
  62. package/dist/chunks/studio-7afd21nw.js +67 -0
  63. package/dist/chunks/studio-7afd21nw.js.map +10 -0
  64. package/dist/chunks/{studio-xze4zrs1.js → studio-7bmdvzne.js} +2 -2
  65. package/dist/chunks/studio-7bmdvzne.js.map +10 -0
  66. package/dist/chunks/studio-8jpzqk5s.js +128 -0
  67. package/dist/chunks/studio-8jpzqk5s.js.map +10 -0
  68. package/dist/chunks/studio-94m77tgk.js +1482 -0
  69. package/dist/chunks/studio-94m77tgk.js.map +13 -0
  70. package/dist/chunks/studio-9je6w5sq.js +1000 -0
  71. package/dist/chunks/studio-9je6w5sq.js.map +16 -0
  72. package/dist/chunks/{studio-w7c6kvk7.js → studio-a7pzveq1.js} +2 -2
  73. package/dist/chunks/{studio-97qcgvdn.js → studio-adn0z1k3.js} +14 -8
  74. package/dist/chunks/{studio-97qcgvdn.js.map → studio-adn0z1k3.js.map} +3 -3
  75. package/dist/chunks/{studio-kr88ryr7.js → studio-bsxxx3x2.js} +17 -15
  76. package/dist/chunks/{studio-kr88ryr7.js.map → studio-bsxxx3x2.js.map} +7 -6
  77. package/dist/chunks/studio-bw5dz6km.js +608 -0
  78. package/dist/chunks/studio-bw5dz6km.js.map +21 -0
  79. package/dist/chunks/studio-c6s5getc.js +4232 -0
  80. package/dist/chunks/studio-c6s5getc.js.map +39 -0
  81. package/dist/chunks/studio-cjm7fdjf.js +451 -0
  82. package/dist/chunks/studio-cjm7fdjf.js.map +14 -0
  83. package/dist/chunks/{studio-cx91mnh8.js → studio-ckwz4d3x.js} +53 -53
  84. package/dist/chunks/{studio-cx91mnh8.js.map → studio-ckwz4d3x.js.map} +5 -5
  85. package/dist/chunks/studio-dg7zyt5x.js +28 -0
  86. package/dist/chunks/studio-dg7zyt5x.js.map +10 -0
  87. package/dist/chunks/studio-dzcyvvvz.js +166 -0
  88. package/dist/chunks/studio-dzcyvvvz.js.map +10 -0
  89. package/dist/chunks/{studio-7kqe41sa.js → studio-evkr5d3b.js} +15 -7
  90. package/dist/chunks/{studio-7kqe41sa.js.map → studio-evkr5d3b.js.map} +5 -4
  91. package/dist/chunks/studio-f12h6177.js +411 -0
  92. package/dist/chunks/studio-f12h6177.js.map +13 -0
  93. package/dist/chunks/studio-hbp1s8m9.js +1817 -0
  94. package/dist/chunks/studio-hbp1s8m9.js.map +14 -0
  95. package/dist/chunks/studio-k2sxjph5.js +15295 -0
  96. package/dist/chunks/studio-k2sxjph5.js.map +235 -0
  97. package/dist/chunks/studio-myje51t3.js +385 -0
  98. package/dist/chunks/studio-myje51t3.js.map +12 -0
  99. package/dist/chunks/studio-na6rwzhw.js +353 -0
  100. package/dist/chunks/studio-na6rwzhw.js.map +11 -0
  101. package/dist/chunks/{studio-4k0m4fmp.js → studio-p471gg5n.js} +126 -3
  102. package/dist/chunks/studio-p471gg5n.js.map +14 -0
  103. package/dist/chunks/{studio-9bjwf0d4.js → studio-rgwcpast.js} +5 -46
  104. package/dist/chunks/{studio-9bjwf0d4.js.map → studio-rgwcpast.js.map} +4 -5
  105. package/dist/chunks/{studio-hhj92gcr.js → studio-s519zc99.js} +3 -3
  106. package/dist/chunks/studio-sas7mt3k.js +75 -0
  107. package/dist/chunks/studio-sas7mt3k.js.map +10 -0
  108. package/dist/chunks/studio-t5wqwzdh.js +74 -0
  109. package/dist/chunks/studio-t5wqwzdh.js.map +10 -0
  110. package/dist/chunks/{studio-9qpspwfn.js → studio-temv5bw4.js} +5 -5
  111. package/dist/chunks/{studio-9qpspwfn.js.map → studio-temv5bw4.js.map} +1 -1
  112. package/dist/chunks/{studio-qkvt37c0.js → studio-tr20m8g8.js} +669 -18
  113. package/dist/chunks/studio-tr20m8g8.js.map +9 -0
  114. package/dist/chunks/{studio-ygzav7z5.js → studio-v96qfnww.js} +5514 -4291
  115. package/dist/chunks/studio-v96qfnww.js.map +54 -0
  116. package/dist/chunks/studio-vcetc91k.js +659 -0
  117. package/dist/chunks/studio-vcetc91k.js.map +10 -0
  118. package/dist/chunks/{studio-n9zmpxjg.js → studio-vmymjefp.js} +2972 -4937
  119. package/dist/chunks/studio-vmymjefp.js.map +98 -0
  120. package/dist/chunks/{studio-bghqfmea.js → studio-wwseqyw0.js} +2 -2
  121. package/dist/chunks/studio-x9hmy5kr.js +390 -0
  122. package/dist/chunks/studio-x9hmy5kr.js.map +10 -0
  123. package/dist/chunks/studio-xa0ce0n7.js +335 -0
  124. package/dist/chunks/studio-xa0ce0n7.js.map +10 -0
  125. package/dist/chunks/studio-xm3dbxvn.js +378 -0
  126. package/dist/chunks/studio-xm3dbxvn.js.map +19 -0
  127. package/dist/chunks/{studio-nqw433kv.js → studio-xmvbhg31.js} +2 -2
  128. package/dist/chunks/studio-zv37yrfa.js +1054 -0
  129. package/dist/chunks/studio-zv37yrfa.js.map +13 -0
  130. package/dist/chunks/{ws-client-q7hkz3j9.js → ws-client-654ts66j.js} +6 -4
  131. package/dist/chunks/ws-client-654ts66j.js.map +11 -0
  132. package/dist/iframe-entry.js +668 -230
  133. package/dist/studio.js +23711 -35185
  134. package/index.html +35 -4685
  135. package/package.json +17 -15
  136. package/src/about/about-modal.ts +42 -11
  137. package/src/browse/library-commands.ts +240 -0
  138. package/src/browse/library-layouts.ts +369 -0
  139. package/src/browse/library-model.ts +396 -0
  140. package/src/browse/library-pane.ts +1049 -0
  141. package/src/browse/library-preview.ts +252 -0
  142. package/src/browse/library-source.ts +150 -0
  143. package/src/canvas/canvas-helpers.ts +33 -9
  144. package/src/canvas/canvas-live-render.ts +45 -29
  145. package/src/canvas/canvas-patcher.ts +151 -31
  146. package/src/canvas/canvas-perf.ts +46 -7
  147. package/src/canvas/canvas-render.ts +1092 -220
  148. package/src/canvas/canvas-surface.ts +240 -0
  149. package/src/canvas/canvas-utils.ts +1166 -124
  150. package/src/canvas/iframe-drop.ts +2 -1
  151. package/src/canvas/iframe-entry.ts +241 -4
  152. package/src/canvas/iframe-host.ts +1226 -143
  153. package/src/canvas/iframe-inline-edit.ts +31 -0
  154. package/src/canvas/iframe-interaction.ts +76 -16
  155. package/src/canvas/iframe-keys.ts +107 -45
  156. package/src/canvas/iframe-overlay.ts +38 -1
  157. package/src/canvas/iframe-protocol.ts +137 -2
  158. package/src/canvas/iframe-render.ts +70 -2
  159. package/src/canvas/iframe-slash.ts +6 -0
  160. package/src/canvas/path-mapping.ts +56 -6
  161. package/src/canvas/surface-registry.ts +292 -0
  162. package/src/collab/collab-commands.ts +244 -0
  163. package/src/collab/collab-session.ts +198 -32
  164. package/src/collab/collab-state.ts +28 -2
  165. package/src/collab/presence-chips.ts +100 -9
  166. package/src/commands/active-registry.ts +42 -0
  167. package/src/commands/app-commands.ts +176 -0
  168. package/src/commands/budget.ts +158 -0
  169. package/src/commands/command-args.ts +253 -0
  170. package/src/commands/context.ts +387 -0
  171. package/src/commands/defaults.ts +580 -0
  172. package/src/commands/keymap.ts +571 -0
  173. package/src/commands/levels.ts +345 -0
  174. package/src/commands/live-context.ts +193 -0
  175. package/src/commands/reference.ts +227 -0
  176. package/src/commands/registry.ts +293 -0
  177. package/src/component-props.ts +3 -2
  178. package/src/content/draft-state.ts +106 -0
  179. package/src/content/entry-commands.ts +282 -0
  180. package/src/content/entry-editor.ts +327 -0
  181. package/src/content/entry-fields.ts +116 -0
  182. package/src/content/entry-model.ts +175 -0
  183. package/src/editor/canvas-context-menu.ts +17 -11
  184. package/src/editor/canvas-slash-bridge.ts +11 -4
  185. package/src/editor/context-menu.ts +804 -204
  186. package/src/editor/convert-to-component.ts +31 -10
  187. package/src/editor/convert-to-repeater.ts +3 -2
  188. package/src/editor/inline-edit-apply.ts +5 -5
  189. package/src/editor/inline-edit.ts +86 -50
  190. package/src/editor/insert-zone-action.ts +1 -1
  191. package/src/editor/shortcuts.ts +1043 -329
  192. package/src/editor/slash-menu.ts +1 -0
  193. package/src/files/elements.ts +166 -0
  194. package/src/files/file-ops.ts +178 -31
  195. package/src/files/files.ts +898 -268
  196. package/src/files/fs-events.ts +21 -0
  197. package/src/files/media-meta.ts +203 -0
  198. package/src/files/media-paths.ts +141 -0
  199. package/src/files/media-upload.ts +7 -3
  200. package/src/files/media-usage.ts +189 -0
  201. package/src/github/github-auth.ts +235 -33
  202. package/src/github/github-publish.ts +80 -21
  203. package/src/grid/grid-controller.ts +152 -12
  204. package/src/grid/grid-layout.ts +225 -20
  205. package/src/grid/grid-open.ts +120 -0
  206. package/src/grid/grid-panel.ts +554 -39
  207. package/src/grid/grid-source.ts +27 -1
  208. package/src/grid/redirects-grid.ts +599 -0
  209. package/src/grid/redirects.ts +398 -0
  210. package/src/grid/sources/content-source.ts +108 -2
  211. package/src/i18n/i18n-commands.ts +322 -0
  212. package/src/new-project/add-repo-modal.ts +8 -10
  213. package/src/new-project/import-tab.ts +34 -9
  214. package/src/new-project/location-fields.ts +9 -1
  215. package/src/new-project/new-project-modal.ts +270 -262
  216. package/src/packages/jxsuite-update.ts +97 -48
  217. package/src/packages/pull-package-sync.ts +18 -9
  218. package/src/page-params.ts +2 -1
  219. package/src/panels/activity-bar.ts +152 -91
  220. package/src/panels/activity-panel.ts +481 -0
  221. package/src/panels/ai-chat/chat-markdown.ts +8 -3
  222. package/src/panels/ai-chat/chat-view.ts +245 -18
  223. package/src/panels/ai-chat/composer.ts +31 -5
  224. package/src/panels/ai-chat/sessions-view.ts +17 -10
  225. package/src/panels/ai-panel.ts +279 -120
  226. package/src/panels/block-action-bar.ts +1115 -224
  227. package/src/panels/bottom-dock.ts +337 -0
  228. package/src/panels/canvas-dnd-bridge.ts +37 -8
  229. package/src/panels/chat-panel.ts +29 -12
  230. package/src/panels/data-explorer.ts +254 -112
  231. package/src/panels/data-grid.ts +10 -4
  232. package/src/panels/dnd.ts +28 -51
  233. package/src/panels/editors.ts +434 -107
  234. package/src/panels/elements-panel.ts +66 -2
  235. package/src/panels/empty-state.ts +112 -0
  236. package/src/panels/events-panel.ts +596 -82
  237. package/src/panels/formula-workspace.ts +408 -218
  238. package/src/panels/frontmatter-fields.ts +51 -10
  239. package/src/panels/frontmatter-panel.ts +357 -79
  240. package/src/panels/git-panel.ts +375 -164
  241. package/src/panels/head-panel.ts +791 -85
  242. package/src/panels/i18n-panel.ts +592 -0
  243. package/src/panels/imports-panel.ts +95 -85
  244. package/src/panels/jump-bar.ts +584 -0
  245. package/src/panels/layers-panel.ts +1106 -328
  246. package/src/panels/left-panel.ts +109 -204
  247. package/src/panels/navigator-panels.ts +131 -0
  248. package/src/panels/overlays.ts +7 -2
  249. package/src/panels/pane-context.ts +1477 -0
  250. package/src/panels/pane-grid.ts +406 -0
  251. package/src/panels/panel-registry.ts +340 -0
  252. package/src/panels/panel-scheduler.ts +75 -0
  253. package/src/panels/problems-panel.ts +234 -0
  254. package/src/panels/properties-panel.ts +946 -1139
  255. package/src/panels/provenance.ts +258 -0
  256. package/src/panels/quick-search.ts +791 -122
  257. package/src/panels/right-panel.ts +228 -102
  258. package/src/panels/seo-modal.ts +395 -0
  259. package/src/panels/settings-pane.ts +203 -0
  260. package/src/panels/signals-panel.ts +354 -137
  261. package/src/panels/statement-editor.ts +41 -25
  262. package/src/panels/statusbar.ts +342 -106
  263. package/src/panels/style-panel.ts +974 -463
  264. package/src/panels/style-utils.ts +3 -3
  265. package/src/panels/stylebook-doc.ts +4 -2
  266. package/src/panels/stylebook-layers-panel.ts +3 -2
  267. package/src/panels/stylebook-panel.ts +51 -26
  268. package/src/panels/tab-strip.ts +1058 -78
  269. package/src/panels/target-line.ts +274 -0
  270. package/src/panels/toolbar.ts +631 -484
  271. package/src/panels/welcome-screen.ts +301 -198
  272. package/src/platform-errors.ts +26 -3
  273. package/src/platform.ts +96 -2
  274. package/src/platforms/cloud.ts +71 -8
  275. package/src/platforms/devserver.ts +92 -29
  276. package/src/publish/deploy-checklist.ts +383 -0
  277. package/src/publish/pages-service.ts +10 -1
  278. package/src/publish/publish-commands.ts +218 -0
  279. package/src/publish/publish-panel.ts +110 -16
  280. package/src/recent-projects.ts +3 -2
  281. package/src/services/a11y-report.ts +505 -0
  282. package/src/services/ai-models.ts +75 -2
  283. package/src/services/ai-project-tools.ts +29 -10
  284. package/src/services/ai-system-prompt.ts +53 -14
  285. package/src/services/ai-tools.ts +39 -3
  286. package/src/services/ai-writes.ts +154 -0
  287. package/src/services/announce.ts +97 -0
  288. package/src/services/automation.ts +424 -175
  289. package/src/services/cem-export.ts +9 -4
  290. package/src/services/clock.ts +61 -0
  291. package/src/services/document-assistant.ts +36 -8
  292. package/src/services/idle.ts +179 -0
  293. package/src/services/import-client.ts +26 -0
  294. package/src/services/monaco-buffer.ts +627 -0
  295. package/src/services/monaco-lazy.ts +36 -0
  296. package/src/services/notify.ts +271 -0
  297. package/src/services/profile.ts +155 -0
  298. package/src/services/references.ts +0 -0
  299. package/src/services/token-lint.ts +3 -2
  300. package/src/services/tool-executor.ts +53 -7
  301. package/src/services/trusted-types.ts +123 -0
  302. package/src/settings/contexts-section.ts +427 -0
  303. package/src/settings/contributed-section.ts +149 -11
  304. package/src/settings/css-vars-editor.ts +306 -349
  305. package/src/settings/defs-editor.ts +93 -34
  306. package/src/settings/dependencies-editor.ts +7 -7
  307. package/src/settings/extension-sections.ts +37 -5
  308. package/src/settings/general-settings.ts +204 -121
  309. package/src/settings/locales-section.ts +347 -0
  310. package/src/settings/preferences-accounts.ts +140 -0
  311. package/src/settings/preferences-dialog.ts +620 -0
  312. package/src/settings/preferences-keymap.ts +270 -0
  313. package/src/settings/project-sections.ts +260 -0
  314. package/src/settings/section-registry.ts +169 -0
  315. package/src/settings/settings-document.ts +385 -0
  316. package/src/shell.ts +1549 -0
  317. package/src/site-context.ts +45 -20
  318. package/src/state.ts +14 -275
  319. package/src/store.ts +88 -43
  320. package/src/studio.ts +790 -346
  321. package/src/style/live-preview.ts +36 -0
  322. package/src/style/project-styles.ts +349 -0
  323. package/src/style/token-ref.ts +123 -0
  324. package/src/tabs/patch-ops.ts +16 -4
  325. package/src/tabs/project-config.ts +416 -0
  326. package/src/tabs/selection.ts +323 -0
  327. package/src/tabs/tab.ts +182 -47
  328. package/src/tabs/transact.ts +209 -28
  329. package/src/types.ts +68 -13
  330. package/src/ui/ai-credentials-form.ts +39 -35
  331. package/src/ui/ai-managed-connect.ts +113 -0
  332. package/src/ui/dynamic-slot.ts +224 -81
  333. package/src/ui/expression-editor.ts +71 -63
  334. package/src/ui/field-input.ts +4 -6
  335. package/src/ui/field-row.ts +215 -38
  336. package/src/ui/form-controls.ts +194 -7
  337. package/src/ui/layers.ts +492 -69
  338. package/src/ui/media-picker.ts +115 -25
  339. package/src/ui/panel-resize.ts +109 -91
  340. package/src/ui/progress-modal.ts +131 -50
  341. package/src/ui/regions.ts +462 -0
  342. package/src/ui/schema-form.ts +229 -45
  343. package/src/ui/spectrum.ts +24 -8
  344. package/src/ui/timing.ts +49 -0
  345. package/src/ui/value-selector.ts +20 -0
  346. package/src/ui/value-source.ts +348 -0
  347. package/src/ui/virtual-window.ts +400 -0
  348. package/src/utils/edit-display.ts +3 -2
  349. package/src/utils/inherited-style.ts +67 -37
  350. package/src/view.ts +64 -78
  351. package/src/workspace/pane-derive.ts +1258 -0
  352. package/src/workspace/session.ts +317 -0
  353. package/src/workspace/workspace.ts +1345 -23
  354. package/styles/canvas.css +653 -0
  355. package/styles/forced-colors.css +106 -0
  356. package/styles/inspector.css +1454 -0
  357. package/styles/overlays.css +2704 -0
  358. package/styles/panels.css +1701 -0
  359. package/styles/shell.css +1423 -0
  360. package/styles/tokens.css +151 -0
  361. package/dist/chunks/Overlay.dev-cszx7yn5.js +0 -22
  362. package/dist/chunks/extension-sections-qct0gt8f.js +0 -531
  363. package/dist/chunks/extension-sections-qct0gt8f.js.map +0 -12
  364. package/dist/chunks/files-02zn5y24.js +0 -50
  365. package/dist/chunks/files-02zn5y24.js.map +0 -9
  366. package/dist/chunks/git-panel-mbb0y0hz.js +0 -28
  367. package/dist/chunks/git-panel-mbb0y0hz.js.map +0 -9
  368. package/dist/chunks/layers-panel-9qekmqk1.js +0 -26
  369. package/dist/chunks/layers-panel-9qekmqk1.js.map +0 -9
  370. package/dist/chunks/settings-modal-gj0hrah4.js +0 -29
  371. package/dist/chunks/settings-modal-gj0hrah4.js.map +0 -9
  372. package/dist/chunks/sp-overlay.dev-earn5as8.js +0 -17
  373. package/dist/chunks/sp-overlay.dev-earn5as8.js.map +0 -9
  374. package/dist/chunks/sp-popover.dev-frxtfejn.js +0 -8
  375. package/dist/chunks/sp-popover.dev-frxtfejn.js.map +0 -9
  376. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js +0 -14
  377. package/dist/chunks/sp-progress-circle.dev-7tvw34h8.js.map +0 -9
  378. package/dist/chunks/sp-tooltip.dev-a9fywesm.js +0 -21
  379. package/dist/chunks/sp-tooltip.dev-a9fywesm.js.map +0 -10
  380. package/dist/chunks/studio-4k0m4fmp.js.map +0 -13
  381. package/dist/chunks/studio-568nx4t5.js +0 -469
  382. package/dist/chunks/studio-568nx4t5.js.map +0 -14
  383. package/dist/chunks/studio-9smfzqhc.js +0 -19
  384. package/dist/chunks/studio-9smfzqhc.js.map +0 -10
  385. package/dist/chunks/studio-asvf0j9e.js +0 -429
  386. package/dist/chunks/studio-asvf0j9e.js.map +0 -13
  387. package/dist/chunks/studio-d77qm3pk.js +0 -3427
  388. package/dist/chunks/studio-d77qm3pk.js.map +0 -26
  389. package/dist/chunks/studio-j6gqyjf4.js +0 -1854
  390. package/dist/chunks/studio-j6gqyjf4.js.map +0 -18
  391. package/dist/chunks/studio-n9zmpxjg.js.map +0 -115
  392. package/dist/chunks/studio-qkvt37c0.js.map +0 -9
  393. package/dist/chunks/studio-rq0vxb19.js +0 -3744
  394. package/dist/chunks/studio-rq0vxb19.js.map +0 -22
  395. package/dist/chunks/studio-wd6ewdvd.js +0 -853
  396. package/dist/chunks/studio-wd6ewdvd.js.map +0 -12
  397. package/dist/chunks/studio-xq0t7n5t.js +0 -140
  398. package/dist/chunks/studio-xq0t7n5t.js.map +0 -10
  399. package/dist/chunks/studio-xze4zrs1.js.map +0 -10
  400. package/dist/chunks/studio-ygzav7z5.js.map +0 -46
  401. package/dist/chunks/studio-zmy7241e.js +0 -399
  402. package/dist/chunks/studio-zmy7241e.js.map +0 -12
  403. package/dist/chunks/ws-client-q7hkz3j9.js.map +0 -11
  404. package/src/browse/browse-modal.ts +0 -69
  405. package/src/browse/browse.ts +0 -904
  406. package/src/canvas/canvas-diff.ts +0 -216
  407. package/src/canvas/nested-site-style.ts +0 -58
  408. package/src/new-project/design-fields.ts +0 -264
  409. package/src/new-project/templates.ts +0 -61
  410. package/src/panels/tab-bar.ts +0 -548
  411. package/src/settings/settings-modal.ts +0 -203
  412. /package/dist/chunks/{adapter-z8fkmbmv.js.map → adapter-qfnesn5v.js.map} +0 -0
  413. /package/dist/chunks/{cf-settings-mmyv436d.js.map → cf-settings-73sh5z4p.js.map} +0 -0
  414. /package/dist/chunks/{format-host-2c188n41.js.map → format-host-mkwsmt8d.js.map} +0 -0
  415. /package/dist/chunks/{jx-validate-qx8degj7.js.map → jx-validate-v6qgknrs.js.map} +0 -0
  416. /package/dist/chunks/{studio-w7c6kvk7.js.map → studio-a7pzveq1.js.map} +0 -0
  417. /package/dist/chunks/{studio-hhj92gcr.js.map → studio-s519zc99.js.map} +0 -0
  418. /package/dist/chunks/{studio-bghqfmea.js.map → studio-wwseqyw0.js.map} +0 -0
  419. /package/dist/chunks/{studio-nqw433kv.js.map → studio-xmvbhg31.js.map} +0 -0
@@ -17,6 +17,7 @@
17
17
  */
18
18
 
19
19
  import { parseJxPath } from "./path-mapping";
20
+ import { displayTagName } from "@jxsuite/schema/guards";
20
21
  import { rectOf, elementAtPoint } from "../utils/geometry";
21
22
  import { getNodeAtPath, isAncestor, pathsEqual } from "../state";
22
23
  import type { DragSrcKind, DropPreview } from "./iframe-protocol";
@@ -120,7 +121,7 @@ export function computeDropInstruction(
120
121
  }
121
122
 
122
123
  const node = getNodeAtPath(shadowDoc, targetPath) as JxMutableNode | undefined;
123
- const tag = (node?.tagName || "div").toLowerCase();
124
+ const tag = (displayTagName(node?.tagName) || "div").toLowerCase();
124
125
  const hasElementChildren =
125
126
  Array.isArray(node?.children) &&
126
127
  node.children.some((c: unknown) => c != null && typeof c === "object");
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  import { postMessageChannel } from "./iframe-channel";
9
+ import { displayTagName } from "@jxsuite/schema/guards";
9
10
  import {
10
11
  applyPreviewColorScheme,
11
12
  applySiteStyle,
@@ -23,7 +24,8 @@ import {
23
24
  } from "./iframe-drop";
24
25
  import { startIframeInlineEdit } from "./iframe-inline-edit";
25
26
  import { startIframeSlashBridge } from "./iframe-slash";
26
- import { startKeyForwarding } from "./iframe-keys";
27
+ import { NO_TABLE, startKeyForwarding } from "./iframe-keys";
28
+ import type { ForwardTable } from "./iframe-keys";
27
29
  import { applyIframePatch } from "./iframe-patch";
28
30
  import { disposeAllSubtrees } from "./iframe-subtree";
29
31
  import { evaluateLiveExprs } from "./iframe-eval";
@@ -49,6 +51,7 @@ import type {
49
51
  DragSrcKind,
50
52
  FileDropHit,
51
53
  IframeToParent,
54
+ LayoutHit,
52
55
  ParentToIframe,
53
56
  } from "./iframe-protocol";
54
57
  import type { JxDocument, JxMutableNode, JxStyle } from "@jxsuite/schema/types";
@@ -106,7 +109,35 @@ export function fileDropHitFor(
106
109
  return {
107
110
  path,
108
111
  rect: rectFor(targetEl),
109
- tagName: (node?.tagName ?? targetEl.tagName).toLowerCase(),
112
+ tagName: (displayTagName(node?.tagName) || targetEl.tagName).toLowerCase(),
113
+ };
114
+ }
115
+
116
+ /**
117
+ * Resolve a click to the layout-chrome node it landed on, or null when it did not land on one.
118
+ *
119
+ * Page content wins outright: a `[data-jx-path]` ancestor means the runtime rendered this node from
120
+ * the page document, and {@link file://./iframe-interaction.ts} already reports it as a normal
121
+ * `hit`. Only when no page node claims the click does the nearest `[data-jx-layout-region]` — the
122
+ * dimmed, frozen chrome the layout contributed — answer for it.
123
+ */
124
+ export function layoutHitFor(target: EventTarget | null): LayoutHit | null {
125
+ if (!(target instanceof Element)) {
126
+ return null;
127
+ }
128
+ if (target.closest("[data-jx-path]")) {
129
+ return null;
130
+ }
131
+ const el = target.closest("[data-jx-layout-region]");
132
+ if (!(el instanceof HTMLElement)) {
133
+ return null;
134
+ }
135
+ return {
136
+ className: typeof el.className === "string" ? el.className : "",
137
+ layoutFile: el.dataset.jxLayoutFile ?? "",
138
+ layoutPath: parseJxPath(el.dataset.jxLayoutPath ?? "[]"),
139
+ rect: rectFor(el),
140
+ tagName: el.tagName.toLowerCase(),
110
141
  };
111
142
  }
112
143
 
@@ -147,6 +178,27 @@ export function patchDisturbsActiveEdit(forwardOps: JxDocOp[]): boolean {
147
178
  return false;
148
179
  }
149
180
 
181
+ /** Consecutive quiet animation frames before the frame declares itself settled (§13.4). */
182
+ export const IDLE_QUIET_FRAMES = 2;
183
+
184
+ /**
185
+ * How long the idle watcher keeps sampling before it stops.
186
+ *
187
+ * A page with an endless animation never reaches two quiet frames, and a rAF loop that runs for the
188
+ * life of the tab to prove it is not free. Giving up is safe because the last posted sample already
189
+ * names the animation — the parent stays honestly "not idle" rather than being told a comfortable
190
+ * lie.
191
+ */
192
+ export const IDLE_WATCH_MAX_MS = 5000;
193
+
194
+ /**
195
+ * How long after a failed image load a retry may still be in flight.
196
+ *
197
+ * `installCanvasImageRetry` re-fires at 150/300/450 ms; each further failure re-arms the window, so
198
+ * a per-error grace comfortably covers the whole chain without encoding its schedule twice.
199
+ */
200
+ export const IMAGE_RETRY_WINDOW_MS = 500;
201
+
150
202
  /**
151
203
  * Drive a channel: render each `render` message into `container`, dropping stale generations, and
152
204
  * acknowledge with `renderComplete`/`renderError`. Exposed (rather than inlined in {@link boot}) so
@@ -170,6 +222,11 @@ export function startCanvasIframe(opts: {
170
222
  // The mode of the LIVE render — gates the interactive surfaces (inline editing, insert zones,
171
223
  // Grab-drags) that only design/edit modes own. Adopted alongside shadowDoc.
172
224
  let currentMode: CanvasMode = "design";
225
+ /* The host's chord table. Empty until the first `keymap` message, which the host posts on
226
+ `ready` — before any render, so there is nothing to type into during the gap. An empty table
227
+ forwards nothing, which is the honest cold-start answer: the frame does not guess at what the
228
+ parent might bind, and it never `preventDefault`s a key it cannot name. */
229
+ let forwardTable: ForwardTable = NO_TABLE;
173
230
  // The current render's retained context (scope/mapping), used to render subtrees for structural
174
231
  // Patches. Set together with `shadowDoc`, so it's non-null whenever a patch is applied.
175
232
  let renderCtx: IframeRenderCtx | null = null;
@@ -280,9 +337,33 @@ export function startCanvasIframe(opts: {
280
337
  getMode: () => currentMode,
281
338
  getShadowDoc: () => shadowDoc,
282
339
  });
340
+ // Report clicks that land on LAYOUT chrome. The interaction wiring above only knows about
341
+ // `[data-jx-path]` nodes, and layout chrome has none — so this is the listener that makes "My
342
+ // Site" in the header answer a click at all. It runs in CAPTURE alongside the interaction click
343
+ // Handler; the two are disjoint by construction (`layoutHitFor` refuses anything a page node
344
+ // Claims), so exactly one of them posts per click.
345
+ const onLayoutClick = (e: Event) => {
346
+ if (currentMode !== "design" && currentMode !== "edit") {
347
+ return;
348
+ }
349
+ const hit = layoutHitFor(e.target);
350
+ if (hit) {
351
+ channel.post({ hit, kind: "layoutHit" });
352
+ }
353
+ };
354
+ container.ownerDocument.addEventListener("click", onLayoutClick, true);
283
355
  // Forward global-shortcut keystrokes to the parent — its shortcut handler is bound to the editor
284
356
  // Document, so without this they'd be swallowed whenever focus is inside the canvas iframe.
285
- const stopKeyForwarding = startKeyForwarding(channel, container.ownerDocument);
357
+ // `isEditing` is the real "is a caret session live" predicate: the canvas root is PERMANENTLY
358
+ // Contenteditable, so "the target is editable" is true even with no session, and the clipboard
359
+ // Chords have to be split on the session — not on editability — to reach the right owner.
360
+ const stopKeyForwarding = startKeyForwarding(
361
+ channel,
362
+ container.ownerDocument,
363
+ isEditing,
364
+ () => forwardTable,
365
+ () => currentMode,
366
+ );
286
367
  // Run inline editing (contenteditable) here, posting committed/split/insert results to the parent.
287
368
  // The shadow-doc accessor gates prop-bound sessions on the RAW instance prop value (template/$ref
288
369
  // Valued props render display sugar and must not be plain-text edited).
@@ -315,17 +396,132 @@ export function startCanvasIframe(opts: {
315
396
  const root = container.firstElementChild;
316
397
  const fragment = root instanceof HTMLElement && root.dataset.jxDefinitionRoot !== undefined;
317
398
  channel.post({ fragment, height: measured, kind: "contentHeight" });
399
+ // The content box moved, so fonts/animations/images may not be where they were.
400
+ armIdleWatch();
318
401
  }
319
402
  }
320
403
  const ResizeObs = win?.ResizeObserver;
321
404
  const heightObserver = ResizeObs ? new ResizeObs(() => postContentHeight()) : null;
405
+
406
+ // ─── Cross-realm quiescence ─────────────────────────────────────────────────
407
+ // The frame answers "have I settled?" instead of being polled (§13.4 condition 5). Nothing in the
408
+ // Parent realm can look inside a cross-origin frame, so the alternative was `wait: {ms}` — and 115
409
+ // Of those were 115 places a slow subsystem got answered with +500 ms and the wrong picture was
410
+ // Accepted. Sampling lives HERE, next to the render that changes the answer.
411
+ const frameDoc = container.ownerDocument;
412
+ let idleFrame = 0;
413
+ let quietFrames = 0;
414
+ let idleDeadline = 0;
415
+ let lastIdleKey = "";
416
+ /** Images whose load failed, and the moment `installCanvasImageRetry` can no longer be waiting. */
417
+ const retryingImages = new Map<HTMLImageElement, number>();
418
+
419
+ /**
420
+ * Images with a retry still outstanding.
421
+ *
422
+ * `installCanvasImageRetry` re-fires at 150/300/450 ms and bounds itself at three attempts, so an
423
+ * error puts the image back in flight for at most that long; each further error extends the
424
+ * window. Only the app knows this is pending — a `<img>` mid-retry looks exactly like one that
425
+ * settled broken.
426
+ */
427
+ function pendingImageRetries(): number {
428
+ const now = Date.now();
429
+ for (const [img, deadline] of retryingImages) {
430
+ if (deadline <= now) {
431
+ retryingImages.delete(img);
432
+ }
433
+ }
434
+ return retryingImages.size;
435
+ }
436
+
437
+ function sampleIdle(): Extract<IframeToParent, { kind: "idle" }> {
438
+ const running =
439
+ typeof frameDoc.getAnimations === "function"
440
+ ? frameDoc.getAnimations().filter((a) => a.playState === "running").length
441
+ : 0;
442
+ return {
443
+ animations: running,
444
+ fonts: frameDoc.fonts ? frameDoc.fonts.status === "loaded" : true,
445
+ gen: renderedGen,
446
+ images: pendingImageRetries(),
447
+ kind: "idle",
448
+ };
449
+ }
450
+
451
+ function idleTick(): void {
452
+ idleFrame = 0;
453
+ const sample = sampleIdle();
454
+ const key = `${sample.gen}|${sample.fonts}|${sample.animations}|${sample.images}`;
455
+ const changed = key !== lastIdleKey;
456
+ if (changed) {
457
+ lastIdleKey = key;
458
+ channel.post(sample);
459
+ }
460
+ const quiet = sample.fonts && sample.animations === 0 && sample.images === 0;
461
+ quietFrames = quiet ? (changed ? 1 : quietFrames + 1) : 0;
462
+ // Two consecutive quiet frames, then stop — the state is stable and any change re-arms us.
463
+ if (quietFrames >= IDLE_QUIET_FRAMES) {
464
+ return;
465
+ }
466
+ // A page with a genuinely endless animation never goes quiet. Give up rather than burn a rAF
467
+ // Loop forever: the last posted sample already NAMES the animation, which is the honest answer.
468
+ if (Date.now() >= idleDeadline) {
469
+ return;
470
+ }
471
+ idleFrame = win ? win.requestAnimationFrame(idleTick) : 0;
472
+ }
473
+
474
+ /** Something changed the frame's DOM or assets — re-sample until it is quiet again. */
475
+ function armIdleWatch(): void {
476
+ quietFrames = 0;
477
+ idleDeadline = Date.now() + IDLE_WATCH_MAX_MS;
478
+ if (!idleFrame && win) {
479
+ idleFrame = win.requestAnimationFrame(idleTick);
480
+ }
481
+ }
482
+
483
+ const onImageError = (event: Event): void => {
484
+ if (event.target instanceof HTMLImageElement) {
485
+ retryingImages.set(event.target, Date.now() + IMAGE_RETRY_WINDOW_MS);
486
+ armIdleWatch();
487
+ }
488
+ };
489
+ const onImageLoad = (event: Event): void => {
490
+ if (event.target instanceof HTMLImageElement && retryingImages.delete(event.target)) {
491
+ armIdleWatch();
492
+ }
493
+ };
494
+ // Capture: neither `error` nor `load` bubbles from an <img>.
495
+ container.addEventListener("error", onImageError, true);
496
+ container.addEventListener("load", onImageLoad, true);
497
+ armIdleWatch();
498
+ // Observed only once the quiescence state above exists: a reflow arms the watcher.
322
499
  heightObserver?.observe(container);
323
500
 
324
501
  // ─── Wheel forwarding (canvas zoom/pan) ─────────────────────────────────────
325
502
  // The iframe is sized to its content (never scrolls itself), so wheel events over it are meant for
326
503
  // The parent canvas: ctrl/cmd+wheel = zoom, plain = pan. A cross-origin OOPIF doesn't bubble wheel to
327
504
  // The parent, so forward the deltas + modifiers + cursor; the host redispatches to its wheel handler.
505
+ //
506
+ // PREVIEW is the exception, and it is not a small one. There the host keeps the iframe at the
507
+ // Preview stage's own height and the document scrolls FOR REAL, which is the whole point of the
508
+ // View — sticky headers, scroll-driven animation and IntersectionObserver reveals only fire when
509
+ // Something actually scrolls. Swallowing the wheel here (this handler used to preventDefault
510
+ // Unconditionally) made the one view whose job is fidelity the one view you could not scroll.
328
511
  const onWheel = (e: WheelEvent) => {
512
+ if (currentMode === "preview") {
513
+ /* The document scrolls for real, so the plain wheel is ITS wheel and this handler takes no
514
+ part in it. Ctrl/⌘ — and the trackpad pinch that arrives as exactly this event — is not
515
+ that gesture: the browser reads it as page zoom, and the page it would scale is the whole
516
+ Studio window rather than the previewed document, which is neither what the author asked
517
+ for nor recoverable from inside the frame. The host cannot block it on this frame's behalf
518
+ (a cross-origin OOPIF's wheel never reaches it, and preview is the one mode that forwards
519
+ nothing), so the block belongs here. */
520
+ if (e.ctrlKey || e.metaKey) {
521
+ e.preventDefault();
522
+ }
523
+ return;
524
+ }
329
525
  e.preventDefault();
330
526
  channel.post({
331
527
  ctrlKey: e.ctrlKey,
@@ -473,7 +669,16 @@ export function startCanvasIframe(opts: {
473
669
  if (msg.kind === "patch") {
474
670
  const { gen } = msg;
475
671
  if (gen < renderedGen) {
476
- // A newer full render already supersedes this edit — drop it.
672
+ /* BEHIND, and that is now said out loud rather than dropped.
673
+ "A newer full render already supersedes this edit" is only true when the generation the
674
+ patch carries came from the stage THIS frame is mounted on. It did not while
675
+ `postPatchToHosts` took a single `gen` and fanned it to every host rendering the tab: one
676
+ document displayed in two panes meant whichever pane had rendered more recently held the
677
+ higher `renderedGen` and silently stopped applying patches, with a wrong picture on screen
678
+ and not one counter moving. The parent resolves the generation per host now, so reaching
679
+ here means the frame really is behind — an escalation, which repaints exactly this pane
680
+ and records the reason in `__jxCanvasPerf`. */
681
+ channel.post({ gen, kind: "patchError", message: "patch-behind-render" });
477
682
  return;
478
683
  }
479
684
  if (gen > renderedGen || !shadowDoc || !renderCtx) {
@@ -514,6 +719,7 @@ export function startCanvasIframe(opts: {
514
719
  restoreDocSelection(container, caret);
515
720
  }
516
721
  channel.post({ gen, kind: "patchComplete" });
722
+ armIdleWatch();
517
723
  } catch (error) {
518
724
  channel.post({
519
725
  gen,
@@ -589,11 +795,34 @@ export function startCanvasIframe(opts: {
589
795
  stopAutoScroll();
590
796
  return;
591
797
  }
798
+ if (msg.kind === "keymap") {
799
+ // Replaced wholesale, never merged: the host sends the whole live table, so a chord the
800
+ // Author unbound disappears here rather than lingering as a key the canvas still swallows.
801
+ forwardTable = { chords: msg.chords, mac: msg.mac };
802
+ return;
803
+ }
592
804
  if (msg.kind === "setColorScheme") {
593
805
  // Document-level attribute flip — deliberately patch-free (no render, no gen).
594
806
  applyPreviewColorScheme(container.ownerDocument, msg.scheme);
595
807
  return;
596
808
  }
809
+ if (msg.kind === "setLocale") {
810
+ /* The other document-level attribute flip, and the whole visible half of an axis-3 locale:
811
+ `dir` is what makes an RTL preview actually mirror, and `lang` is what CSS's `:lang()` and
812
+ the font stack select on. Patch-free like the scheme above — the TEXT is whatever file is
813
+ open, because a translation in Jx is a different file rather than a different rendering.
814
+ Cleared rather than blanked when the pane goes back to the document's own language: an
815
+ empty `lang=""` is a document that claims to be in no language at all. */
816
+ const root = container.ownerDocument.documentElement;
817
+ if (msg.locale === null) {
818
+ root.removeAttribute("lang");
819
+ root.removeAttribute("dir");
820
+ } else {
821
+ root.setAttribute("lang", msg.locale);
822
+ root.setAttribute("dir", msg.dir);
823
+ }
824
+ return;
825
+ }
597
826
  if (msg.kind === "siteStyleUpdate") {
598
827
  // Live design-token edit: swap the site-style sheet in place, no re-render.
599
828
  applySiteStyle(msg.siteStyle, msg.media);
@@ -646,6 +875,7 @@ export function startCanvasIframe(opts: {
646
875
  renderedGen = gen;
647
876
  currentMode = msg.mode;
648
877
  channel.post({ gen, kind: "renderComplete" });
878
+ armIdleWatch();
649
879
  // Thread a serializable snapshot of the resolved $defs to the parent so the data-explorer
650
880
  // Panel shows live data (the iframe, not the parent, now resolves the scope). Inside a
651
881
  // Reactive effect: dev-proxy data sources ($prototype/$src) return a ref that fills AFTER
@@ -681,8 +911,15 @@ export function startCanvasIframe(opts: {
681
911
  stopInlineEdit();
682
912
  stopSlashBridge();
683
913
  stopImageRetry();
914
+ if (idleFrame && win) {
915
+ win.cancelAnimationFrame(idleFrame);
916
+ }
917
+ idleFrame = 0;
918
+ container.removeEventListener("error", onImageError, true);
919
+ container.removeEventListener("load", onImageLoad, true);
684
920
  stopAutoScroll();
685
921
  heightObserver?.disconnect();
922
+ container.ownerDocument.removeEventListener("click", onLayoutClick, true);
686
923
  container.ownerDocument.removeEventListener("wheel", onWheel);
687
924
  container.ownerDocument.removeEventListener("dragenter", onNativeDragOver, true);
688
925
  container.ownerDocument.removeEventListener("dragleave", onNativeDragLeave, true);