@kritzel/engine 0.4.31 → 0.4.33

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 (84) hide show
  1. package/LICENSE.md +49 -49
  2. package/dist/cjs/{engine.constants-CakmdKMW.js → engine.constants-VyFrUl1W.js} +627 -129
  3. package/dist/cjs/{index-BbbWU2aN.js → index-BP5Iy6FQ.js} +27 -9
  4. package/dist/cjs/index.cjs.js +4 -2
  5. package/dist/cjs/kritzel-awareness-cursors_5.cjs.entry.js +257 -113
  6. package/dist/cjs/loader.cjs.js +2 -2
  7. package/dist/cjs/stencil.cjs.js +3 -3
  8. package/dist/collection/classes/core/core.class.js +40 -32
  9. package/dist/collection/classes/core/reviver.class.js +4 -0
  10. package/dist/collection/classes/core/store.class.js +10 -3
  11. package/dist/collection/classes/managers/cursor.manager.js +10 -5
  12. package/dist/collection/classes/objects/dynamic-object.class.js +18 -5
  13. package/dist/collection/classes/objects/iframe.class.js +447 -0
  14. package/dist/collection/classes/registries/icon-registry.class.js +100 -67
  15. package/dist/collection/classes/tools/selection-tool.class.js +3 -3
  16. package/dist/collection/collection-manifest.json +4 -2
  17. package/dist/collection/components/kritzel-awareness-cursors/kritzel-awareness-cursors.css +115 -115
  18. package/dist/collection/components/kritzel-awareness-cursors/kritzel-awareness-cursors.js +1 -1
  19. package/dist/collection/components/kritzel-cursor-trail/kritzel-cursor-trail.css +10 -10
  20. package/dist/collection/components/kritzel-cursor-trail/kritzel-cursor-trail.js +1 -1
  21. package/dist/collection/components/kritzel-engine/kritzel-engine.css +80 -80
  22. package/dist/collection/components/kritzel-engine/kritzel-engine.js +196 -44
  23. package/dist/collection/components/kritzel-icon/kritzel-icon.css +18 -18
  24. package/dist/collection/components/kritzel-icon/kritzel-icon.js +25 -4
  25. package/dist/collection/components/kritzel-watermark/kritzel-watermark.css +29 -29
  26. package/dist/collection/components/kritzel-watermark/kritzel-watermark.js +2 -2
  27. package/dist/collection/constants/version.js +1 -1
  28. package/dist/collection/helpers/cursor.helper.js +8 -8
  29. package/dist/collection/helpers/object.helper.js +13 -0
  30. package/dist/collection/helpers/svg-export.helper.js +55 -41
  31. package/dist/collection/helpers/wheel.helper.js +1 -7
  32. package/dist/collection/index.js +3 -0
  33. package/dist/collection/interfaces/embedded-object.interface.js +1 -0
  34. package/dist/collection/themes/dark-theme.js +1 -5
  35. package/dist/collection/themes/light-theme.js +1 -6
  36. package/dist/components/index.js +7 -7
  37. package/dist/components/kritzel-awareness-cursors.js +1 -1
  38. package/dist/components/kritzel-cursor-trail.js +1 -1
  39. package/dist/components/kritzel-engine.js +755 -161
  40. package/dist/components/kritzel-icon.js +1 -1
  41. package/dist/components/kritzel-watermark.js +1 -1
  42. package/dist/components/{p-B2Htv9ou.js → p-BHVbfJrf.js} +3 -3
  43. package/dist/components/{p-YP8wAcF4.js → p-BTU9qcSW.js} +2 -2
  44. package/dist/components/{p-CfSx6HU_.js → p-BWfRbEIq.js} +16 -4
  45. package/dist/components/p-NAEiq8CK.js +214 -0
  46. package/dist/components/{p-BvRGQvVI.js → p-k0LxV9Bg.js} +18 -14
  47. package/dist/esm/{engine.constants-Bl5-pbq-.js → engine.constants-BHTr2qPx.js} +626 -130
  48. package/dist/esm/{index-BU9Mv7y0.js → index-C8PnHbLt.js} +27 -10
  49. package/dist/esm/index.js +3 -3
  50. package/dist/esm/kritzel-awareness-cursors_5.entry.js +257 -113
  51. package/dist/esm/loader.js +3 -3
  52. package/dist/esm/stencil.js +4 -4
  53. package/dist/stencil/index.esm.js +3 -3
  54. package/dist/stencil/{p-f0a8b7af.entry.js → p-40097a38.entry.js} +257 -113
  55. package/dist/stencil/{p-Bl5-pbq-.js → p-BHTr2qPx.js} +626 -130
  56. package/dist/stencil/{p-BU9Mv7y0.js → p-C8PnHbLt.js} +27 -10
  57. package/dist/stencil/stencil.esm.js +4 -4
  58. package/dist/types/classes/core/store.class.d.ts +3 -2
  59. package/dist/types/classes/objects/dynamic-object.class.d.ts +4 -2
  60. package/dist/types/classes/objects/iframe.class.d.ts +76 -0
  61. package/dist/types/classes/registries/icon-registry.class.d.ts +75 -6
  62. package/dist/types/components/kritzel-engine/kritzel-engine.d.ts +14 -1
  63. package/dist/types/components/kritzel-icon/kritzel-icon.d.ts +5 -1
  64. package/dist/types/components.d.ts +26 -8
  65. package/dist/types/constants/version.d.ts +1 -1
  66. package/dist/types/helpers/cursor.helper.d.ts +2 -1
  67. package/dist/types/helpers/object.helper.d.ts +2 -0
  68. package/dist/types/helpers/svg-export.helper.d.ts +1 -0
  69. package/dist/types/helpers/wheel.helper.d.ts +2 -2
  70. package/dist/types/index.d.ts +3 -0
  71. package/dist/types/interfaces/context-menu-item.interface.d.ts +2 -1
  72. package/dist/types/interfaces/dynamic-object-renderer.interface.d.ts +7 -0
  73. package/dist/types/interfaces/embedded-object.interface.d.ts +9 -0
  74. package/dist/types/interfaces/engine-state.interface.d.ts +3 -2
  75. package/dist/types/interfaces/login-config.interface.d.ts +2 -1
  76. package/dist/types/interfaces/master-detail.interface.d.ts +2 -1
  77. package/dist/types/interfaces/menu-item.interface.d.ts +2 -1
  78. package/dist/types/interfaces/theme.interface.d.ts +6 -7
  79. package/dist/types/interfaces/tool.interface.d.ts +9 -0
  80. package/dist/types/interfaces/toolbar-item.interface.d.ts +3 -2
  81. package/dist/types/stencil-public-runtime.d.ts +61 -55
  82. package/package.json +3 -1
  83. package/readme.md +10 -10
  84. package/dist/components/p-fx6msYHJ.js +0 -167
