kritzel-stencil 0.4.20 → 0.4.22

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 (226) hide show
  1. package/LICENSE +21 -21
  2. package/LICENSE.md +49 -49
  3. package/dist/cjs/{index-Dn19mGl-.js → index-Xav9JFHg.js} +11 -47
  4. package/dist/cjs/index.cjs.js +51 -2
  5. package/dist/cjs/kritzel-active-users_47.cjs.entry.js +268 -139
  6. package/dist/cjs/kritzel-brush-style.cjs.entry.js +2 -2
  7. package/dist/cjs/loader.cjs.js +1 -1
  8. package/dist/cjs/{schema.constants-CY0WWJYd.js → schema.constants-CjN-B633.js} +20 -44
  9. package/dist/cjs/stencil.cjs.js +2 -2
  10. package/dist/collection/classes/providers/sync/hocuspocus-sync-provider.class.js +21 -0
  11. package/dist/collection/classes/providers/sync/websocket-sync-provider.class.js +29 -1
  12. package/dist/collection/classes/structures/app-state-map.structure.js +19 -6
  13. package/dist/collection/classes/structures/object-map.structure.js +66 -4
  14. package/dist/collection/collection-manifest.json +1 -1
  15. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.css +115 -115
  16. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.js +1 -1
  17. package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.css +10 -10
  18. package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js +1 -1
  19. package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +160 -160
  20. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +51 -18
  21. package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +80 -80
  22. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +87 -38
  23. package/dist/collection/components/core/kritzel-watermark/kritzel-watermark.css +29 -29
  24. package/dist/collection/components/core/kritzel-watermark/kritzel-watermark.js +2 -2
  25. package/dist/collection/components/shared/kritzel-avatar/kritzel-avatar.css +58 -58
  26. package/dist/collection/components/shared/kritzel-avatar/kritzel-avatar.js +3 -3
  27. package/dist/collection/components/shared/kritzel-brush-style/kritzel-brush-style.css +42 -42
  28. package/dist/collection/components/shared/kritzel-brush-style/kritzel-brush-style.js +3 -3
  29. package/dist/collection/components/shared/kritzel-button/kritzel-button.css +73 -73
  30. package/dist/collection/components/shared/kritzel-button/kritzel-button.js +2 -2
  31. package/dist/collection/components/shared/kritzel-color/kritzel-color.css +24 -24
  32. package/dist/collection/components/shared/kritzel-color/kritzel-color.js +2 -2
  33. package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.css +46 -46
  34. package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +1 -1
  35. package/dist/collection/components/shared/kritzel-dialog/kritzel-dialog.css +209 -209
  36. package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.css +190 -190
  37. package/dist/collection/components/shared/kritzel-dropdown/kritzel-dropdown.js +2 -2
  38. package/dist/collection/components/shared/kritzel-font/kritzel-font.css +10 -10
  39. package/dist/collection/components/shared/kritzel-font/kritzel-font.js +1 -1
  40. package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.css +48 -48
  41. package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.js +2 -2
  42. package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.css +30 -30
  43. package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +1 -1
  44. package/dist/collection/components/shared/kritzel-icon/kritzel-icon.css +18 -18
  45. package/dist/collection/components/shared/kritzel-input/kritzel-input.css +69 -69
  46. package/dist/collection/components/shared/kritzel-input/kritzel-input.js +1 -1
  47. package/dist/collection/components/shared/kritzel-line-endings/kritzel-line-endings.css +60 -60
  48. package/dist/collection/components/shared/kritzel-line-endings/kritzel-line-endings.js +3 -3
  49. package/dist/collection/components/shared/kritzel-master-detail/kritzel-master-detail.css +190 -190
  50. package/dist/collection/components/shared/kritzel-master-detail/kritzel-master-detail.js +3 -3
  51. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.css +34 -34
  52. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +1 -1
  53. package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.css +166 -166
  54. package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js +2 -2
  55. package/dist/collection/components/shared/kritzel-numeric-input/kritzel-numeric-input.css +102 -102
  56. package/dist/collection/components/shared/kritzel-numeric-input/kritzel-numeric-input.js +1 -1
  57. package/dist/collection/components/shared/kritzel-opacity-slider/kritzel-opacity-slider.css +85 -85
  58. package/dist/collection/components/shared/kritzel-opacity-slider/kritzel-opacity-slider.js +1 -1
  59. package/dist/collection/components/shared/kritzel-pill-tabs/kritzel-pill-tabs.css +68 -68
  60. package/dist/collection/components/shared/kritzel-pill-tabs/kritzel-pill-tabs.js +2 -2
  61. package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +1 -1
  62. package/dist/collection/components/shared/kritzel-shape-fill/kritzel-shape-fill.css +47 -47
  63. package/dist/collection/components/shared/kritzel-shape-fill/kritzel-shape-fill.js +4 -4
  64. package/dist/collection/components/shared/kritzel-slide-toggle/kritzel-slide-toggle.css +48 -48
  65. package/dist/collection/components/shared/kritzel-slide-toggle/kritzel-slide-toggle.js +1 -1
  66. package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.css +78 -78
  67. package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js +1 -1
  68. package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.css +37 -37
  69. package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +1 -1
  70. package/dist/collection/components/shared/kritzel-sync-indicator/kritzel-sync-indicator.css +50 -50
  71. package/dist/collection/components/shared/kritzel-sync-indicator/kritzel-sync-indicator.js +1 -1
  72. package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.css +18 -18
  73. package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js +2 -2
  74. package/dist/collection/components/ui/kritzel-active-users/kritzel-active-users.css +65 -65
  75. package/dist/collection/components/ui/kritzel-back-to-content/kritzel-back-to-content.css +42 -42
  76. package/dist/collection/components/ui/kritzel-back-to-content/kritzel-back-to-content.js +1 -1
  77. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.css +112 -112
  78. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.css +331 -331
  79. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +6 -6
  80. package/dist/collection/components/ui/kritzel-current-user/kritzel-current-user.css +11 -11
  81. package/dist/collection/components/ui/kritzel-current-user/kritzel-current-user.js +1 -1
  82. package/dist/collection/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.css +39 -39
  83. package/dist/collection/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.js +1 -1
  84. package/dist/collection/components/ui/kritzel-export/kritzel-export.css +89 -89
  85. package/dist/collection/components/ui/kritzel-export/kritzel-export.js +1 -1
  86. package/dist/collection/components/ui/kritzel-loading-overlay/kritzel-loading-overlay.css +50 -50
  87. package/dist/collection/components/ui/kritzel-loading-overlay/kritzel-loading-overlay.js +1 -1
  88. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.css +98 -98
  89. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.js +1 -1
  90. package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.css +58 -58
  91. package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.js +2 -2
  92. package/dist/collection/components/ui/kritzel-notification-card/kritzel-notification-card.css +101 -101
  93. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.css +137 -137
  94. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +1 -1
  95. package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.css +150 -150
  96. package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.js +2 -2
  97. package/dist/collection/components/ui/kritzel-tool-config/kritzel-tool-config.css +38 -38
  98. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.css +45 -45
  99. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
  100. package/dist/collection/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.css +16 -16
  101. package/dist/collection/components/ui/kritzel-zoom-panel/kritzel-zoom-panel.css +72 -72
  102. package/dist/collection/components/ui/kritzel-zoom-panel/kritzel-zoom-panel.js +1 -1
  103. package/dist/collection/constants/version.js +1 -1
  104. package/dist/collection/helpers/cursor.helper.js +6 -6
  105. package/dist/collection/helpers/svg-export.helper.js +41 -41
  106. package/dist/components/index.js +53 -4
  107. package/dist/components/kritzel-active-users.js +1 -1
  108. package/dist/components/kritzel-avatar.js +1 -1
  109. package/dist/components/kritzel-awareness-cursors.js +1 -1
  110. package/dist/components/kritzel-back-to-content.js +1 -1
  111. package/dist/components/kritzel-brush-style.js +4 -4
  112. package/dist/components/kritzel-button.js +1 -1
  113. package/dist/components/kritzel-color-palette.js +1 -1
  114. package/dist/components/kritzel-color.js +1 -1
  115. package/dist/components/kritzel-context-menu.js +1 -1
  116. package/dist/components/kritzel-controls.js +1 -1
  117. package/dist/components/kritzel-current-user-dialog.js +1 -1
  118. package/dist/components/kritzel-current-user.js +1 -1
  119. package/dist/components/kritzel-cursor-trail.js +1 -1
  120. package/dist/components/kritzel-dialog.js +1 -1
  121. package/dist/components/kritzel-dropdown.js +1 -1
  122. package/dist/components/kritzel-editor.js +61 -56
  123. package/dist/components/kritzel-engine.js +1 -1
  124. package/dist/components/kritzel-export.js +1 -1
  125. package/dist/components/kritzel-font-family.js +1 -1
  126. package/dist/components/kritzel-font-size.js +1 -1
  127. package/dist/components/kritzel-font.js +1 -1
  128. package/dist/components/kritzel-icon.js +1 -1
  129. package/dist/components/kritzel-input.js +1 -1
  130. package/dist/components/kritzel-line-endings.js +1 -1
  131. package/dist/components/kritzel-loading-overlay.js +1 -1
  132. package/dist/components/kritzel-login-dialog.js +1 -1
  133. package/dist/components/kritzel-master-detail.js +1 -1
  134. package/dist/components/kritzel-menu-item.js +1 -1
  135. package/dist/components/kritzel-menu.js +1 -1
  136. package/dist/components/kritzel-more-menu.js +1 -1
  137. package/dist/components/kritzel-notification-card.js +1 -1
  138. package/dist/components/kritzel-numeric-input.js +1 -1
  139. package/dist/components/kritzel-opacity-slider.js +1 -1
  140. package/dist/components/kritzel-pill-tabs.js +1 -1
  141. package/dist/components/kritzel-portal.js +1 -1
  142. package/dist/components/kritzel-settings.js +1 -1
  143. package/dist/components/kritzel-shape-fill.js +1 -1
  144. package/dist/components/kritzel-share-dialog.js +1 -1
  145. package/dist/components/kritzel-slide-toggle.js +1 -1
  146. package/dist/components/kritzel-split-button.js +1 -1
  147. package/dist/components/kritzel-stroke-size.js +1 -1
  148. package/dist/components/kritzel-sync-indicator.js +1 -1
  149. package/dist/components/kritzel-tool-config.js +1 -1
  150. package/dist/components/kritzel-tooltip.js +1 -1
  151. package/dist/components/kritzel-utility-panel.js +1 -1
  152. package/dist/components/kritzel-watermark.js +1 -1
  153. package/dist/components/kritzel-workspace-manager.js +1 -1
  154. package/dist/components/kritzel-zoom-panel.js +1 -1
  155. package/dist/components/{p-CLAz6RJc.js → p-2WiGyky4.js} +3 -3
  156. package/dist/components/{p-zG-WUBGF.js → p-4SPnZZkH.js} +4 -4
  157. package/dist/components/{p-MhQxGUvY.js → p-B-585egz.js} +3 -3
  158. package/dist/components/{p-C9_yBEoX.js → p-B43upypT.js} +10 -30
  159. package/dist/components/{p-CSKToqUl.js → p-B5SWPDuq.js} +4 -4
  160. package/dist/components/{p-Covorf4C.js → p-BFYtCsZu.js} +3 -3
  161. package/dist/components/{p-Csxx9TbU.js → p-BNeE3SiZ.js} +216 -116
  162. package/dist/components/{p-DYPA7jpg.js → p-BPsKYMH6.js} +2 -2
  163. package/dist/components/{p-Cx-L_28S.js → p-BoN700-O.js} +3 -3
  164. package/dist/components/{p-ME1sDz3f.js → p-BozrueXV.js} +2 -2
  165. package/dist/components/{p-D2VcPEtL.js → p-BrNsOp2v.js} +6 -6
  166. package/dist/components/{p-BXUx_C0N.js → p-BsLI_BWq.js} +2 -2
  167. package/dist/components/{p-dAXnRkjA.js → p-C98Eb3_R.js} +5 -5
  168. package/dist/components/{p-Bxi-Bm49.js → p-CAoN_STZ.js} +2 -2
  169. package/dist/components/{p-CSWCmyzb.js → p-CF8pLc07.js} +5 -5
  170. package/dist/components/{p-D3BzgkIE.js → p-CSPYkLLH.js} +2 -2
  171. package/dist/components/{p-Ck-87E2G.js → p-CSuU8frA.js} +1 -1
  172. package/dist/components/{p-Di--2boB.js → p-CXpv9Rxe.js} +3 -3
  173. package/dist/components/{p-o3NYKrVL.js → p-CaBbajU2.js} +3 -3
  174. package/dist/components/{p-3tBE7SyG.js → p-Cm33td2O.js} +2 -2
  175. package/dist/components/{p-vDCa_ZDm.js → p-CrHvaLRV.js} +3 -3
  176. package/dist/components/{p-DT_WBwsw.js → p-CwZ3KKFq.js} +6 -6
  177. package/dist/components/{p-BZZ3KRPk.js → p-CzW58DHM.js} +3 -3
  178. package/dist/components/{p-BrqSjRJN.js → p-Czhdc844.js} +3 -3
  179. package/dist/components/{p-BkXQL5Dl.js → p-D1rjfWgJ.js} +5 -5
  180. package/dist/components/{p-DPsbNStn.js → p-DB58Oa5V.js} +2 -2
  181. package/dist/components/{p-DafP9PAA.js → p-DBqoPgev.js} +2 -2
  182. package/dist/components/{p-BrA9NBEE.js → p-DDTMGbtA.js} +21 -21
  183. package/dist/components/{p-Dznwo6oc.js → p-DKGg-76-.js} +2 -2
  184. package/dist/components/{p-Dp1CD4gK.js → p-DVXTPI71.js} +2 -2
  185. package/dist/components/{p-QSyeAy8R.js → p-DX2nriaq.js} +2 -2
  186. package/dist/components/{p-CHoOe3FD.js → p-Df3BwVGy.js} +3 -3
  187. package/dist/components/{p-DcUIO14-.js → p-Dt7-I2Xz.js} +4 -4
  188. package/dist/components/{p-BShrnlam.js → p-DtnMdWWB.js} +2 -2
  189. package/dist/components/{p-Ch-KG9To.js → p-DwMqCX2P.js} +3 -3
  190. package/dist/components/{p-25ExYYPf.js → p-Dx5NfJ0U.js} +9 -9
  191. package/dist/components/{p-fSV6KVTC.js → p-GKmqCI8r.js} +3 -3
  192. package/dist/components/{p-CWAChRD5.js → p-HoO86l1o.js} +12 -12
  193. package/dist/components/{p-Qdo3E8dr.js → p-PjPPCHVL.js} +2 -2
  194. package/dist/components/{p-D6JycG-I.js → p-bAacqNHq.js} +3 -3
  195. package/dist/components/{p-DjXQxw9R.js → p-djJSnjAX.js} +3 -3
  196. package/dist/components/{p-b0J2ktAm.js → p-dsxHDlQ3.js} +7 -7
  197. package/dist/components/{p-BppcoKoo.js → p-eZXIu4yK.js} +5 -5
  198. package/dist/components/{p-BFYT03fw.js → p-fL9rl200.js} +3 -3
  199. package/dist/components/{p-1Q4VnThv.js → p-jIKskj3S.js} +3 -3
  200. package/dist/components/{p-D0Trc3IQ.js → p-vqEUQ-4Q.js} +5 -5
  201. package/dist/esm/{index-2va1Pk9z.js → index-Dhio9uis.js} +11 -47
  202. package/dist/esm/index.js +52 -3
  203. package/dist/esm/kritzel-active-users_47.entry.js +268 -139
  204. package/dist/esm/kritzel-brush-style.entry.js +2 -2
  205. package/dist/esm/loader.js +2 -2
  206. package/dist/esm/{schema.constants-DBvUmuDH.js → schema.constants-DfvqHmxc.js} +20 -44
  207. package/dist/esm/stencil.js +3 -3
  208. package/dist/stencil/index.esm.js +52 -3
  209. package/dist/stencil/{p-DBvUmuDH.js → p-DfvqHmxc.js} +20 -44
  210. package/dist/stencil/{p-2va1Pk9z.js → p-Dhio9uis.js} +11 -47
  211. package/dist/stencil/{p-d19d1b82.entry.js → p-ab5c4292.entry.js} +268 -139
  212. package/dist/stencil/{p-df06ca3a.entry.js → p-fb32cd8f.entry.js} +2 -2
  213. package/dist/stencil/stencil.esm.js +4 -4
  214. package/dist/types/classes/providers/sync/hocuspocus-sync-provider.class.d.ts +5 -0
  215. package/dist/types/classes/providers/sync/websocket-sync-provider.class.d.ts +6 -0
  216. package/dist/types/classes/structures/app-state-map.structure.d.ts +6 -0
  217. package/dist/types/classes/structures/object-map.structure.d.ts +26 -2
  218. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +3 -0
  219. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +14 -1
  220. package/dist/types/components.d.ts +8 -1
  221. package/dist/types/constants/version.d.ts +1 -1
  222. package/dist/types/interfaces/sync-provider.interface.d.ts +13 -0
  223. package/dist/types/stencil-public-runtime.d.ts +0 -12
  224. package/loader/index.d.ts +1 -1
  225. package/package.json +1 -1
  226. package/readme.md +10 -10
@@ -1,17 +1,17 @@
1
- import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-C9_yBEoX.js';
2
- import { a as KritzelMouseButton, d as defineCustomElement$3 } from './p-3tBE7SyG.js';
3
- import { K as KritzelBaseObject, e as KritzelMathHelper, f as KritzelGeometryHelper, a as KritzelPath, b as KritzelLine, d as defineCustomElement$4 } from './p-D6JycG-I.js';
1
+ import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
+ import { a as KritzelMouseButton, d as defineCustomElement$3 } from './p-Cm33td2O.js';
3
+ import { K as KritzelBaseObject, e as KritzelMathHelper, f as KritzelGeometryHelper, a as KritzelPath, b as KritzelLine, d as defineCustomElement$4 } from './p-bAacqNHq.js';
4
4
  import { c as commonjsGlobal } from './p-BFTU3MAI.js';
5
5
  import { a as KritzelColorHelper, D as DEFAULT_COLOR_PALETTE, K as KritzelThemeManager } from './p-7I4Uzjrw.js';
6
6
  import { K as KritzelDevicesHelper } from './p-jGOpkGDl.js';
7
7
  import { K as KritzelFontRegistry, r as resolveTextToolAvailableFonts } from './p-DJkKlUyZ.js';
8
- import { A as ABSOLUTE_SCALE_MAX, a as ABSOLUTE_SCALE_MIN, d as defineCustomElement$1 } from './p-BShrnlam.js';
8
+ import { A as ABSOLUTE_SCALE_MAX, a as ABSOLUTE_SCALE_MIN, d as defineCustomElement$1 } from './p-DtnMdWWB.js';
9
9
  import { K as KritzelWorkspace, W as WORKSPACE_EXPORT_VERSION } from './p-DAwPPDMS.js';