@@ -1,29 +1,29 @@
1
- :host {
2
- position: absolute;
3
- bottom: var(--kritzel-watermark-offset-bottom, 12px);
4
- right: var(--kritzel-watermark-offset-right, 12px);
5
- z-index: 10000;
6
- pointer-events: none;
7
- }
8
-
9
- .watermark-link {
10
- pointer-events: auto;
11
- display: inline-flex;
12
- align-items: center;
13
- padding: 4px 8px;
14
- border-radius: var(--kritzel-watermark-border-radius, 6px);
15
- font-family: var(--kritzel-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
16
- font-size: var(--kritzel-watermark-font-size, 11px);
17
- line-height: 1;
18
- text-decoration: none;
19
- color: var(--kritzel-watermark-color, rgba(60, 60, 60, 0.75));
20
- background-color: var(--kritzel-watermark-background, rgba(255, 255, 255, 0.6));
21
- box-shadow: var(--kritzel-watermark-box-shadow, 0 1px 2px rgba(0, 0, 0, 0.12));
22
- opacity: var(--kritzel-watermark-opacity, 0.85);
23
- transition: opacity 150ms ease;
24
- user-select: none;
25
- }
26
-
27
- .watermark-link:hover {
28
- opacity: 1;
29
- }
1
+ :host {
2
+ position: absolute;
3
+ bottom: var(--kritzel-watermark-offset-bottom, 12px);
4
+ right: var(--kritzel-watermark-offset-right, 12px);
5
+ z-index: 10000;
6
+ pointer-events: none;
7
+ }
8
+
9
+ .watermark-link {
10
+ pointer-events: auto;
11
+ display: inline-flex;
12
+ align-items: center;
13
+ padding: 4px 8px;
14
+ border-radius: var(--kritzel-watermark-border-radius, 6px);
15
+ font-family: var(--kritzel-global-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif);
16
+ font-size: var(--kritzel-watermark-font-size, 11px);
17
+ line-height: 1;
18
+ text-decoration: none;
19
+ color: var(--kritzel-watermark-color, rgba(60, 60, 60, 0.75));
20
+ background-color: var(--kritzel-watermark-background, rgba(255, 255, 255, 0.6));
21
+ box-shadow: var(--kritzel-watermark-box-shadow, 0 1px 2px rgba(0, 0, 0, 0.12));
22
+ opacity: var(--kritzel-watermark-opacity, 0.85);
23
+ transition: opacity 150ms ease;
24
+ user-select: none;
25
+ }
26
+
27
+ .watermark-link:hover {
28
+ opacity: 1;
29
+ }
@@ -19,7 +19,7 @@ export class KritzelWatermark {
19
19
  label;
20
20
  render() {
21
21
  const label = this.label ?? this.core.localizationManager.translate('watermark.poweredBy');
22
- return (h(Host, { key: '2bacbc19d9469c7fcaf5d6b1b3133ec14d3ff864' }, h("a", { key: '2de44e340afd092ed388b7575350af1ee9155d58', class: "watermark-link", href: KRITZEL_WEBSITE_URL, target: "_blank", rel: "noopener noreferrer", part: "watermark", onPointerDown: (ev) => ev.stopPropagation(), onPointerUp: (ev) => ev.stopPropagation() }, label)));
22
+ return (h(Host, { key: '5bc76650ecd1f82f5ed283d4433b0e5fc8937cab' }, h("a", { key: 'b0828f36df618e461794772d2e8f55c0a8cb357e', class: "watermark-link", href: KRITZEL_WEBSITE_URL, target: "_blank", rel: "noopener noreferrer", part: "watermark", onPointerDown: (ev) => ev.stopPropagation(), onPointerUp: (ev) => ev.stopPropagation() }, label)));
23
23
  }
24
24
  static get is() { return "kritzel-watermark"; }
25
25
  static get encapsulation() { return "shadow"; }
@@ -71,7 +71,7 @@ export class KritzelWatermark {
71
71
  "optional": true,
72
72
  "docs": {
73
73
  "tags": [],
74
- "text": "Resolved \"Powered by Kritzel\" label. Passed in by the engine so the badge\r\nre-renders when the active locale changes. Falls back to resolving the term\r\nfrom the core when not provided."
74
+ "text": "Resolved \"Powered by Kritzel\" label. Passed in by the engine so the badge\nre-renders when the active locale changes. Falls back to resolving the term\nfrom the core when not provided."
75
75
  },
76
76
  "getter": false,
77
77
  "setter": false,
@@ -3,4 +3,4 @@
3
3
  * This file is auto-generated by the version bump scripts.
4
4
  * Do not modify manually.
5
5
  */
6
- export const KRITZEL_VERSION = '0.4.31';
6
+ export const KRITZEL_VERSION = '0.4.33';
@@ -16,7 +16,7 @@ export class KritzelCursorHelper {
16
16
  * The icon is retrieved from the KritzelIconRegistry.
17
17
  */
18
18
  static getCursor(options) {
19
- const iconName = options.iconName === 'default' ? 'mouse-pointer' : options.iconName;
19
+ const iconName = options.iconName === 'default' ? 'mousePointer' : options.iconName;
20
20
  const iconSvg = KritzelIconRegistry.get(iconName);
21
21
  if (!iconSvg) {
22
22
  console.warn(`Icon "${iconName}" not found in registry.`);
@@ -25,7 +25,7 @@ export class KritzelCursorHelper {
25
25
  const size = options.size || 24;
26
26
  const rotation = options.rotation || 0;
27
27
  const color = options.color || 'black';
28
- // Default cursor (mouse-pointer) has hotspot at (4, 4), others at center
28
+ // Default cursor (mousePointer) has hotspot at (4, 4), others at center
29
29
  const hotspot = options.hotspot || (options.iconName === 'default' ? { x: 4, y: 4 } : { x: size / 2, y: size / 2 });
30
30
  // Modify the SVG string to set size and color
31
31
  // We replace width and height to match the requested size
@@ -38,12 +38,12 @@ export class KritzelCursorHelper {
38
38
  // We rotate around the center of the SVG canvas
39
39
  const center = size / 2;
40
40
  // We use a group to apply the rotation
41
- const svg = `
42
- <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
43
- <g transform="rotate(${rotation} ${center} ${center})">
44
- ${content}
45
- </g>
46
- </svg>
41
+ const svg = `
42
+ <svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
43
+ <g transform="rotate(${rotation} ${center} ${center})">
44
+ ${content}
45
+ </g>
46
+ </svg>
47
47
  `;
48
48
  // Encode the SVG for use in a data URI
49
49
  // We need to be careful with encoding to ensure it works across browsers
@@ -15,6 +15,19 @@ export class ObjectHelper {
15
15
  static isClass(object, className) {
16
16
  return !!object && object.__class__ === className;
17
17
  }
18
+ static isKritzelEmbeddedObject(object) {
19
+ if (!object || typeof object !== 'object') {
20
+ return false;
21
+ }
22
+ const candidate = object;
23
+ return (typeof candidate.isInteractive === 'boolean' &&
24
+ typeof candidate.isSelected === 'boolean' &&
25
+ typeof candidate.mount === 'function' &&
26
+ typeof candidate.unmount === 'function' &&
27
+ typeof candidate.setIsInteractive === 'function' &&
28
+ typeof candidate.hasFocusedInputElement === 'function' &&
29
+ typeof candidate.getEmbeddedContentRoots === 'function');
30
+ }
18
31
  static isKritzelExportable(object) {
19
32
  if (!object || typeof object !== 'object') {
20
33
  return false;
@@ -66,8 +66,8 @@ export class KritzelSvgExportHelper {
66
66
  .join('\n ');
67
67
  const xmlDecl = includeXmlDeclaration ? '<?xml version="1.0" encoding="UTF-8"?>\n' : '';
68
68
  const defsContent = defs.length > 0 ? `\n <defs>\n ${defs.join('\n ')}\n </defs>` : '';
69
- return `${xmlDecl}<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}" width="${viewBoxWidth}" height="${viewBoxHeight}">${defsContent}
70
- ${elements}
69
+ return `${xmlDecl}<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}" width="${viewBoxWidth}" height="${viewBoxHeight}">${defsContent}
70
+ ${elements}
71
71
  </svg>`;
72
72
  }
73
73
  /**
@@ -219,8 +219,8 @@ export class KritzelSvgExportHelper {
219
219
  const orient = end === 'start' ? 'auto-start-reverse' : 'auto';
220
220
  const refX = 0;
221
221
  const refY = size / 2;
222
- return `<marker id="${markerId}" markerWidth="${size}" markerHeight="${size}" refX="${refX}" refY="${refY}" orient="${orient}" markerUnits="userSpaceOnUse">
223
- <path d="${path}" fill="${fill}" transform="scale(${size / 10})"/>
222
+ return `<marker id="${markerId}" markerWidth="${size}" markerHeight="${size}" refX="${refX}" refY="${refY}" orient="${orient}" markerUnits="userSpaceOnUse">
223
+ <path d="${path}" fill="${fill}" transform="scale(${size / 10})"/>
224
224
  </marker>`;
225
225
  }
226
226
  /**
@@ -249,6 +249,9 @@ export class KritzelSvgExportHelper {
249
249
  if (KritzelClassHelper.isInstanceOf(object, 'KritzelDynamicObject')) {
250
250
  return this.dynamicObjectToSvg(object, rasterSafeForCanvas);
251
251
  }
252
+ if (KritzelClassHelper.isInstanceOf(object, 'KritzelIframeObject')) {
253
+ return this.iframeObjectToSvg(object);
254
+ }
252
255
  if (KritzelClassHelper.isInstanceOf(object, 'KritzelGroup')) {
253
256
  return this.groupToSvg(object, theme, imageDataUrls, rasterSafeForCanvas);
254
257
  }
@@ -267,10 +270,10 @@ export class KritzelSvgExportHelper {
267
270
  const opacity = path.opacity !== 1 ? ` opacity="${path.opacity}"` : '';
268
271
  const scale = this.getObjectScale(path);
269
272
  // Path needs to be wrapped in a g with translation since path.d uses local coordinates
270
- return `<g transform="${transform}"${opacity}>
271
- <svg viewBox="${path.viewBox}" width="${path.totalWidth / scale}" height="${path.totalHeight / scale}" overflow="visible">
272
- <path d="${path.d}" fill="${fill || 'none'}" stroke="${stroke || 'none'}"${path.strokeWidth ? ` stroke-width="${path.strokeWidth}"` : ''}/>
273
- </svg>
273
+ return `<g transform="${transform}"${opacity}>
274
+ <svg viewBox="${path.viewBox}" width="${path.totalWidth / scale}" height="${path.totalHeight / scale}" overflow="visible">
275
+ <path d="${path.d}" fill="${fill || 'none'}" stroke="${stroke || 'none'}"${path.strokeWidth ? ` stroke-width="${path.strokeWidth}"` : ''}/>
276
+ </svg>
274
277
  </g>`;
275
278
  }
276
279
  /**
@@ -286,10 +289,10 @@ export class KritzelSvgExportHelper {
286
289
  const scale = this.getObjectScale(line);
287
290
  const markerStart = line.hasStartArrow ? ` marker-start="url(#${line.startMarkerId})"` : '';
288
291
  const markerEnd = line.hasEndArrow ? ` marker-end="url(#${line.endMarkerId})"` : '';
289
- return `<g transform="${transform}"${opacity}>
290
- <svg viewBox="${line.viewBox}" width="${line.totalWidth / scale}" height="${line.totalHeight / scale}" overflow="visible">
291
- <path d="${line.d}" fill="none" stroke="${stroke}" stroke-width="${line.strokeWidth}" stroke-linecap="round"${markerStart}${markerEnd}/>
292
- </svg>
292
+ return `<g transform="${transform}"${opacity}>
293
+ <svg viewBox="${line.viewBox}" width="${line.totalWidth / scale}" height="${line.totalHeight / scale}" overflow="visible">
294
+ <path d="${line.d}" fill="none" stroke="${stroke}" stroke-width="${line.strokeWidth}" stroke-linecap="round"${markerStart}${markerEnd}/>
295
+ </svg>
293
296
  </g>`;
294
297
  }
295
298
  /**
@@ -315,18 +318,18 @@ export class KritzelSvgExportHelper {
315
318
  const textHtml = this.prosemirrorToHtml(shape.content, shape, theme);
316
319
  if (textHtml) {
317
320
  const fontColor = KritzelColorHelper.resolveThemeColor(shape.fontColor, theme);
318
- textContent = `
319
- <foreignObject x="${shape.x}" y="${shape.y}" width="${shape.width}" height="${shape.height}">
320
- <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;">
321
- ${textHtml}
322
- </div>
321
+ textContent = `
322
+ <foreignObject x="${shape.x}" y="${shape.y}" width="${shape.width}" height="${shape.height}">
323
+ <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;">
324
+ ${textHtml}
325
+ </div>
323
326
  </foreignObject>`;
324
327
  }
325
328
  }
326
- return `<g transform="${transform}"${opacity}>
327
- <svg viewBox="${shape.viewBox}" width="${shape.totalWidth / scale}" height="${shape.totalHeight / scale}" overflow="visible" preserveAspectRatio="none">
328
- <path d="${pathD}" fill="${fill || 'transparent'}" stroke="${stroke}" stroke-width="${shape.strokeWidth}"/>${textContent}
329
- </svg>
329
+ return `<g transform="${transform}"${opacity}>
330
+ <svg viewBox="${shape.viewBox}" width="${shape.totalWidth / scale}" height="${shape.totalHeight / scale}" overflow="visible" preserveAspectRatio="none">
331
+ <path d="${pathD}" fill="${fill || 'transparent'}" stroke="${stroke}" stroke-width="${shape.strokeWidth}"/>${textContent}
332
+ </svg>
330
333
  </g>`;
331
334
  }
332
335
  /**
@@ -357,10 +360,10 @@ export class KritzelSvgExportHelper {
357
360
  // adjusted font-size already accounts for it – keeping both would double-scale
358
361
  // the content and overflow the foreignObject.
359
362
  const svgFontSizePx = (text.fontSize * (4 / 3) * (text.scaleFactor || 1) / scale).toFixed(4);
360
- return `<g transform="${transform}"${opacity}>
361
- <foreignObject x="0" y="0" width="${width}" height="${height}" overflow="visible">
362
- <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>
363
- </foreignObject>
363
+ return `<g transform="${transform}"${opacity}>
364
+ <foreignObject x="0" y="0" width="${width}" height="${height}" overflow="visible">
365
+ <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>
366
+ </foreignObject>
364
367
  </g>`;
365
368
  }
366
369
  /**
@@ -394,9 +397,9 @@ export class KritzelSvgExportHelper {
394
397
  return `<tspan x="0" y="${y}" xml:space="preserve">${this.escapeHtml(line)}</tspan>`;
395
398
  })
396
399
  .join('');
397
- return `<g transform="${transform}"${opacity}>
398
- ${bgRect}
399
- <text font-family="${this.escapeHtml(text.fontFamily)}" font-size="${resolvedFontSizePx}" fill="${fontColor}">${tspans}</text>
400
+ return `<g transform="${transform}"${opacity}>
401
+ ${bgRect}
402
+ <text font-family="${this.escapeHtml(text.fontFamily)}" font-size="${resolvedFontSizePx}" fill="${fontColor}">${tspans}</text>
400
403
  </g>`;
401
404
  }
402
405
  /**
@@ -424,8 +427,8 @@ export class KritzelSvgExportHelper {
424
427
  const width = image.totalWidth / scale;
425
428
  const height = image.totalHeight / scale;
426
429
  const href = imageDataUrls?.get(image.id) || image.resolvedSrc || image.src || '';
427
- return `<g transform="${transform}"${opacity}>
428
- <image href="${href}" x="0" y="0" width="${width}" height="${height}" preserveAspectRatio="xMidYMid meet"/>
430
+ return `<g transform="${transform}"${opacity}>
431
+ <image href="${href}" x="0" y="0" width="${width}" height="${height}" preserveAspectRatio="xMidYMid meet"/>
429
432
  </g>`;
430
433
  }
431
434
  /**
@@ -445,19 +448,30 @@ export class KritzelSvgExportHelper {
445
448
  if (rasterSafeForCanvas) {
446
449
  // PNG export: render placeholder rect (foreignObject doesn't rasterize to PNG well)
447
450
  console.warn('[KritzelDynamicObject SVG Export] Dynamic objects do not serialize well to PNG. Use SVG export or screenshot instead.');
448
- return `<g transform="${transform}"${opacity}>
449
- <rect x="0" y="0" width="${width}" height="${height}" fill="#f0f0f0" stroke="#999" stroke-width="1" />
450
- <text x="${width / 2}" y="${height / 2}" text-anchor="middle" dominant-baseline="middle" font-size="12" fill="#999">[Dynamic Object]</text>
451
+ return `<g transform="${transform}"${opacity}>
452
+ <rect x="0" y="0" width="${width}" height="${height}" fill="#f0f0f0" stroke="#999" stroke-width="1" />
453
+ <text x="${width / 2}" y="${height / 2}" text-anchor="middle" dominant-baseline="middle" font-size="12" fill="#999">[Dynamic Object]</text>
451
454
  </g>`;
452
455
  }
453
456
  // SVG export: use foreignObject to embed HTML
454
457
  const html = obj.element?.outerHTML || '<div style="border:1px dashed #ccc">Empty</div>';
455
- return `<g transform="${transform}"${opacity}>
456
- <foreignObject x="0" y="0" width="${width}" height="${height}">
457
- <div xmlns="http://www.w3.org/1999/xhtml" style="width:100%;height:100%;overflow:hidden;">
458
- ${html}
459
- </div>
460
- </foreignObject>
458
+ return `<g transform="${transform}"${opacity}>
459
+ <foreignObject x="0" y="0" width="${width}" height="${height}">
460
+ <div xmlns="http://www.w3.org/1999/xhtml" style="width:100%;height:100%;overflow:hidden;">
461
+ ${html}
462
+ </div>
463
+ </foreignObject>
464
+ </g>`;
465
+ }
466
+ static iframeObjectToSvg(object) {
467
+ const transform = this.buildTransform(object);
468
+ const opacity = object.opacity !== 1 ? ` opacity="${object.opacity}"` : '';
469
+ const scale = this.getObjectScale(object);
470
+ const width = object.totalWidth / scale;
471
+ const height = object.totalHeight / scale;
472
+ return `<g transform="${transform}"${opacity}>
473
+ <rect x="0" y="0" width="${width}" height="${height}" fill="#f0f0f0" stroke="#999" stroke-width="1" />
474
+ <text x="${width / 2}" y="${height / 2}" text-anchor="middle" dominant-baseline="middle" font-size="12" fill="#999">[Iframe]</text>
461
475
  </g>`;
462
476
  }
463
477
  /**
@@ -477,8 +491,8 @@ export class KritzelSvgExportHelper {
477
491
  return '';
478
492
  }
479
493
  const opacity = group.opacity !== 1 ? ` opacity="${group.opacity}"` : '';
480
- return `<g${opacity}>
481
- ${children}
494
+ return `<g${opacity}>
495
+ ${children}
482
496
  </g>`;
483
497
  }
484
498
  /**
@@ -14,13 +14,7 @@ export class KritzelWheelHelper {
14
14
  return this.canElementConsumeWheel(scrollContainer, ev.deltaX, ev.deltaY);
15
15
  }
16
16
  static getScrollableContainerFromEventPath(path, dynamicObject) {
17
- const potentialRoots = [];
18
- if (dynamicObject.element instanceof HTMLElement) {
19
- potentialRoots.push(dynamicObject.element);
20
- }
21
- if (dynamicObject.elementRef instanceof HTMLElement) {
22
- potentialRoots.push(dynamicObject.elementRef);
23
- }
17
+ const potentialRoots = dynamicObject.getEmbeddedContentRoots();
24
18
  const legacyElementRef = dynamicObject.elmeentRef;
25
19
  if (legacyElementRef instanceof HTMLElement) {
26
20
  potentialRoots.push(legacyElementRef);
@@ -15,6 +15,7 @@ export * from './classes/objects/line.class';
15
15
  export * from './classes/objects/group.class';
16
16
  export * from './classes/objects/shape.class';
17
17
  export * from './classes/objects/dynamic-object.class';
18
+ export * from './classes/objects/iframe.class';
18
19
  export * from './classes/objects/selection-group.class';
19
20
  export * from './classes/objects/selection-box.class';
20
21
  export * from './classes/tools/base-tool.class';
@@ -51,10 +52,12 @@ export * from './classes/registries/dynamic-object-renderer.registry';
51
52
  export * from './classes/registries/font-registry.class';
52
53
  export * from './classes/registries/icon-registry.class';
53
54
  export * from './interfaces/toolbar-item.interface';
55
+ export * from './interfaces/tool.interface';
54
56
  export * from './interfaces/menu-item.interface';
55
57
  export * from './interfaces/object-export.interface';
56
58
  export * from './interfaces/object-change-event.interface';
57
59
  export * from './interfaces/dynamic-object-renderer.interface';
60
+ export * from './interfaces/embedded-object.interface';
58
61
  export * from './interfaces/sync-provider.interface';
59
62
  export * from './interfaces/sync-config.interface';
60
63
  export * from './interfaces/asset.interface';
@@ -8,6 +8,7 @@ export const darkTheme = {
8
8
  dividerColor: '#3a3a3a',
9
9
  focusColor: '#ffffff',
10
10
  focusRingColor: '#ffffff',
11
+ fontFamily: 'sans-serif',
11
12
  iconColor: 'currentColor',
12
13
  scrollbarThumbColor: '#555555',
13
14
  textPrimary: '#ffffff',
@@ -130,11 +131,6 @@ export const darkTheme = {
130
131
  loadingOverlayColor: '#e0e0e0',
131
132
  loadingOverlaySpinnerActiveColor: '#e0e0e0',
132
133
  loadingOverlaySpinnerColor: '#555555',
133
- syncIndicatorBackground: 'rgba(30, 30, 30, 0.95)',
134
- syncIndicatorColor: '#e0e0e0',
135
- syncIndicatorSpinnerColor: '#0A84FF',
136
- syncIndicatorSpinnerTrack: 'rgba(160, 160, 160, 0.3)',
137
- syncIndicatorZIndex: '10001',
138
134
  },
139
135
  snap: {
140
136
  indicatorFill: 'rgba(10, 132, 255, 0.35)',
@@ -8,6 +8,7 @@ export const lightTheme = {
8
8
  dividerColor: '#e0e0e0',
9
9
  focusColor: '#333333',
10
10
  focusRingColor: '#333333',
11
+ fontFamily: 'sans-serif',
11
12
  iconColor: 'currentColor',
12
13
  scrollbarThumbColor: '#ebebeb',
13
14
  textPrimary: '#000000',
@@ -96,7 +97,6 @@ export const lightTheme = {
96
97
  closeButtonColor: '#333333',
97
98
  closeButtonHoverBackground: 'hsl(0, 0%, 0%, 4.3%)',
98
99
  closeButtonHoverColor: '#000000',
99
- fontFamily: 'inherit',
100
100
  footerBorder: '1px solid #ebebeb',
101
101
  headerBorder: '1px solid #ebebeb',
102
102
  titleColor: '#000000',
@@ -131,11 +131,6 @@ export const lightTheme = {
131
131
  loadingOverlayColor: '#333333',
132
132
  loadingOverlaySpinnerActiveColor: '#333333',
133
133
  loadingOverlaySpinnerColor: '#cccccc',
134
- syncIndicatorBackground: 'rgba(255, 255, 255, 0.92)',
135
- syncIndicatorColor: '#334155',
136
- syncIndicatorSpinnerColor: '#007AFF',
137
- syncIndicatorSpinnerTrack: 'rgba(148, 163, 184, 0.35)',
138
- syncIndicatorZIndex: '10001',
139
134
  },
140
135
  snap: {
141
136
  indicatorFill: 'rgba(59, 130, 246, 0.3)',
@@ -1,13 +1,13 @@
1
- export { g as getAssetPath, r as render, s as setAssetPath, a as setNonce, b as setPlatformOptions } from './p-CfSx6HU_.js';
2
- import { D as DEFAULT_COLOR_PALETTE } from './p-BvRGQvVI.js';
3
- export { K as KritzelBaseObject, c as KritzelColorHelper, b as KritzelLine, a as KritzelPath, d as KritzelThemeManager, O as ObjectHelper, T as ThemeHelper, e as darkTheme, l as lightTheme, r as resolveColor } from './p-BvRGQvVI.js';
1
+ export { g as getAssetPath, r as render, s as setAssetPath, a as setNonce, b as setPlatformOptions } from './p-BWfRbEIq.js';
2
+ import { D as DEFAULT_COLOR_PALETTE } from './p-k0LxV9Bg.js';
3
+ export { K as KritzelBaseObject, c as KritzelColorHelper, b as KritzelLine, a as KritzelPath, d as KritzelThemeManager, O as ObjectHelper, T as ThemeHelper, e as darkTheme, l as lightTheme, r as resolveColor } from './p-k0LxV9Bg.js';
4
4
  import { D as DEFAULT_STROKE_SIZES, a as DEFAULT_FONT_SIZES, b as DEFAULT_TEXT_TOOL_AVAILABLE_FONTS, S as ShapeType } from './kritzel-engine.js';
5
- export { L as APP_STATE_MIGRATIONS, A as AssetNotFoundError, N as CURRENT_APP_STATE_SCHEMA_VERSION, O as CURRENT_WORKSPACE_SCHEMA_VERSION, C as DEFAULT_SYNC_CONFIG, F as DE_LOCALE, E as EN_LOCALE, G as FR_LOCALE, I as IndexedDBAssetProvider, H as KritzelAlignment, w as KritzelAnchorManager, u as KritzelAssetResolver, i as KritzelBaseTool, j as KritzelBrushTool, p as KritzelCursorHelper, r as KritzelDevicesHelper, f as KritzelDynamicObject, z as KritzelDynamicObjectRendererRegistry, KritzelEngine, l as KritzelEraserTool, B as KritzelFontRegistry, d as KritzelGroup, s as KritzelHTMLHelper, c as KritzelImage, m as KritzelImageTool, q as KritzelKeyboardHelper, y as KritzelLicenseManager, k as KritzelLineTool, x as KritzelLocalizationManager, h as KritzelSelectionBox, g as KritzelSelectionGroup, t as KritzelSelectionTool, e as KritzelShape, o as KritzelShapeTool, K as KritzelText, n as KritzelTextTool, v as KritzelWorkspace, W as WORKSPACE_EXPORT_VERSION, M as WORKSPACE_MIGRATIONS, defineCustomElement as defineCustomElementKritzelEngine, P as resolveTextToolAvailableFonts, J as runMigrations } from './kritzel-engine.js';
5
+ export { M as APP_STATE_MIGRATIONS, A as AssetNotFoundError, O as CURRENT_APP_STATE_SCHEMA_VERSION, P as CURRENT_WORKSPACE_SCHEMA_VERSION, E as DEFAULT_SYNC_CONFIG, G as DE_LOCALE, F as EN_LOCALE, H as FR_LOCALE, I as IndexedDBAssetProvider, J as KritzelAlignment, x as KritzelAnchorManager, v as KritzelAssetResolver, j as KritzelBaseTool, k as KritzelBrushTool, q as KritzelCursorHelper, s as KritzelDevicesHelper, f as KritzelDynamicObject, B as KritzelDynamicObjectRendererRegistry, KritzelEngine, m as KritzelEraserTool, C as KritzelFontRegistry, d as KritzelGroup, t as KritzelHTMLHelper, g as KritzelIframeObject, c as KritzelImage, n as KritzelImageTool, r as KritzelKeyboardHelper, z as KritzelLicenseManager, l as KritzelLineTool, y as KritzelLocalizationManager, i as KritzelSelectionBox, h as KritzelSelectionGroup, u as KritzelSelectionTool, e as KritzelShape, p as KritzelShapeTool, K as KritzelText, o as KritzelTextTool, w as KritzelWorkspace, W as WORKSPACE_EXPORT_VERSION, N as WORKSPACE_MIGRATIONS, defineCustomElement as defineCustomElementKritzelEngine, Q as resolveTextToolAvailableFonts, L as runMigrations } from './kritzel-engine.js';
6
6
  import * as Y from 'yjs';
7
7
  import { IndexeddbPersistence } from 'y-indexeddb';
8
8
  import { WebsocketProvider } from 'y-websocket';
9
- export { K as KritzelIconRegistry } from './p-fx6msYHJ.js';
10
- export { A as ABSOLUTE_SCALE_MAX, a as ABSOLUTE_SCALE_MIN, K as KRITZEL_WEBSITE_URL } from './p-B2Htv9ou.js';
9
+ export { K as KritzelIconRegistry, d as defaultIcons } from './p-NAEiq8CK.js';
10
+ export { A as ABSOLUTE_SCALE_MAX, a as ABSOLUTE_SCALE_MIN, K as KRITZEL_WEBSITE_URL } from './p-BHVbfJrf.js';
11
11
  export { KritzelAwarenessCursors, defineCustomElement as defineCustomElementKritzelAwarenessCursors } from './kritzel-awareness-cursors.js';
12
12
  export { KritzelCursorTrail, defineCustomElement as defineCustomElementKritzelCursorTrail } from './kritzel-cursor-trail.js';
13
13
  export { KritzelIcon, defineCustomElement as defineCustomElementKritzelIcon } from './kritzel-icon.js';
@@ -4138,6 +4138,6 @@ const DEFAULT_ASSET_STORAGE_CONFIG = {
4138
4138
  * This file is auto-generated by the version bump scripts.
4139
4139
  * Do not modify manually.
4140
4140
  */
4141
- const KRITZEL_VERSION = '0.4.31';
4141
+ const KRITZEL_VERSION = '0.4.33';
4142
4142
 
4143
4143
  export { BroadcastSyncProvider, DEFAULT_ASSET_STORAGE_CONFIG, DEFAULT_BRUSH_CONFIG, DEFAULT_COLOR_PALETTE, DEFAULT_LINE_TOOL_CONFIG, DEFAULT_SHAPE_CONFIG, DEFAULT_TEXT_CONFIG, DEFAULT_TEXT_TOOL_AVAILABLE_FONTS, HocuspocusSyncProvider, HttpAssetProvider, InMemorySyncProvider, IndexedDBSyncProvider, KRITZEL_VERSION, KritzelToolConfigHelper, PresignedAssetProvider, ShapeType, WebSocketSyncProvider, hasRemoteSyncProvider };
@@ -1,4 +1,4 @@
1
- import { f as KritzelAwarenessCursors$1, g as defineCustomElement$1 } from './p-BvRGQvVI.js';
1
+ import { f as KritzelAwarenessCursors$1, g as defineCustomElement$1 } from './p-k0LxV9Bg.js';
2
2
 
3
3
  const KritzelAwarenessCursors = KritzelAwarenessCursors$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -1,4 +1,4 @@
1
- import { K as KritzelCursorTrail$1, d as defineCustomElement$1 } from './p-YP8wAcF4.js';
1
+ import { K as KritzelCursorTrail$1, d as defineCustomElement$1 } from './p-BTU9qcSW.js';
2
2
 
3
3
  const KritzelCursorTrail = KritzelCursorTrail$1;
4
4
  const defineCustomElement = defineCustomElement$1;