10
10
  import { K as KritzelHTMLHelper } from './p-WUdQqYnu.js';
11
11
  import { O as ObjectHelper } from './p-DPONTran.js';
12
12
  import * as Y from 'yjs';
13
13
  import { a as CURRENT_WORKSPACE_SCHEMA_VERSION, C as CURRENT_APP_STATE_SCHEMA_VERSION } from './p-CW-VyJgK.js';
14
- import { K as KritzelIconRegistry, d as defineCustomElement$2 } from './p-Ck-87E2G.js';
14
+ import { K as KritzelIconRegistry, d as defineCustomElement$2 } from './p-CSuU8frA.js';
15
15
 
16
16
  class KritzelKeyboardHelper {
17
17
  static forceHideKeyboard() {
@@ -5076,11 +5076,10 @@ class Fitter {
5076
5076
  }
5077
5077
  openMore() {
5078
5078
  let { content, openStart, openEnd } = this.unplaced;
5079
- if (maxOpen(content, -1) <= openStart)
5079
+ let inner = contentAt(content, openStart);
5080
+ if (!inner.childCount || inner.firstChild.isLeaf)
5080
5081
  return false;
5081
- if (this.unplaced.size > 1 && maxOpen(content, 1) > openEnd)
5082
- openEnd++;
5083
- this.unplaced = new Slice(content, openStart + 1, openEnd);
5082
+ this.unplaced = new Slice(content, openStart + 1, Math.max(openEnd, inner.size + openStart >= content.size - openEnd ? openStart + 1 : 0));
5084
5083
  return true;
5085
5084
  }
5086
5085
  dropNode() {
@@ -5250,14 +5249,6 @@ function invalidMarks(type, fragment, start) {
5250
5249
  function definesContent(type) {
5251
5250
  return type.spec.defining || type.spec.definingForContent;
5252
5251
  }
5253
- function maxOpen(frag, side) {
5254
- for (let count = 0;; count++) {
5255
- let ch = side < 0 ? frag.firstChild : frag.lastChild;
5256
- if (!ch || ch.isAtom)
5257
- return count;
5258
- frag = ch.content;
5259
- }
5260
- }
5261
5252
  function replaceRange(tr, from, to, slice) {
5262
5253
  if (!slice.size)
5263
5254
  return tr.deleteRange(from, to);
@@ -7962,8 +7953,7 @@ class WidgetViewDesc extends ViewDesc {
7962
7953
  wrap.appendChild(dom);
7963
7954
  dom = wrap;
7964
7955
  }
7965
- if (!dom.hasAttribute("contenteditable"))
7966
- dom.contentEditable = "false";
7956
+ dom.contentEditable = "false";
7967
7957
  dom.classList.add("ProseMirror-widget");
7968
7958
  }
7969
7959
  super(parent, [], dom, null);
@@ -9811,14 +9801,8 @@ function maybeWrapTrusted(html) {
9811
9801
  // With the require-trusted-types-for CSP, Chrome will block
9812
9802
  // innerHTML, even on a detached document. This wraps the string in
9813
9803
  // a way that makes the browser allow us to use its parser again.
9814
- if (!_policy) {
9815
- if (_policy = trustedTypes.defaultPolicy)
9816
- try {
9817
- return _policy.createHTML(html);
9818
- }
9819
- catch (_a) { }
9820
- _policy = trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
9821
- }
9804
+ if (!_policy)
9805
+ _policy = trustedTypes.defaultPolicy || trustedTypes.createPolicy("ProseMirrorClipboard", { createHTML: (s) => s });
9822
9806
  return _policy.createHTML(html);
9823
9807
  }
9824
9808
  function readHTML(html) {
@@ -9875,12 +9859,6 @@ function addContext(slice, context) {
9875
9859
  let type = schema.nodes[array[i]];
9876
9860
  if (!type || type.hasRequiredAttrs())
9877
9861
  break;
9878
- try {
9879
- type.checkAttrs(array[i + 1]);
9880
- }
9881
- catch (e) {
9882
- break;
9883
- }
9884
9862
  content = Fragment.from(type.create(array[i + 1], content));
9885
9863
  openStart++;
9886
9864
  openEnd++;
@@ -13539,20 +13517,16 @@ a custom function to determine the type of the newly split off block.
13539
13517
  */
13540
13518
  function splitBlockAs(splitNode) {
13541
13519
  return (state, dispatch) => {
13520
+ let { $from} = state.selection;
13542
13521
  if (state.selection instanceof NodeSelection && state.selection.node.isBlock) {
13543
- let { $from } = state.selection;
13544
13522
  if (!$from.parentOffset || !canSplit(state.doc, $from.pos))
13545
13523
  return false;
13546
13524
  if (dispatch)
13547
13525
  dispatch(state.tr.split($from.pos).scrollIntoView());
13548
13526
  return true;
13549
13527
  }
13550
- if (!state.selection.$from.depth)
13528
+ if (!$from.depth)
13551
13529
  return false;
13552
- let tr = state.tr;
13553
- if (!state.selection.empty && (state.selection instanceof TextSelection || state.selection instanceof AllSelection))
13554
- tr.deleteSelection();
13555
- let { $from } = tr.selection, mapFrom = tr.steps.length;
13556
13530
  let types = [];
13557
13531
  let splitDepth, deflt, atEnd = false, atStart = false;
13558
13532
  for (let d = $from.depth;; d--) {
@@ -13571,7 +13545,10 @@ function splitBlockAs(splitNode) {
13571
13545
  types.unshift(null);
13572
13546
  }
13573
13547
  }
13574
- let splitPos = $from.pos;
13548
+ let tr = state.tr;
13549
+ if (state.selection instanceof TextSelection || state.selection instanceof AllSelection)
13550
+ tr.deleteSelection();
13551
+ let splitPos = tr.mapping.map($from.pos);
13575
13552
  let can = canSplit(tr.doc, splitPos, types.length, types);
13576
13553
  if (!can) {
13577
13554
  types[0] = deflt ? { type: deflt } : null;
@@ -13581,10 +13558,9 @@ function splitBlockAs(splitNode) {
13581
13558
  return false;
13582
13559
  tr.split(splitPos, types.length, types);
13583
13560
  if (!atEnd && atStart && $from.node(splitDepth).type != deflt) {
13584
- let mapping = tr.mapping.slice(mapFrom);
13585
- let first = mapping.map($from.before(splitDepth)), $first = tr.doc.resolve(first);
13561
+ let first = tr.mapping.map($from.before(splitDepth)), $first = tr.doc.resolve(first);
13586
13562
  if (deflt && $from.node(splitDepth - 1).canReplaceWith($first.index(), $first.index() + 1, deflt))
13587
- tr.setNodeMarkup(mapping.map($from.before(splitDepth)), deflt);
13563
+ tr.setNodeMarkup(tr.mapping.map($from.before(splitDepth)), deflt);
13588
13564
  }
13589
13565
  if (dispatch)
13590
13566
  dispatch(tr.scrollIntoView());
@@ -19319,12 +19295,12 @@ class KritzelCursorHelper {
19319
19295
  // We rotate around the center of the SVG canvas
19320
19296
  const center = size / 2;
19321
19297
  // We use a group to apply the rotation
19322
- const svg = `
19323
- <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
19324
- <g transform="rotate(${rotation} ${center} ${center})">
19325
- ${content}
19326
- </g>
19327
- </svg>
19298
+ const svg = `
19299
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
19300
+ <g transform="rotate(${rotation} ${center} ${center})">
19301
+ ${content}
19302
+ </g>
19303
+ </svg>
19328
19304
  `;
19329
19305
  // Encode the SVG for use in a data URI
19330
19306
  // We need to be careful with encoding to ensure it works across browsers
@@ -43343,6 +43319,10 @@ class KritzelObjectMap {
43343
43319
  _awarenessChangeHandler = null;
43344
43320
  _awarenessChangeCallbacks = [];
43345
43321
  _objectsChangeCallbacks = [];
43322
+ _remoteChangesCallbacks = [];
43323
+ _docUpdateHandler = null;
43324
+ _remoteOrigins = new Set();
43325
+ _appliedRemoteChanges = false;
43346
43326
  _lastAwarenessEmitTime = 0;
43347
43327
  _awarenessEmitTimeout = null;
43348
43328
  AWARENESS_THROTTLE_INTERVAL = 100; // milliseconds
@@ -43366,12 +43346,44 @@ class KritzelObjectMap {
43366
43346
  return this._isReady;
43367
43347
  }
43368
43348
  /**
43369
- * Promise that settles when network providers finish connecting.
43370
- * Resolves immediately if no network providers. Awaited by the loading overlay.
43349
+ * Promise that settles when network providers finish connecting and complete
43350
+ * their Yjs sync handshake. Resolves immediately if no network providers.
43371
43351
  */
43372
43352
  whenNetworkSynced() {
43373
43353
  return this._networkSyncPromise ?? Promise.resolve();
43374
43354
  }
43355
+ /**
43356
+ * Whether any configured provider synchronizes over the network.
43357
+ */
43358
+ get hasNetworkSyncProvider() {
43359
+ return this._providers.some(provider => provider.type === 'network');
43360
+ }
43361
+ /**
43362
+ * Whether remote-originated changes can be told apart from local writes.
43363
+ * Requires every network provider to expose its Yjs update origin.
43364
+ */
43365
+ get supportsRemoteChangeDetection() {
43366
+ const networkProviders = this._providers.filter(provider => provider.type === 'network');
43367
+ return networkProviders.length > 0 && networkProviders.every(provider => provider.updateOrigin !== undefined);
43368
+ }
43369
+ /**
43370
+ * Whether at least one update originating from a network provider has been
43371
+ * applied to this document. Stays `false` when the remote held no data the
43372
+ * local document was missing, because Yjs suppresses empty updates.
43373
+ */
43374
+ get hasAppliedRemoteChanges() {
43375
+ return this._appliedRemoteChanges;
43376
+ }
43377
+ /**
43378
+ * Registers a callback invoked whenever a network provider applies changes to this document.
43379
+ * @returns A function that unregisters the callback.
43380
+ */
43381
+ onRemoteChangesApplied(callback) {
43382
+ this._remoteChangesCallbacks.push(callback);
43383
+ return () => {
43384
+ this._remoteChangesCallbacks = this._remoteChangesCallbacks.filter(registered => registered !== callback);
43385
+ };
43386
+ }
43375
43387
  /**
43376
43388
  * Returns the Yjs Awareness instance, if a network provider is available.
43377
43389
  */
@@ -43614,6 +43626,22 @@ class KritzelObjectMap {
43614
43626
  const providerList = this._providers.map(p => `${p.constructor.name} (${p.type})`).join(', ');
43615
43627
  console.info(`[Kritzel] Workspace sync providers initialized for ${docName}: ${providerList || 'none'}`);
43616
43628
  }
43629
+ // Registered before any provider connects so no remote update can be missed.
43630
+ for (const provider of this._providers) {
43631
+ if (provider.type === 'network' && provider.updateOrigin !== undefined) {
43632
+ this._remoteOrigins.add(provider.updateOrigin);
43633
+ }
43634
+ }
43635
+ this._docUpdateHandler = (_update, origin) => {
43636
+ if (!this._remoteOrigins.has(origin)) {
43637
+ return;
43638
+ }
43639
+ this._appliedRemoteChanges = true;
43640
+ for (const callback of [...this._remoteChangesCallbacks]) {
43641
+ callback();
43642
+ }
43643
+ };
43644
+ this._ydoc.on('update', this._docUpdateHandler);
43617
43645
  // captureTimeout is effectively infinite — undo-step boundaries are
43618
43646
  // marked explicitly via markUndoBoundary() in insert/remove/reset and
43619
43647
  // at stroke/gesture boundaries in the tools. This prevents a single
@@ -43667,12 +43695,15 @@ class KritzelObjectMap {
43667
43695
  if (showSyncProviderInfo && networkProviders.length > 0) {
43668
43696
  console.info(`[Kritzel] Workspace network providers connecting in background: ${networkProviders.length}`);
43669
43697
  }
43670
- const networkConnectPromises = networkProviders.map(provider => provider.connect().catch(err => {
43698
+ const networkConnectPromises = networkProviders.map(provider => provider
43699
+ .connect()
43700
+ .then(() => provider.whenSynced?.())
43701
+ .catch(err => {
43671
43702
  if (showSyncProviderInfo) {
43672
43703
  console.error(`[Kritzel] Network sync provider "${provider.constructor.name}" failed to connect:`, err);
43673
43704
  }
43674
43705
  }));
43675
- // Network sync awaited by loading overlay to show remote workspace hydration
43706
+ // Settles once remote data has been reconciled, not merely once the transport connected
43676
43707
  this._networkSyncPromise = networkConnectPromises.length > 0 ? Promise.allSettled(networkConnectPromises).then(() => undefined) : null;
43677
43708
  this._isReady = true;
43678
43709
  // Find the first provider that exposes awareness (network providers)
@@ -44330,6 +44361,13 @@ class KritzelObjectMap {
44330
44361
  this._objectsMap.unobserve(this._objectsObserver);
44331
44362
  this._objectsObserver = null;
44332
44363
  }
44364
+ if (this._ydoc && this._docUpdateHandler) {
44365
+ this._ydoc.off('update', this._docUpdateHandler);
44366
+ }
44367
+ this._docUpdateHandler = null;
44368
+ this._remoteOrigins.clear();
44369
+ this._remoteChangesCallbacks = [];
44370
+ this._appliedRemoteChanges = false;
44333
44371
  // Remove undo manager event listeners
44334
44372
  if (this._undoManager) {
44335
44373
  if (this._stackItemAddedHandler) {
@@ -44726,6 +44764,7 @@ class KritzelAppStateMap {
44726
44764
  _isReady = false;
44727
44765
  _onRemoteChangeCallback = null;
44728
44766
  _workspacesObserver = null;
44767
+ _networkSyncPromise = null;
44729
44768
  /**
44730
44769
  * Indicates whether the app state map has been initialized and is ready for use.
44731
44770
  * @returns True if initialized and all providers are connected, false otherwise.
@@ -44733,6 +44772,13 @@ class KritzelAppStateMap {
44733
44772
  get isReady() {
44734
44773
  return this._isReady;
44735
44774
  }
44775
+ /**
44776
+ * Settles when network providers finish their initial sync (or fail/time out).
44777
+ * Resolves immediately when no network providers are configured.
44778
+ */
44779
+ whenNetworkSynced() {
44780
+ return this._networkSyncPromise ?? Promise.resolve();
44781
+ }
44736
44782
  /**
44737
44783
  * Indicates whether any configured sync provider replicates over the network.
44738
44784
  * Used by the engine to warn when a matching remote asset storage
@@ -44817,12 +44863,16 @@ class KritzelAppStateMap {
44817
44863
  if (showSyncProviderInfo && networkProviders.length > 0) {
44818
44864
  console.info(`[Kritzel] App-state network providers connecting in background: ${networkProviders.length}`);
44819
44865
  }
44820
- for (const provider of networkProviders) {
44821
- provider.connect().catch(err => {
44822
- if (showSyncProviderInfo) {
44823
- console.error(`[Kritzel] Network sync provider "${provider.constructor.name}" failed to connect:`, err);
44824
- }
44825
- });
44866
+ const networkConnectPromises = networkProviders.map(provider => provider
44867
+ .connect()
44868
+ .then(() => provider.whenSynced?.())
44869
+ .catch(err => {
44870
+ if (showSyncProviderInfo) {
44871
+ console.error(`[Kritzel] Network sync provider "${provider.constructor.name}" failed to connect:`, err);
44872
+ }
44873
+ }));
44874
+ if (networkConnectPromises.length > 0) {
44875
+ this._networkSyncPromise = Promise.allSettled(networkConnectPromises).then(() => undefined);
44826
44876
  }
44827
44877
  this._isReady = true;
44828
44878
  // Run any pending schema migrations before loading data
@@ -45147,6 +45197,7 @@ class KritzelAppStateMap {
45147
45197
  // Clear remaining references
45148
45198
  this._core = null;
45149
45199
  this._onRemoteChangeCallback = null;
45200
+ this._networkSyncPromise = null;
45150
45201
  this._isReady = false;
45151
45202
  }
45152
45203
  }
@@ -48099,8 +48150,8 @@ class KritzelSvgExportHelper {
48099
48150
  .join('\n ');
48100
48151
  const xmlDecl = includeXmlDeclaration ? '<?xml version="1.0" encoding="UTF-8"?>\n' : '';
48101
48152
  const defsContent = defs.length > 0 ? `\n <defs>\n ${defs.join('\n ')}\n </defs>` : '';
48102
- return `${xmlDecl}<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}" width="${viewBoxWidth}" height="${viewBoxHeight}">${defsContent}
48103
- ${elements}
48153
+ return `${xmlDecl}<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}" width="${viewBoxWidth}" height="${viewBoxHeight}">${defsContent}
48154
+ ${elements}
48104
48155
  </svg>`;
48105
48156
  }
48106
48157
  /**
@@ -48252,8 +48303,8 @@ class KritzelSvgExportHelper {
48252
48303
  const orient = end === 'start' ? 'auto-start-reverse' : 'auto';
48253
48304
  const refX = 0;
48254
48305
  const refY = size / 2;
48255
- return `<marker id="${markerId}" markerWidth="${size}" markerHeight="${size}" refX="${refX}" refY="${refY}" orient="${orient}" markerUnits="userSpaceOnUse">
48256
- <path d="${path}" fill="${fill}" transform="scale(${size / 10})"/>
48306
+ return `<marker id="${markerId}" markerWidth="${size}" markerHeight="${size}" refX="${refX}" refY="${refY}" orient="${orient}" markerUnits="userSpaceOnUse">
48307
+ <path d="${path}" fill="${fill}" transform="scale(${size / 10})"/>
48257
48308
  </marker>`;
48258
48309
  }
48259
48310
  /**
@@ -48300,10 +48351,10 @@ class KritzelSvgExportHelper {
48300
48351
  const opacity = path.opacity !== 1 ? ` opacity="${path.opacity}"` : '';
48301
48352
  const scale = this.getObjectScale(path);
48302
48353
  // Path needs to be wrapped in a g with translation since path.d uses local coordinates
48303
- return `<g transform="${transform}"${opacity}>
48304
- <svg viewBox="${path.viewBox}" width="${path.totalWidth / scale}" height="${path.totalHeight / scale}" overflow="visible">
48305
- <path d="${path.d}" fill="${fill || 'none'}" stroke="${stroke || 'none'}"${path.strokeWidth ? ` stroke-width="${path.strokeWidth}"` : ''}/>
48306
- </svg>
48354
+ return `<g transform="${transform}"${opacity}>
48355
+ <svg viewBox="${path.viewBox}" width="${path.totalWidth / scale}" height="${path.totalHeight / scale}" overflow="visible">
48356
+ <path d="${path.d}" fill="${fill || 'none'}" stroke="${stroke || 'none'}"${path.strokeWidth ? ` stroke-width="${path.strokeWidth}"` : ''}/>
48357
+ </svg>
48307
48358
  </g>`;
48308
48359
  }
48309
48360
  /**
@@ -48319,10 +48370,10 @@ class KritzelSvgExportHelper {
48319
48370
  const scale = this.getObjectScale(line);
48320
48371
  const markerStart = line.hasStartArrow ? ` marker-start="url(#${line.startMarkerId})"` : '';
48321
48372
  const markerEnd = line.hasEndArrow ? ` marker-end="url(#${line.endMarkerId})"` : '';
48322
- return `<g transform="${transform}"${opacity}>
48323
- <svg viewBox="${line.viewBox}" width="${line.totalWidth / scale}" height="${line.totalHeight / scale}" overflow="visible">
48324
- <path d="${line.d}" fill="none" stroke="${stroke}" stroke-width="${line.strokeWidth}" stroke-linecap="round"${markerStart}${markerEnd}/>
48325
- </svg>
48373
+ return `<g transform="${transform}"${opacity}>
48374
+ <svg viewBox="${line.viewBox}" width="${line.totalWidth / scale}" height="${line.totalHeight / scale}" overflow="visible">
48375
+ <path d="${line.d}" fill="none" stroke="${stroke}" stroke-width="${line.strokeWidth}" stroke-linecap="round"${markerStart}${markerEnd}/>
48376
+ </svg>
48326
48377
  </g>`;
48327
48378
  }
48328
48379
  /**
@@ -48346,18 +48397,18 @@ class KritzelSvgExportHelper {
48346
48397
  const textHtml = this.prosemirrorToHtml(shape.content, shape, theme);
48347
48398
  if (textHtml) {
48348
48399
  const fontColor = KritzelColorHelper.resolveThemeColor(shape.fontColor, theme);
48349
- textContent = `
48350
- <foreignObject x="${shape.x}" y="${shape.y}" width="${shape.width}" height="${shape.height}">
48351
- <div xmlns="http://www.w3.org/1999/xhtml" style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; text-align: center; font-family: ${shape.fontFamily}; font-size: ${shape.fontSize}px; color: ${fontColor}; overflow: hidden;">
48352
- ${textHtml}
48353
- </div>
48400
+ textContent = `
48401
+ <foreignObject x="${shape.x}" y="${shape.y}" width="${shape.width}" height="${shape.height}">
48402
+ <div xmlns="http://www.w3.org/1999/xhtml" style="width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; text-align: center; font-family: ${shape.fontFamily}; font-size: ${shape.fontSize}px; color: ${fontColor}; overflow: hidden;">
48403
+ ${textHtml}
48404
+ </div>
48354
48405
  </foreignObject>`;
48355
48406
  }
48356
48407
  }
48357
- return `<g transform="${transform}"${opacity}>
48358
- <svg viewBox="${shape.viewBox}" width="${shape.totalWidth / scale}" height="${shape.totalHeight / scale}" overflow="visible" preserveAspectRatio="none">
48359
- <path d="${pathD}" fill="${fill || 'transparent'}" stroke="${stroke}" stroke-width="${shape.strokeWidth}"/>${textContent}
48360
- </svg>
48408
+ return `<g transform="${transform}"${opacity}>
48409
+ <svg viewBox="${shape.viewBox}" width="${shape.totalWidth / scale}" height="${shape.totalHeight / scale}" overflow="visible" preserveAspectRatio="none">
48410
+ <path d="${pathD}" fill="${fill || 'transparent'}" stroke="${stroke}" stroke-width="${shape.strokeWidth}"/>${textContent}
48411
+ </svg>
48361
48412
  </g>`;
48362
48413
  }
48363
48414
  /**
@@ -48388,10 +48439,10 @@ class KritzelSvgExportHelper {
48388
48439
  // adjusted font-size already accounts for it – keeping both would double-scale
48389
48440
  // the content and overflow the foreignObject.
48390
48441
  const svgFontSizePx = (text.fontSize * (4 / 3) * (text.scaleFactor || 1) / scale).toFixed(4);
48391
- return `<g transform="${transform}"${opacity}>
48392
- <foreignObject x="0" y="0" width="${width}" height="${height}" overflow="visible">
48393
- <div xmlns="http://www.w3.org/1999/xhtml" style="font-family: ${text.fontFamily}; font-size: ${svgFontSizePx}px; color: ${fontColor}; background-color: ${bgColor || 'transparent'}; white-space: pre-wrap; word-wrap: break-word; width: 100%; margin: 0; padding: 0; box-sizing: border-box;">${htmlContent.trim()}</div>
48394
- </foreignObject>
48442
+ return `<g transform="${transform}"${opacity}>
48443
+ <foreignObject x="0" y="0" width="${width}" height="${height}" overflow="visible">
48444
+ <div xmlns="http://www.w3.org/1999/xhtml" style="font-family: ${text.fontFamily}; font-size: ${svgFontSizePx}px; color: ${fontColor}; background-color: ${bgColor || 'transparent'}; white-space: pre-wrap; word-wrap: break-word; width: 100%; margin: 0; padding: 0; box-sizing: border-box;">${htmlContent.trim()}</div>
48445
+ </foreignObject>
48395
48446
  </g>`;
48396
48447
  }
48397
48448
  /**
@@ -48425,9 +48476,9 @@ class KritzelSvgExportHelper {
48425
48476
  return `<tspan x="0" y="${y}" xml:space="preserve">${this.escapeHtml(line)}</tspan>`;
48426
48477
  })
48427
48478
  .join('');
48428
- return `<g transform="${transform}"${opacity}>
48429
- ${bgRect}
48430
- <text font-family="${this.escapeHtml(text.fontFamily)}" font-size="${resolvedFontSizePx}" fill="${fontColor}">${tspans}</text>
48479
+ return `<g transform="${transform}"${opacity}>
48480
+ ${bgRect}
48481
+ <text font-family="${this.escapeHtml(text.fontFamily)}" font-size="${resolvedFontSizePx}" fill="${fontColor}">${tspans}</text>
48431
48482
  </g>`;
48432
48483
  }
48433
48484
  /**
@@ -48455,8 +48506,8 @@ class KritzelSvgExportHelper {
48455
48506
  const width = image.totalWidth / scale;
48456
48507
  const height = image.totalHeight / scale;
48457
48508
  const href = imageDataUrls?.get(image.id) || image.resolvedSrc || image.src || '';
48458
- return `<g transform="${transform}"${opacity}>
48459
- <image href="${href}" x="0" y="0" width="${width}" height="${height}" preserveAspectRatio="xMidYMid meet"/>
48509
+ return `<g transform="${transform}"${opacity}>
48510
+ <image href="${href}" x="0" y="0" width="${width}" height="${height}" preserveAspectRatio="xMidYMid meet"/>
48460
48511
  </g>`;
48461
48512
  }
48462
48513
  /**
@@ -48476,19 +48527,19 @@ class KritzelSvgExportHelper {
48476
48527
  if (rasterSafeForCanvas) {
48477
48528
  // PNG export: render placeholder rect (foreignObject doesn't rasterize to PNG well)
48478
48529
  console.warn('[KritzelCustomElement SVG Export] Custom elements do not serialize well to PNG. Use SVG export or screenshot instead.');
48479
- return `<g transform="${transform}"${opacity}>
48480
- <rect x="0" y="0" width="${width}" height="${height}" fill="#f0f0f0" stroke="#999" stroke-width="1" />
48481
- <text x="${width / 2}" y="${height / 2}" text-anchor="middle" dominant-baseline="middle" font-size="12" fill="#999">[Custom Element]</text>
48530
+ return `<g transform="${transform}"${opacity}>
48531
+ <rect x="0" y="0" width="${width}" height="${height}" fill="#f0f0f0" stroke="#999" stroke-width="1" />
48532
+ <text x="${width / 2}" y="${height / 2}" text-anchor="middle" dominant-baseline="middle" font-size="12" fill="#999">[Custom Element]</text>
48482
48533
  </g>`;
48483
48534
  }
48484
48535
  // SVG export: use foreignObject to embed HTML
48485
48536
  const html = obj.element?.outerHTML || '<div style="border:1px dashed #ccc">Empty</div>';
48486
- return `<g transform="${transform}"${opacity}>
48487
- <foreignObject x="0" y="0" width="${width}" height="${height}">
48488
- <div xmlns="http://www.w3.org/1999/xhtml" style="width:100%;height:100%;overflow:hidden;">
48489
- ${html}
48490
- </div>
48491
- </foreignObject>
48537
+ return `<g transform="${transform}"${opacity}>
48538
+ <foreignObject x="0" y="0" width="${width}" height="${height}">
48539
+ <div xmlns="http://www.w3.org/1999/xhtml" style="width:100%;height:100%;overflow:hidden;">
48540
+ ${html}
48541
+ </div>
48542
+ </foreignObject>
48492
48543
  </g>`;
48493
48544
  }
48494
48545
  /**
@@ -48508,8 +48559,8 @@ class KritzelSvgExportHelper {
48508
48559
  return '';
48509
48560
  }
48510
48561
  const opacity = group.opacity !== 1 ? ` opacity="${group.opacity}"` : '';
48511
- return `<g${opacity}>
48512
- ${children}
48562
+ return `<g${opacity}>
48563
+ ${children}
48513
48564
  </g>`;
48514
48565
  }
48515
48566
  /**
@@ -48919,7 +48970,7 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
48919
48970
  contextMenuStateChange;
48920
48971
  /** Emitted when the combined loading state (external `isLoading` prop or internal workspace loading) changes. */
48921
48972
  loadingChange;
48922
- /** Emitted when remote workspace synchronization is in progress. */
48973
+ /** Emitted while remote changes are being applied to the active workspace. Stays silent when the remote holds nothing new. */
48923
48974
  syncingChange;
48924
48975
  forceUpdate = 0;
48925
48976
  isSyncing = false;
@@ -50506,6 +50557,7 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
50506
50557
  _sceneBootstrapOpacity = 1;
50507
50558
  _sceneBootstrapTransitionEnabled = false;
50508
50559
  _sceneBootstrapTransitionTimer = null;
50560
+ _remoteChangesUnsubscribe = null;
50509
50561
  _defaultUndoState = {
50510
50562
  canUndo: false,
50511
50563
  canRedo: false,
@@ -50523,9 +50575,16 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
50523
50575
  this.loadingChange.emit(this.core.store.state.isLoading);
50524
50576
  }
50525
50577
  syncSyncingState(isSyncing) {
50578
+ if (this.isSyncing === isSyncing) {
50579
+ return;
50580
+ }
50526
50581
  this.isSyncing = isSyncing;
50527
50582
  this.syncingChange.emit(isSyncing);
50528
50583
  }
50584
+ clearRemoteChangesSubscription() {
50585
+ this._remoteChangesUnsubscribe?.();
50586
+ this._remoteChangesUnsubscribe = null;
50587
+ }
50529
50588
  isNetworkAvailable() {
50530
50589
  return typeof navigator !== 'undefined' && navigator.onLine;
50531
50590
  }
@@ -50641,6 +50700,7 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
50641
50700
  disconnectedCallback() {
50642
50701
  this.throttledPointerMoveMulti.cancel();
50643
50702
  this._revealedImageKeys.clear();
50703
+ this.clearRemoteChangesSubscription();
50644
50704
  if (this._sceneBootstrapTransitionTimer !== null) {
50645
50705
  clearTimeout(this._sceneBootstrapTransitionTimer);
50646
50706
  this._sceneBootstrapTransitionTimer = null;
@@ -50787,6 +50847,7 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
50787
50847
  if (!this._isAssetStorageInitialized && this.assetStorageConfig) {
50788
50848
  await this.initializeAssetStorage();
50789
50849
  }
50850
+ await this.waitForRemoteAppStateIfEmpty();
50790
50851
  if (this.activeWorkspaceId) {
50791
50852
  const startupWorkspace = this.core.getWorkspaces().find(ws => ws.id === this.activeWorkspaceId);
50792
50853
  if (startupWorkspace) {
@@ -50819,6 +50880,27 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
50819
50880
  }
50820
50881
  this.tryResolveActiveWorkspaceFromId();
50821
50882
  }
50883
+ /**
50884
+ * On a cold start the remote workspace list may still be in flight; creating a
50885
+ * fallback workspace before it arrives would pollute the synced app state.
50886
+ */
50887
+ async waitForRemoteAppStateIfEmpty() {
50888
+ if (this.core.getWorkspaces().length > 0) {
50889
+ return;
50890
+ }
50891
+ if (!this.core.appStateMap.hasNetworkSyncProvider || !this.isNetworkAvailable()) {
50892
+ return;
50893
+ }
50894
+ this._isWorkspaceLoading = true;
50895
+ this.syncLoadingState();
50896
+ try {
50897
+ await this.core.appStateMap.whenNetworkSynced();
50898
+ }
50899
+ finally {
50900
+ this._isWorkspaceLoading = false;
50901
+ this.syncLoadingState();
50902
+ }
50903
+ }
50822
50904
  resolveStartupWorkspace() {
50823
50905
  if (this.activeWorkspaceId) {
50824
50906
  const workspaceById = this.core.getWorkspaces().find(ws => ws.id === this.activeWorkspaceId);
@@ -50873,21 +50955,7 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
50873
50955
  this._workspaceInitializationTargetKey = targetKey;
50874
50956
  try {
50875
50957
  await initializationPromise;
50876
- // Track remote sync in the background without blocking the loading overlay.
50877
- const initializedObjects = this.core.store.objects;
50878
- const networkSyncPromise = initializedObjects?.whenNetworkSynced();
50879
- if (networkSyncPromise && this.isNetworkAvailable()) {
50880
- this.syncSyncingState(true);
50881
- void networkSyncPromise.finally(() => {
50882
- // Only clear syncing for the currently active object map.
50883
- if (this.core.store.objects === initializedObjects) {
50884
- this.syncSyncingState(false);
50885
- }
50886
- });
50887
- }
50888
- else {
50889
- this.syncSyncingState(false);
50890
- }
50958
+ this.trackRemoteSynchronization();
50891
50959
  }
50892
50960
  finally {
50893
50961
  // Only the most recent init clears loading state to prevent race conditions
@@ -50899,6 +50967,38 @@ const KritzelEngine = /*@__PURE__*/ proxyCustomElement(class KritzelEngine exten
50899
50967
  }
50900
50968
  }
50901
50969
  }
50970
+ /**
50971
+ * Reports syncing only while remote data is actually being reconciled into the
50972
+ * active workspace. Yjs suppresses updates that carry nothing new, so a workspace
50973
+ * that already matches the remote never reports syncing at all.
50974
+ */
50975
+ trackRemoteSynchronization() {
50976
+ this.clearRemoteChangesSubscription();
50977
+ this.syncSyncingState(false);
50978
+ const initializedObjects = this.core.store.objects;
50979
+ if (!initializedObjects?.hasNetworkSyncProvider || !this.isNetworkAvailable()) {
50980
+ return;
50981
+ }
50982
+ if (initializedObjects.supportsRemoteChangeDetection) {
50983
+ this._remoteChangesUnsubscribe = initializedObjects.onRemoteChangesApplied(() => {
50984
+ if (this.core.store.objects !== initializedObjects) {
50985
+ return;
50986
+ }
50987
+ this.syncSyncingState(true);
50988
+ });
50989
+ }
50990
+ else {
50991
+ // Custom providers without an update origin cannot be diffed, so fall back to reporting the whole handshake.
50992
+ this.syncSyncingState(true);
50993
+ }
50994
+ void initializedObjects.whenNetworkSynced().finally(() => {
50995
+ if (this.core.store.objects !== initializedObjects) {
50996
+ return;
50997
+ }
50998
+ this.clearRemoteChangesSubscription();
50999
+ this.syncSyncingState(false);
51000
+ });
51001
+ }
50902
51002
  emitObjectsChange() {
50903
51003
  const objectsMap = this.core.store.objects;
50904
51004
  if (!objectsMap) {
@@ -1,4 +1,4 @@
1
- import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-C9_yBEoX.js';
1
+ import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
2
  import { O as ObjectHelper } from './p-DPONTran.js';
3
3
  import { K as KritzelHTMLHelper } from './p-WUdQqYnu.js';
4
4
 
@@ -286,7 +286,7 @@ const KritzelPortal = /*@__PURE__*/ proxyCustomElement(class KritzelPortal exten
286
286
  this.portal.style.visibility = 'visible';
287
287
  }
288
288
  render() {
289
- return (h(Host, { key: '3cdb321c2292fc7927a89efef4f3e4e37d68ac8f', style: { display: this.anchor ? 'block' : 'none' } }, h("slot", { key: '54a41f7983405f23e305791bc42513f59c027733' })));
289
+ return (h(Host, { key: '489a752e48d96c2607defa40a39477675685b60a', style: { display: this.anchor ? 'block' : 'none' } }, h("slot", { key: '13c6b7567039b8c8c78de27e3d9aeda30a798de1' })));
290
290
  }
291
291
  static get watchers() { return {
292
292
  "anchor": [{
@@ -1,4 +1,4 @@
1
- import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-C9_yBEoX.js';
1
+ import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
2
 
3
3
  const kritzelButtonCss = () => `:host{display:inline-block;font-family:sans-serif}button{border:none;background-color:transparent;padding:0;margin:0;font-family:inherit;font-size:inherit;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:var(--kritzel-global-pointer-cursor, pointer);display:inline-flex;width:var(--kritzel-button-width, auto);align-items:center;justify-content:center;gap:6px;border-radius:var(--kritzel-button-border-radius, 8px);padding:var(--kritzel-button-padding, 12px 20px);font-size:var(--kritzel-button-font-size, 14px);font-weight:var(--kritzel-button-font-weight, 500);transition:background-color 0.15s ease, opacity 0.15s ease;-webkit-tap-highlight-color:transparent}button.primary{background-color:var(--kritzel-button-primary-background-color, #007AFF);color:var(--kritzel-button-primary-color, #ffffff)}button.primary:hover{background-color:var(--kritzel-button-primary-hover-background-color, #006ae6)}button.primary:active{background-color:var(--kritzel-button-primary-active-background-color, #005bbf)}button.secondary{background-color:var(--kritzel-button-secondary-background-color, #f0f0f0);color:var(--kritzel-button-secondary-color, #333333)}button.secondary:hover{background-color:var(--kritzel-button-secondary-hover-background-color, #e0e0e0)}button.secondary:active{background-color:var(--kritzel-button-secondary-active-background-color, #d0d0d0)}button.text{background-color:transparent;color:var(--kritzel-button-text-color, #007AFF)}button.text:hover{background-color:var(--kritzel-button-text-hover-background-color, rgba(0, 122, 255, 0.08))}button.text:active{background-color:var(--kritzel-button-text-active-background-color, rgba(0, 122, 255, 0.15))}button.disabled{opacity:0.4;cursor:not-allowed;pointer-events:none}`;
4
4
 
@@ -26,11 +26,11 @@ const KritzelButton = /*@__PURE__*/ proxyCustomElement(class KritzelButton exten
26
26
  this.buttonClick.emit();
27
27
  };
28
28
  render() {
29
- return (h(Host, { key: 'ef407708a606dab1ac691b6c6f1c319ba5529e3b' }, h("button", { key: '5b26e220334c3ee20e0af433792496568067ca8c', type: this.type, class: {
29
+ return (h(Host, { key: '51621006f6b085db2b43accf52192f0674d2c50c' }, h("button", { key: '01ab2d96abe5ad34285e59f6fec66f6b21e91849', type: this.type, class: {
30
30
  'kritzel-button': true,
31
31
  [this.variant]: true,
32
32
  'disabled': this.disabled,
33
- }, disabled: this.disabled, onClick: this.handleClick }, h("slot", { key: '5272679ba3b67e3d7c0ec1b2ef0b3829ef4204ba' }))));
33
+ }, disabled: this.disabled, onClick: this.handleClick }, h("slot", { key: '4b085139ea85ad9f836059f4cf2dde15b948e0e2' }))));
34
34
  }
35
35
  static get style() { return kritzelButtonCss(); }
36
36
  }, [769, "kritzel-button", {