@kritzel/engine 0.4.31 → 0.4.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +49 -49
- package/dist/cjs/{engine.constants-CakmdKMW.js → engine.constants-cfbepvaI.js} +595 -98
- package/dist/cjs/{index-BbbWU2aN.js → index-BrjM5aN2.js} +12 -0
- package/dist/cjs/index.cjs.js +4 -2
- package/dist/cjs/kritzel-awareness-cursors_5.cjs.entry.js +257 -113
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/stencil.cjs.js +2 -2
- package/dist/collection/classes/core/core.class.js +40 -32
- package/dist/collection/classes/core/reviver.class.js +4 -0
- package/dist/collection/classes/core/store.class.js +10 -3
- package/dist/collection/classes/managers/cursor.manager.js +10 -5
- package/dist/collection/classes/objects/dynamic-object.class.js +18 -5
- package/dist/collection/classes/objects/iframe.class.js +447 -0
- package/dist/collection/classes/registries/icon-registry.class.js +100 -67
- package/dist/collection/classes/tools/selection-tool.class.js +3 -3
- package/dist/collection/collection-manifest.json +3 -1
- package/dist/collection/components/kritzel-awareness-cursors/kritzel-awareness-cursors.css +115 -115
- package/dist/collection/components/kritzel-awareness-cursors/kritzel-awareness-cursors.js +1 -1
- package/dist/collection/components/kritzel-cursor-trail/kritzel-cursor-trail.css +10 -10
- package/dist/collection/components/kritzel-cursor-trail/kritzel-cursor-trail.js +1 -1
- package/dist/collection/components/kritzel-engine/kritzel-engine.css +80 -80
- package/dist/collection/components/kritzel-engine/kritzel-engine.js +196 -44
- package/dist/collection/components/kritzel-icon/kritzel-icon.css +18 -18
- package/dist/collection/components/kritzel-icon/kritzel-icon.js +25 -4
- package/dist/collection/components/kritzel-watermark/kritzel-watermark.css +29 -29
- package/dist/collection/components/kritzel-watermark/kritzel-watermark.js +2 -2
- package/dist/collection/constants/version.js +1 -1
- package/dist/collection/helpers/cursor.helper.js +8 -8
- package/dist/collection/helpers/object.helper.js +13 -0
- package/dist/collection/helpers/svg-export.helper.js +55 -41
- package/dist/collection/helpers/wheel.helper.js +1 -7
- package/dist/collection/index.js +3 -0
- package/dist/collection/interfaces/embedded-object.interface.js +1 -0
- package/dist/collection/themes/dark-theme.js +1 -5
- package/dist/collection/themes/light-theme.js +1 -6
- package/dist/components/index.js +7 -7
- package/dist/components/kritzel-awareness-cursors.js +1 -1
- package/dist/components/kritzel-cursor-trail.js +1 -1
- package/dist/components/kritzel-engine.js +723 -130
- package/dist/components/kritzel-icon.js +1 -1
- package/dist/components/kritzel-watermark.js +1 -1
- package/dist/components/{p-YP8wAcF4.js → p-9YjkpHyU.js} +2 -2
- package/dist/components/p-BIUT0gBe.js +214 -0
- package/dist/components/{p-B2Htv9ou.js → p-Bnuu1qip.js} +3 -3
- package/dist/components/{p-CfSx6HU_.js → p-CJ5B8cMK.js} +12 -1
- package/dist/components/{p-BvRGQvVI.js → p-DXnF4FeS.js} +18 -14
- package/dist/esm/{engine.constants-Bl5-pbq-.js → engine.constants-DPDQhv6S.js} +594 -99
- package/dist/esm/{index-BU9Mv7y0.js → index-Hqbtnnex.js} +12 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/kritzel-awareness-cursors_5.entry.js +257 -113
- package/dist/esm/loader.js +3 -3
- package/dist/esm/stencil.js +3 -3
- package/dist/stencil/index.esm.js +3 -3
- package/dist/stencil/{p-Bl5-pbq-.js → p-DPDQhv6S.js} +594 -99
- package/dist/stencil/{p-BU9Mv7y0.js → p-Hqbtnnex.js} +12 -1
- package/dist/stencil/{p-f0a8b7af.entry.js → p-d678528e.entry.js} +257 -113
- package/dist/stencil/stencil.esm.js +3 -3
- package/dist/types/classes/core/store.class.d.ts +3 -2
- package/dist/types/classes/objects/dynamic-object.class.d.ts +4 -2
- package/dist/types/classes/objects/iframe.class.d.ts +76 -0
- package/dist/types/classes/registries/icon-registry.class.d.ts +75 -6
- package/dist/types/components/kritzel-engine/kritzel-engine.d.ts +14 -1
- package/dist/types/components/kritzel-icon/kritzel-icon.d.ts +5 -1
- package/dist/types/components.d.ts +26 -8
- package/dist/types/constants/version.d.ts +1 -1
- package/dist/types/helpers/cursor.helper.d.ts +2 -1
- package/dist/types/helpers/object.helper.d.ts +2 -0
- package/dist/types/helpers/svg-export.helper.d.ts +1 -0
- package/dist/types/helpers/wheel.helper.d.ts +2 -2
- package/dist/types/index.d.ts +3 -0
- package/dist/types/interfaces/context-menu-item.interface.d.ts +2 -1
- package/dist/types/interfaces/dynamic-object-renderer.interface.d.ts +7 -0
- package/dist/types/interfaces/embedded-object.interface.d.ts +9 -0
- package/dist/types/interfaces/engine-state.interface.d.ts +3 -2
- package/dist/types/interfaces/login-config.interface.d.ts +2 -1
- package/dist/types/interfaces/master-detail.interface.d.ts +2 -1
- package/dist/types/interfaces/menu-item.interface.d.ts +2 -1
- package/dist/types/interfaces/theme.interface.d.ts +6 -7
- package/dist/types/interfaces/tool.interface.d.ts +9 -0
- package/dist/types/interfaces/toolbar-item.interface.d.ts +3 -2
- package/package.json +1 -1
- package/readme.md +10 -10
- package/dist/components/p-fx6msYHJ.js +0 -167
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-
|
|
2
|
-
import { a as KritzelMouseButton, d as defineCustomElement$4 } from './p-
|
|
3
|
-
import { K as KritzelBaseObject, h as KritzelMathHelper, c as KritzelColorHelper, i as KritzelGeometryHelper, D as DEFAULT_COLOR_PALETTE, a as KritzelPath, b as KritzelLine, O as ObjectHelper, d as KritzelThemeManager, g as defineCustomElement$5 } from './p-
|
|
4
|
-
import { A as ABSOLUTE_SCALE_MAX, a as ABSOLUTE_SCALE_MIN, d as defineCustomElement$2 } from './p-
|
|
1
|
+
import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-CJ5B8cMK.js';
|
|
2
|
+
import { a as KritzelMouseButton, d as defineCustomElement$4 } from './p-9YjkpHyU.js';
|
|
3
|
+
import { K as KritzelBaseObject, h as KritzelMathHelper, c as KritzelColorHelper, i as KritzelGeometryHelper, D as DEFAULT_COLOR_PALETTE, a as KritzelPath, b as KritzelLine, O as ObjectHelper, d as KritzelThemeManager, g as defineCustomElement$5 } from './p-DXnF4FeS.js';
|
|
4
|
+
import { A as ABSOLUTE_SCALE_MAX, a as ABSOLUTE_SCALE_MIN, d as defineCustomElement$2 } from './p-Bnuu1qip.js';
|
|
5
5
|
import * as Y from 'yjs';
|
|
6
|
-
import { K as KritzelIconRegistry,
|
|
6
|
+
import { K as KritzelIconRegistry, a as defineCustomElement$3 } from './p-BIUT0gBe.js';
|
|
7
7
|
|
|
8
8
|
class KritzelDevicesHelper {
|
|
9
9
|
static isTouchDevice() {
|
|
@@ -17181,7 +17181,7 @@ class KritzelDynamicObject extends KritzelBaseObject {
|
|
|
17181
17181
|
}
|
|
17182
17182
|
applyInteractiveState() {
|
|
17183
17183
|
const pointerEvents = this.isInteractive ? 'auto' : 'none';
|
|
17184
|
-
const contentCursor = this.isInteractive ? 'auto' : '';
|
|
17184
|
+
const contentCursor = this.isInteractive ? 'var(--kritzel-global-default-cursor, auto)' : '';
|
|
17185
17185
|
if (this.element) {
|
|
17186
17186
|
this.element.style.pointerEvents = pointerEvents;
|
|
17187
17187
|
this.element.style.cursor = contentCursor;
|
|
@@ -17217,7 +17217,7 @@ class KritzelDynamicObject extends KritzelBaseObject {
|
|
|
17217
17217
|
if (!this.isInteractive) {
|
|
17218
17218
|
return false;
|
|
17219
17219
|
}
|
|
17220
|
-
const focusHosts = this.
|
|
17220
|
+
const focusHosts = this.getEmbeddedContentRoots();
|
|
17221
17221
|
// Primary path: locate the focused input-like element by walking from each host through
|
|
17222
17222
|
// `:focus` (piercing open shadow roots). This works in real browsers even when the engine
|
|
17223
17223
|
// and editor are nested web components, because it never relies on the document-level
|
|
@@ -17234,7 +17234,7 @@ class KritzelDynamicObject extends KritzelBaseObject {
|
|
|
17234
17234
|
}
|
|
17235
17235
|
return false;
|
|
17236
17236
|
}
|
|
17237
|
-
|
|
17237
|
+
getEmbeddedContentRoots() {
|
|
17238
17238
|
const hosts = [];
|
|
17239
17239
|
if (this.element) {
|
|
17240
17240
|
hosts.push(this.element);
|
|
@@ -17447,11 +17447,11 @@ class KritzelDynamicObject extends KritzelBaseObject {
|
|
|
17447
17447
|
* @returns A serializable object with htmlString and dimension snapshots
|
|
17448
17448
|
*/
|
|
17449
17449
|
serialize() {
|
|
17450
|
-
const { _core, _elementRef, element, totalWidth, totalHeight, isSelected, isHovered, isMounted, isInteractive, resizing, markedForRemoval, isVisible, ...props } = this;
|
|
17450
|
+
const { _core, _elementRef, element, totalWidth, totalHeight, isSelected, isHovered, isMounted, isInteractive, resizing, markedForRemoval, isVisible, rendererData, ...props } = this;
|
|
17451
17451
|
const cloned = structuredClone(props);
|
|
17452
17452
|
// Include rendererKey and rendererData for lifecycle-driven rendering
|
|
17453
17453
|
cloned.rendererKey = this.rendererKey;
|
|
17454
|
-
cloned.rendererData = this.
|
|
17454
|
+
cloned.rendererData = this.serializeRendererData();
|
|
17455
17455
|
// Store HTML as string for fallback/compatibility when renderer is unavailable
|
|
17456
17456
|
cloned.htmlString = element ? element.outerHTML : '';
|
|
17457
17457
|
// Capture dimension snapshot at serialization time
|
|
@@ -17459,6 +17459,19 @@ class KritzelDynamicObject extends KritzelBaseObject {
|
|
|
17459
17459
|
cloned.serializedHeight = this.height;
|
|
17460
17460
|
return cloned;
|
|
17461
17461
|
}
|
|
17462
|
+
serializeRendererData() {
|
|
17463
|
+
if (this.rendererKey) {
|
|
17464
|
+
const renderer = KritzelDynamicObjectRendererRegistry.get(this.rendererKey);
|
|
17465
|
+
if (renderer?.onSerialize) {
|
|
17466
|
+
return structuredClone(renderer.onSerialize({
|
|
17467
|
+
object: this,
|
|
17468
|
+
container: this.isMounted && this.elementRef instanceof HTMLElement ? this.elementRef : null,
|
|
17469
|
+
data: this.rendererData,
|
|
17470
|
+
}));
|
|
17471
|
+
}
|
|
17472
|
+
}
|
|
17473
|
+
return structuredClone(this.rendererData);
|
|
17474
|
+
}
|
|
17462
17475
|
/**
|
|
17463
17476
|
* Deserializes the dynamic object from a plain object.
|
|
17464
17477
|
* Reconstructs the element from stored HTML string with fallback to placeholder.
|
|
@@ -17491,6 +17504,452 @@ class KritzelDynamicObject extends KritzelBaseObject {
|
|
|
17491
17504
|
}
|
|
17492
17505
|
}
|
|
17493
17506
|
|
|
17507
|
+
const IFRAME_STATE_MESSAGE = 'kritzel-iframe-state';
|
|
17508
|
+
const IFRAME_PARENT_STATE_MESSAGE = 'kritzel-iframe-parent-state';
|
|
17509
|
+
const IFRAME_POINTER_MESSAGE = 'kritzel-iframe-pointer';
|
|
17510
|
+
const IFRAME_CONTEXT_MENU_MESSAGE = 'kritzel-iframe-contextmenu';
|
|
17511
|
+
const SUPPORTED_SANDBOX_TOKENS = new Set([
|
|
17512
|
+
'allow-downloads',
|
|
17513
|
+
'allow-forms',
|
|
17514
|
+
'allow-modals',
|
|
17515
|
+
'allow-orientation-lock',
|
|
17516
|
+
'allow-pointer-lock',
|
|
17517
|
+
'allow-popups',
|
|
17518
|
+
'allow-popups-to-escape-sandbox',
|
|
17519
|
+
'allow-presentation',
|
|
17520
|
+
'allow-same-origin',
|
|
17521
|
+
'allow-scripts',
|
|
17522
|
+
'allow-top-navigation-by-user-activation',
|
|
17523
|
+
]);
|
|
17524
|
+
const iframePointerBridgeStarts = new WeakMap();
|
|
17525
|
+
class KritzelIframeObject extends KritzelBaseObject {
|
|
17526
|
+
__class__ = 'KritzelIframeObject';
|
|
17527
|
+
content = { html: '', css: '', script: '' };
|
|
17528
|
+
loadingContent;
|
|
17529
|
+
isLoading = false;
|
|
17530
|
+
state = {};
|
|
17531
|
+
title = 'Embedded content';
|
|
17532
|
+
sandbox = ['allow-scripts'];
|
|
17533
|
+
borderRadius;
|
|
17534
|
+
boxShadow;
|
|
17535
|
+
get html() { return this.content.html; }
|
|
17536
|
+
set html(value) { this.content = { ...this.content, html: value }; }
|
|
17537
|
+
get css() { return this.content.css; }
|
|
17538
|
+
set css(value) { this.content = { ...this.content, css: value }; }
|
|
17539
|
+
get script() { return this.content.script; }
|
|
17540
|
+
set script(value) { this.content = { ...this.content, script: value }; }
|
|
17541
|
+
messageListener = null;
|
|
17542
|
+
constructor(config) {
|
|
17543
|
+
super();
|
|
17544
|
+
this.content = {
|
|
17545
|
+
html: config?.content?.html ?? config?.html ?? '',
|
|
17546
|
+
css: config?.content?.css ?? config?.css ?? '',
|
|
17547
|
+
script: config?.content?.script ?? config?.script ?? '',
|
|
17548
|
+
};
|
|
17549
|
+
this.loadingContent = config?.loadingContent ? {
|
|
17550
|
+
html: config.loadingContent.html ?? '',
|
|
17551
|
+
css: config.loadingContent.css ?? '',
|
|
17552
|
+
script: config.loadingContent.script ?? '',
|
|
17553
|
+
} : undefined;
|
|
17554
|
+
this.isLoading = config?.isLoading ?? false;
|
|
17555
|
+
this.state = structuredClone(config?.state ?? {});
|
|
17556
|
+
this.title = config?.title ?? 'Embedded content';
|
|
17557
|
+
this.sandbox = this.normalizeSandbox(config?.sandbox);
|
|
17558
|
+
this.borderRadius = config?.borderRadius;
|
|
17559
|
+
this.boxShadow = config?.boxShadow;
|
|
17560
|
+
this.translateX = config?.translateX ?? 0;
|
|
17561
|
+
this.translateY = config?.translateY ?? 0;
|
|
17562
|
+
this.rotation = KritzelMathHelper.degreesToRadians(config?.rotation ?? 0);
|
|
17563
|
+
this.scale = config?.scale ?? 1;
|
|
17564
|
+
this.width = config?.width ?? 0;
|
|
17565
|
+
this.height = config?.height ?? 0;
|
|
17566
|
+
}
|
|
17567
|
+
static create(core, config) {
|
|
17568
|
+
const object = new KritzelIframeObject(config);
|
|
17569
|
+
object._core = core;
|
|
17570
|
+
object.id = object.generateId();
|
|
17571
|
+
object.workspaceId = core.store.state.activeWorkspace.id;
|
|
17572
|
+
object.userId = core.user?.id;
|
|
17573
|
+
object.scale = config?.scale ?? core.store.state.scale;
|
|
17574
|
+
object.zIndex = core.store.currentZIndex;
|
|
17575
|
+
return object;
|
|
17576
|
+
}
|
|
17577
|
+
get sandboxAttribute() {
|
|
17578
|
+
return this.sandbox.join(' ');
|
|
17579
|
+
}
|
|
17580
|
+
mount(iframe) {
|
|
17581
|
+
if (this.isMounted && this.elementRef === iframe) {
|
|
17582
|
+
return;
|
|
17583
|
+
}
|
|
17584
|
+
if (this.isMounted) {
|
|
17585
|
+
this.unmount();
|
|
17586
|
+
}
|
|
17587
|
+
this.elementRef = iframe;
|
|
17588
|
+
this.isMounted = true;
|
|
17589
|
+
iframe.title = this.title;
|
|
17590
|
+
iframe.setAttribute('sandbox', this.sandboxAttribute);
|
|
17591
|
+
iframe.style.pointerEvents = this.isInteractive ? 'auto' : 'none';
|
|
17592
|
+
this.messageListener = event => this.handleMessage(event);
|
|
17593
|
+
window.addEventListener('message', this.messageListener);
|
|
17594
|
+
iframe.srcdoc = this.createSourceDocument();
|
|
17595
|
+
this.onMount(this.createLifecycleContext());
|
|
17596
|
+
}
|
|
17597
|
+
unmount() {
|
|
17598
|
+
if (!this.isMounted) {
|
|
17599
|
+
return;
|
|
17600
|
+
}
|
|
17601
|
+
const nextState = this.onUnmount(this.createLifecycleContext());
|
|
17602
|
+
if (nextState !== undefined) {
|
|
17603
|
+
this.state = structuredClone(nextState);
|
|
17604
|
+
}
|
|
17605
|
+
if (this.messageListener) {
|
|
17606
|
+
window.removeEventListener('message', this.messageListener);
|
|
17607
|
+
this.messageListener = null;
|
|
17608
|
+
}
|
|
17609
|
+
this.isMounted = false;
|
|
17610
|
+
this._elementRef = null;
|
|
17611
|
+
}
|
|
17612
|
+
setContent(content) {
|
|
17613
|
+
this.content = {
|
|
17614
|
+
html: content.html ?? this.content.html,
|
|
17615
|
+
css: content.css ?? this.content.css,
|
|
17616
|
+
script: content.script ?? this.content.script,
|
|
17617
|
+
};
|
|
17618
|
+
this.refreshDocument();
|
|
17619
|
+
this.persistUpdate();
|
|
17620
|
+
}
|
|
17621
|
+
setLoadingContent(content) {
|
|
17622
|
+
this.loadingContent = {
|
|
17623
|
+
html: content.html ?? this.loadingContent?.html ?? '',
|
|
17624
|
+
css: content.css ?? this.loadingContent?.css ?? '',
|
|
17625
|
+
script: content.script ?? this.loadingContent?.script ?? '',
|
|
17626
|
+
};
|
|
17627
|
+
this.refreshDocument();
|
|
17628
|
+
this.persistUpdate();
|
|
17629
|
+
}
|
|
17630
|
+
setLoading(isLoading) {
|
|
17631
|
+
this.isLoading = isLoading;
|
|
17632
|
+
this.refreshDocument();
|
|
17633
|
+
this.persistUpdate();
|
|
17634
|
+
}
|
|
17635
|
+
getActiveContent() {
|
|
17636
|
+
const activeLoadingContent = this.isLoading ? this.loadingContent : undefined;
|
|
17637
|
+
return {
|
|
17638
|
+
html: activeLoadingContent?.html ?? this.content.html,
|
|
17639
|
+
css: activeLoadingContent?.css ?? this.content.css,
|
|
17640
|
+
script: activeLoadingContent?.script ?? this.content.script,
|
|
17641
|
+
};
|
|
17642
|
+
}
|
|
17643
|
+
setState(state) {
|
|
17644
|
+
this.state = structuredClone(state);
|
|
17645
|
+
this.elementRef?.contentWindow?.postMessage({ type: IFRAME_PARENT_STATE_MESSAGE, state: this.state }, '*');
|
|
17646
|
+
this.persistUpdate();
|
|
17647
|
+
}
|
|
17648
|
+
setIsInteractive(isInteractive) {
|
|
17649
|
+
this.isInteractive = isInteractive;
|
|
17650
|
+
if (this.isMounted && this.elementRef) {
|
|
17651
|
+
this.elementRef.style.pointerEvents = isInteractive ? 'auto' : 'none';
|
|
17652
|
+
if (!isInteractive) {
|
|
17653
|
+
this.elementRef.blur();
|
|
17654
|
+
}
|
|
17655
|
+
}
|
|
17656
|
+
}
|
|
17657
|
+
hasFocusedInputElement() {
|
|
17658
|
+
return this.isInteractive && this.isMounted && document.activeElement === this.elementRef;
|
|
17659
|
+
}
|
|
17660
|
+
getEmbeddedContentRoots() {
|
|
17661
|
+
return this.isMounted && this.elementRef instanceof HTMLElement && this.elementRef.tagName === 'IFRAME' ? [this.elementRef] : [];
|
|
17662
|
+
}
|
|
17663
|
+
onMount(_context) { }
|
|
17664
|
+
onSerialize(context) {
|
|
17665
|
+
return context.state;
|
|
17666
|
+
}
|
|
17667
|
+
onUnmount(context) {
|
|
17668
|
+
return context.state;
|
|
17669
|
+
}
|
|
17670
|
+
serialize() {
|
|
17671
|
+
const nextState = this.onSerialize(this.createLifecycleContext());
|
|
17672
|
+
this.state = structuredClone(nextState);
|
|
17673
|
+
const messageListener = this.messageListener;
|
|
17674
|
+
this.messageListener = null;
|
|
17675
|
+
try {
|
|
17676
|
+
const serialized = super.serialize();
|
|
17677
|
+
delete serialized.messageListener;
|
|
17678
|
+
return serialized;
|
|
17679
|
+
}
|
|
17680
|
+
finally {
|
|
17681
|
+
this.messageListener = messageListener;
|
|
17682
|
+
}
|
|
17683
|
+
}
|
|
17684
|
+
deserialize(object) {
|
|
17685
|
+
super.deserialize(object);
|
|
17686
|
+
const nextContent = object.content && typeof object.content === 'object' ? object.content : {};
|
|
17687
|
+
const nextLoadingContent = object.loadingContent && typeof object.loadingContent === 'object' ? object.loadingContent : undefined;
|
|
17688
|
+
this.content = {
|
|
17689
|
+
html: typeof nextContent.html === 'string' ? nextContent.html : typeof object.html === 'string' ? object.html : '',
|
|
17690
|
+
css: typeof nextContent.css === 'string' ? nextContent.css : typeof object.css === 'string' ? object.css : '',
|
|
17691
|
+
script: typeof nextContent.script === 'string' ? nextContent.script : typeof object.script === 'string' ? object.script : '',
|
|
17692
|
+
};
|
|
17693
|
+
this.loadingContent = nextLoadingContent ? {
|
|
17694
|
+
html: typeof nextLoadingContent.html === 'string' ? nextLoadingContent.html : '',
|
|
17695
|
+
css: typeof nextLoadingContent.css === 'string' ? nextLoadingContent.css : '',
|
|
17696
|
+
script: typeof nextLoadingContent.script === 'string' ? nextLoadingContent.script : '',
|
|
17697
|
+
} : undefined;
|
|
17698
|
+
this.isLoading = typeof object.isLoading === 'boolean' ? object.isLoading : false;
|
|
17699
|
+
this.state = object.state && typeof object.state === 'object' ? structuredClone(object.state) : {};
|
|
17700
|
+
this.title = typeof object.title === 'string' ? object.title : 'Embedded content';
|
|
17701
|
+
this.sandbox = this.normalizeSandbox(Array.isArray(object.sandbox) ? object.sandbox.filter((token) => typeof token === 'string') : undefined);
|
|
17702
|
+
this.borderRadius = (typeof object.borderRadius === 'number' || typeof object.borderRadius === 'string') ? object.borderRadius : undefined;
|
|
17703
|
+
this.boxShadow = typeof object.boxShadow === 'string' ? object.boxShadow : undefined;
|
|
17704
|
+
this.messageListener = null;
|
|
17705
|
+
return this;
|
|
17706
|
+
}
|
|
17707
|
+
copy() {
|
|
17708
|
+
const copiedObject = super.copy();
|
|
17709
|
+
copiedObject.content = { ...this.content };
|
|
17710
|
+
copiedObject.loadingContent = this.loadingContent ? { ...this.loadingContent } : undefined;
|
|
17711
|
+
copiedObject.isLoading = this.isLoading;
|
|
17712
|
+
copiedObject.state = structuredClone(this.state);
|
|
17713
|
+
copiedObject.sandbox = [...this.sandbox];
|
|
17714
|
+
copiedObject.borderRadius = this.borderRadius;
|
|
17715
|
+
copiedObject.boxShadow = this.boxShadow;
|
|
17716
|
+
copiedObject.messageListener = null;
|
|
17717
|
+
copiedObject._elementRef = null;
|
|
17718
|
+
return copiedObject;
|
|
17719
|
+
}
|
|
17720
|
+
clone() {
|
|
17721
|
+
const clonedObject = super.clone();
|
|
17722
|
+
clonedObject.content = { ...this.content };
|
|
17723
|
+
clonedObject.loadingContent = this.loadingContent ? { ...this.loadingContent } : undefined;
|
|
17724
|
+
clonedObject.isLoading = this.isLoading;
|
|
17725
|
+
clonedObject.state = structuredClone(this.state);
|
|
17726
|
+
clonedObject.sandbox = [...this.sandbox];
|
|
17727
|
+
clonedObject.borderRadius = this.borderRadius;
|
|
17728
|
+
clonedObject.boxShadow = this.boxShadow;
|
|
17729
|
+
clonedObject.messageListener = null;
|
|
17730
|
+
clonedObject.isMounted = false;
|
|
17731
|
+
clonedObject._elementRef = null;
|
|
17732
|
+
return clonedObject;
|
|
17733
|
+
}
|
|
17734
|
+
adoptTransientStateFrom(previous) {
|
|
17735
|
+
if (!(previous instanceof KritzelIframeObject)) {
|
|
17736
|
+
return;
|
|
17737
|
+
}
|
|
17738
|
+
this.isInteractive = previous.isInteractive;
|
|
17739
|
+
this.isSelected = previous.isSelected;
|
|
17740
|
+
this.isHovered = previous.isHovered;
|
|
17741
|
+
if (!previous.isMounted || !(previous.elementRef instanceof HTMLElement) || previous.elementRef.tagName !== 'IFRAME') {
|
|
17742
|
+
return;
|
|
17743
|
+
}
|
|
17744
|
+
if (previous.messageListener) {
|
|
17745
|
+
window.removeEventListener('message', previous.messageListener);
|
|
17746
|
+
}
|
|
17747
|
+
this._elementRef = previous.elementRef;
|
|
17748
|
+
this.isMounted = true;
|
|
17749
|
+
this.messageListener = event => this.handleMessage(event);
|
|
17750
|
+
window.addEventListener('message', this.messageListener);
|
|
17751
|
+
this.elementRef.style.pointerEvents = this.isInteractive ? 'auto' : 'none';
|
|
17752
|
+
previous.messageListener = null;
|
|
17753
|
+
previous.isMounted = false;
|
|
17754
|
+
previous._elementRef = null;
|
|
17755
|
+
}
|
|
17756
|
+
createLifecycleContext() {
|
|
17757
|
+
return {
|
|
17758
|
+
object: this,
|
|
17759
|
+
iframe: this.isMounted ? this.elementRef : null,
|
|
17760
|
+
state: structuredClone(this.state),
|
|
17761
|
+
};
|
|
17762
|
+
}
|
|
17763
|
+
normalizeSandbox(tokens) {
|
|
17764
|
+
const requestedTokens = tokens ?? ['allow-scripts'];
|
|
17765
|
+
const normalized = requestedTokens.filter(token => SUPPORTED_SANDBOX_TOKENS.has(token));
|
|
17766
|
+
return [...new Set(normalized.length > 0 ? normalized : ['allow-scripts'])];
|
|
17767
|
+
}
|
|
17768
|
+
createSourceDocument() {
|
|
17769
|
+
const activeContent = this.getActiveContent();
|
|
17770
|
+
const state = JSON.stringify(this.state).replace(/</g, '\\u003c');
|
|
17771
|
+
const css = activeContent.css.replace(/<\/style/gi, '<\\/style');
|
|
17772
|
+
const script = activeContent.script.replace(/<\/script/gi, '<\\/script');
|
|
17773
|
+
const computedStyle = this.isMounted ? getComputedStyle(this.elementRef) : null;
|
|
17774
|
+
const defaultCursor = computedStyle?.getPropertyValue('--kritzel-global-default-cursor').trim() || 'auto';
|
|
17775
|
+
const pointerCursor = computedStyle?.getPropertyValue('--kritzel-global-pointer-cursor').trim() || defaultCursor;
|
|
17776
|
+
return `<!doctype html>
|
|
17777
|
+
<html>
|
|
17778
|
+
<head>
|
|
17779
|
+
<meta charset="utf-8">
|
|
17780
|
+
<style>
|
|
17781
|
+
:root {
|
|
17782
|
+
--kritzel-iframe-default-cursor: ${defaultCursor};
|
|
17783
|
+
--kritzel-iframe-pointer-cursor: ${pointerCursor};
|
|
17784
|
+
}
|
|
17785
|
+
html, body { width: 100%; height: 100%; margin: 0; overflow: hidden; cursor: var(--kritzel-iframe-default-cursor); }
|
|
17786
|
+
button, button *, a, a *, input, textarea, select { cursor: var(--kritzel-iframe-pointer-cursor) !important; }
|
|
17787
|
+
${css}
|
|
17788
|
+
</style>
|
|
17789
|
+
</head>
|
|
17790
|
+
<body>
|
|
17791
|
+
${activeContent.html}
|
|
17792
|
+
<script>
|
|
17793
|
+
const kritzel = globalThis.kritzel = {
|
|
17794
|
+
state: ${state},
|
|
17795
|
+
setState(nextState) {
|
|
17796
|
+
this.state = nextState;
|
|
17797
|
+
parent.postMessage({ type: '${IFRAME_STATE_MESSAGE}', state: nextState }, '*');
|
|
17798
|
+
},
|
|
17799
|
+
};
|
|
17800
|
+
globalThis.addEventListener('message', event => {
|
|
17801
|
+
if (event.data?.type === '${IFRAME_PARENT_STATE_MESSAGE}' && event.data.state && typeof event.data.state === 'object') {
|
|
17802
|
+
kritzel.state = event.data.state;
|
|
17803
|
+
globalThis.dispatchEvent(new CustomEvent('kritzelstatechange', { detail: kritzel.state }));
|
|
17804
|
+
}
|
|
17805
|
+
});
|
|
17806
|
+
let bridgedPointerId = null;
|
|
17807
|
+
const interactiveSelector = 'button, input, textarea, select, a[href], [contenteditable="true"], [contenteditable=""]';
|
|
17808
|
+
const bridgePointerEvent = event => parent.postMessage({
|
|
17809
|
+
type: '${IFRAME_POINTER_MESSAGE}',
|
|
17810
|
+
eventType: event.type,
|
|
17811
|
+
pointerId: event.pointerId,
|
|
17812
|
+
pointerType: event.pointerType,
|
|
17813
|
+
clientX: event.clientX,
|
|
17814
|
+
clientY: event.clientY,
|
|
17815
|
+
screenX: event.screenX,
|
|
17816
|
+
screenY: event.screenY,
|
|
17817
|
+
button: event.button,
|
|
17818
|
+
buttons: event.buttons,
|
|
17819
|
+
shiftKey: event.shiftKey,
|
|
17820
|
+
ctrlKey: event.ctrlKey,
|
|
17821
|
+
altKey: event.altKey,
|
|
17822
|
+
metaKey: event.metaKey,
|
|
17823
|
+
}, '*');
|
|
17824
|
+
document.addEventListener('pointerdown', event => {
|
|
17825
|
+
if (event.target instanceof Element && event.target.closest(interactiveSelector)) return;
|
|
17826
|
+
bridgedPointerId = event.pointerId;
|
|
17827
|
+
event.preventDefault();
|
|
17828
|
+
bridgePointerEvent(event);
|
|
17829
|
+
});
|
|
17830
|
+
document.addEventListener('pointermove', event => {
|
|
17831
|
+
if (event.pointerId !== bridgedPointerId) return;
|
|
17832
|
+
event.preventDefault();
|
|
17833
|
+
bridgePointerEvent(event);
|
|
17834
|
+
});
|
|
17835
|
+
const finishPointerBridge = event => {
|
|
17836
|
+
if (event.pointerId !== bridgedPointerId) return;
|
|
17837
|
+
event.preventDefault();
|
|
17838
|
+
bridgePointerEvent(event);
|
|
17839
|
+
bridgedPointerId = null;
|
|
17840
|
+
};
|
|
17841
|
+
document.addEventListener('pointerup', finishPointerBridge);
|
|
17842
|
+
document.addEventListener('pointercancel', finishPointerBridge);
|
|
17843
|
+
document.addEventListener('contextmenu', event => {
|
|
17844
|
+
event.preventDefault();
|
|
17845
|
+
parent.postMessage({
|
|
17846
|
+
type: '${IFRAME_CONTEXT_MENU_MESSAGE}',
|
|
17847
|
+
clientX: event.clientX,
|
|
17848
|
+
clientY: event.clientY,
|
|
17849
|
+
button: event.button,
|
|
17850
|
+
shiftKey: event.shiftKey,
|
|
17851
|
+
ctrlKey: event.ctrlKey,
|
|
17852
|
+
altKey: event.altKey,
|
|
17853
|
+
metaKey: event.metaKey,
|
|
17854
|
+
}, '*');
|
|
17855
|
+
});
|
|
17856
|
+
${script}
|
|
17857
|
+
<\/script>
|
|
17858
|
+
</body>
|
|
17859
|
+
</html>`;
|
|
17860
|
+
}
|
|
17861
|
+
handleMessage(event) {
|
|
17862
|
+
if (event.source !== this.elementRef?.contentWindow || !event.data || typeof event.data !== 'object') {
|
|
17863
|
+
return;
|
|
17864
|
+
}
|
|
17865
|
+
const message = event.data;
|
|
17866
|
+
if (message.type === IFRAME_POINTER_MESSAGE) {
|
|
17867
|
+
this.dispatchPointerMessage(event.data);
|
|
17868
|
+
return;
|
|
17869
|
+
}
|
|
17870
|
+
if (message.type === IFRAME_CONTEXT_MENU_MESSAGE) {
|
|
17871
|
+
this.dispatchContextMenuMessage(event.data);
|
|
17872
|
+
return;
|
|
17873
|
+
}
|
|
17874
|
+
if (message.type !== IFRAME_STATE_MESSAGE || !message.state || typeof message.state !== 'object') {
|
|
17875
|
+
return;
|
|
17876
|
+
}
|
|
17877
|
+
this.state = structuredClone(message.state);
|
|
17878
|
+
this.persistUpdate();
|
|
17879
|
+
}
|
|
17880
|
+
dispatchPointerMessage(message) {
|
|
17881
|
+
if (!this.isMounted || !this.elementRef || !['pointerdown', 'pointermove', 'pointerup', 'pointercancel'].includes(message.eventType)) {
|
|
17882
|
+
return;
|
|
17883
|
+
}
|
|
17884
|
+
const iframeRect = this.elementRef.getBoundingClientRect();
|
|
17885
|
+
if (message.eventType === 'pointerdown') {
|
|
17886
|
+
const scaleX = this.elementRef.offsetWidth > 0 ? iframeRect.width / this.elementRef.offsetWidth : 1;
|
|
17887
|
+
const scaleY = this.elementRef.offsetHeight > 0 ? iframeRect.height / this.elementRef.offsetHeight : 1;
|
|
17888
|
+
iframePointerBridgeStarts.set(this.elementRef, {
|
|
17889
|
+
pointerId: message.pointerId,
|
|
17890
|
+
clientX: iframeRect.left + message.clientX * scaleX,
|
|
17891
|
+
clientY: iframeRect.top + message.clientY * scaleY,
|
|
17892
|
+
screenX: message.screenX,
|
|
17893
|
+
screenY: message.screenY,
|
|
17894
|
+
});
|
|
17895
|
+
}
|
|
17896
|
+
const bridgeStart = iframePointerBridgeStarts.get(this.elementRef);
|
|
17897
|
+
const hasBridgeStart = bridgeStart?.pointerId === message.pointerId;
|
|
17898
|
+
const clientX = hasBridgeStart ? bridgeStart.clientX + message.screenX - bridgeStart.screenX : iframeRect.left + message.clientX;
|
|
17899
|
+
const clientY = hasBridgeStart ? bridgeStart.clientY + message.screenY - bridgeStart.screenY : iframeRect.top + message.clientY;
|
|
17900
|
+
this.elementRef.dispatchEvent(new PointerEvent(message.eventType, {
|
|
17901
|
+
bubbles: true,
|
|
17902
|
+
composed: true,
|
|
17903
|
+
cancelable: true,
|
|
17904
|
+
pointerId: message.pointerId,
|
|
17905
|
+
pointerType: message.pointerType,
|
|
17906
|
+
clientX,
|
|
17907
|
+
clientY,
|
|
17908
|
+
screenX: message.screenX,
|
|
17909
|
+
screenY: message.screenY,
|
|
17910
|
+
button: message.button,
|
|
17911
|
+
buttons: message.buttons,
|
|
17912
|
+
shiftKey: message.shiftKey,
|
|
17913
|
+
ctrlKey: message.ctrlKey,
|
|
17914
|
+
altKey: message.altKey,
|
|
17915
|
+
metaKey: message.metaKey,
|
|
17916
|
+
}));
|
|
17917
|
+
if (message.eventType === 'pointerup' || message.eventType === 'pointercancel') {
|
|
17918
|
+
iframePointerBridgeStarts.delete(this.elementRef);
|
|
17919
|
+
}
|
|
17920
|
+
}
|
|
17921
|
+
dispatchContextMenuMessage(message) {
|
|
17922
|
+
if (!this.isMounted || !this.elementRef) {
|
|
17923
|
+
return;
|
|
17924
|
+
}
|
|
17925
|
+
const iframeRect = this.elementRef.getBoundingClientRect();
|
|
17926
|
+
// Dispatched as a MouseEvent (not PointerEvent) to mirror how browsers
|
|
17927
|
+
// natively raise 'contextmenu' for both mouse right-click and touch long-press.
|
|
17928
|
+
this.elementRef.dispatchEvent(new MouseEvent('contextmenu', {
|
|
17929
|
+
bubbles: true,
|
|
17930
|
+
composed: true,
|
|
17931
|
+
cancelable: true,
|
|
17932
|
+
clientX: iframeRect.left + message.clientX,
|
|
17933
|
+
clientY: iframeRect.top + message.clientY,
|
|
17934
|
+
button: message.button,
|
|
17935
|
+
shiftKey: message.shiftKey,
|
|
17936
|
+
ctrlKey: message.ctrlKey,
|
|
17937
|
+
altKey: message.altKey,
|
|
17938
|
+
metaKey: message.metaKey,
|
|
17939
|
+
}));
|
|
17940
|
+
}
|
|
17941
|
+
refreshDocument() {
|
|
17942
|
+
if (this.isMounted && this.elementRef) {
|
|
17943
|
+
this.elementRef.srcdoc = this.createSourceDocument();
|
|
17944
|
+
}
|
|
17945
|
+
}
|
|
17946
|
+
persistUpdate() {
|
|
17947
|
+
if (this._core?.store?.objects) {
|
|
17948
|
+
this.update();
|
|
17949
|
+
}
|
|
17950
|
+
}
|
|
17951
|
+
}
|
|
17952
|
+
|
|
17494
17953
|
/**
|
|
17495
17954
|
* Represents a selection group that manages multiple selected objects on the canvas.
|
|
17496
17955
|
* The selection group allows batch operations like move, resize, and rotate on multiple objects simultaneously.
|
|
@@ -19631,7 +20090,7 @@ class KritzelCursorHelper {
|
|
|
19631
20090
|
* The icon is retrieved from the KritzelIconRegistry.
|
|
19632
20091
|
*/
|
|
19633
20092
|
static getCursor(options) {
|
|
19634
|
-
const iconName = options.iconName === 'default' ? '
|
|
20093
|
+
const iconName = options.iconName === 'default' ? 'mousePointer' : options.iconName;
|
|
19635
20094
|
const iconSvg = KritzelIconRegistry.get(iconName);
|
|
19636
20095
|
if (!iconSvg) {
|
|
19637
20096
|
console.warn(`Icon "${iconName}" not found in registry.`);
|
|
@@ -19640,7 +20099,7 @@ class KritzelCursorHelper {
|
|
|
19640
20099
|
const size = options.size || 24;
|
|
19641
20100
|
const rotation = options.rotation || 0;
|
|
19642
20101
|
const color = options.color || 'black';
|
|
19643
|
-
// Default cursor (
|
|
20102
|
+
// Default cursor (mousePointer) has hotspot at (4, 4), others at center
|
|
19644
20103
|
const hotspot = options.hotspot || (options.iconName === 'default' ? { x: 4, y: 4 } : { x: size / 2, y: size / 2 });
|
|
19645
20104
|
// Modify the SVG string to set size and color
|
|
19646
20105
|
// We replace width and height to match the requested size
|
|
@@ -19653,12 +20112,12 @@ class KritzelCursorHelper {
|
|
|
19653
20112
|
// We rotate around the center of the SVG canvas
|
|
19654
20113
|
const center = size / 2;
|
|
19655
20114
|
// We use a group to apply the rotation
|
|
19656
|
-
const svg = `
|
|
19657
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
19658
|
-
<g transform="rotate(${rotation} ${center} ${center})">
|
|
19659
|
-
${content}
|
|
19660
|
-
</g>
|
|
19661
|
-
</svg>
|
|
20115
|
+
const svg = `
|
|
20116
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${size} ${size}">
|
|
20117
|
+
<g transform="rotate(${rotation} ${center} ${center})">
|
|
20118
|
+
${content}
|
|
20119
|
+
</g>
|
|
20120
|
+
</svg>
|
|
19662
20121
|
`;
|
|
19663
20122
|
// Encode the SVG for use in a data URI
|
|
19664
20123
|
// We need to be careful with encoding to ensure it works across browsers
|
|
@@ -21874,9 +22333,8 @@ class KritzelSelectionTool extends KritzelBaseTool {
|
|
|
21874
22333
|
}
|
|
21875
22334
|
if (selectedObject && selectedObject.isSelected === false && selectedObject?.objects.length === 1) {
|
|
21876
22335
|
const firstObj = selectedObject.objects[0];
|
|
21877
|
-
if (
|
|
21878
|
-
// Selected
|
|
21879
|
-
// embedded DOM content. Unselected dynamic objects remain selectable.
|
|
22336
|
+
if (ObjectHelper.isKritzelEmbeddedObject(firstObj)) {
|
|
22337
|
+
// Selected embedded objects hand pointer interaction to their content.
|
|
21880
22338
|
if (firstObj.isSelected && this._core.store.selectionGroup?.objects.length === 1)
|
|
21881
22339
|
return;
|
|
21882
22340
|
}
|
|
@@ -43322,6 +43780,9 @@ class KritzelReviver {
|
|
|
43322
43780
|
case 'KritzelDynamicObject':
|
|
43323
43781
|
revivedObj = KritzelDynamicObject.create(this._core).deserialize(obj);
|
|
43324
43782
|
break;
|
|
43783
|
+
case 'KritzelIframeObject':
|
|
43784
|
+
revivedObj = KritzelIframeObject.create(this._core).deserialize(obj);
|
|
43785
|
+
break;
|
|
43325
43786
|
case 'KritzelSelectionGroup':
|
|
43326
43787
|
revivedObj = KritzelSelectionGroup.create(this._core).deserialize(obj);
|
|
43327
43788
|
break;
|
|
@@ -45146,9 +45607,16 @@ class KritzelStore {
|
|
|
45146
45607
|
* Gets the currently selected dynamic object whose focused descendant is an input-like element.
|
|
45147
45608
|
* @returns The interactive dynamic object with focused input-like content, or null if none matches
|
|
45148
45609
|
*/
|
|
45610
|
+
get activeInteractiveEmbeddedObject() {
|
|
45611
|
+
for (const object of this.selectedObjects) {
|
|
45612
|
+
if (ObjectHelper.isKritzelEmbeddedObject(object) && object.hasFocusedInputElement()) {
|
|
45613
|
+
return object;
|
|
45614
|
+
}
|
|
45615
|
+
}
|
|
45616
|
+
return null;
|
|
45617
|
+
}
|
|
45149
45618
|
get activeInteractiveDynamicObject() {
|
|
45150
|
-
|
|
45151
|
-
return interactiveDynamicObject ?? null;
|
|
45619
|
+
return this.activeInteractiveEmbeddedObject;
|
|
45152
45620
|
}
|
|
45153
45621
|
/**
|
|
45154
45622
|
* Gets the path currently being drawn (not yet completed).
|
|
@@ -45736,11 +46204,13 @@ class KritzelCursorManager {
|
|
|
45736
46204
|
// Reset cursor on old target
|
|
45737
46205
|
if (this._targetElement) {
|
|
45738
46206
|
this._targetElement.style.cursor = '';
|
|
46207
|
+
this._targetElement.style.removeProperty('--kritzel-global-default-cursor');
|
|
45739
46208
|
this._targetElement.style.removeProperty('--kritzel-global-pointer-cursor');
|
|
45740
46209
|
}
|
|
45741
46210
|
this._targetElement = element;
|
|
45742
46211
|
// Set the pointer cursor CSS variable for child components to use
|
|
45743
46212
|
if (this._targetElement) {
|
|
46213
|
+
this._targetElement.style.setProperty('--kritzel-global-default-cursor', KritzelCursorHelper.getCursor({ iconName: 'default' }));
|
|
45744
46214
|
this._targetElement.style.setProperty('--kritzel-global-pointer-cursor', KritzelCursorHelper.getPointerCursor());
|
|
45745
46215
|
}
|
|
45746
46216
|
}
|
|
@@ -45785,8 +46255,10 @@ class KritzelCursorManager {
|
|
|
45785
46255
|
if (!this._shadowRoot)
|
|
45786
46256
|
return;
|
|
45787
46257
|
const elementsAtPoint = this._shadowRoot.elementsFromPoint(ev.clientX, ev.clientY);
|
|
45788
|
-
if (!elementsAtPoint || elementsAtPoint.length === 0)
|
|
46258
|
+
if (!elementsAtPoint || elementsAtPoint.length === 0) {
|
|
46259
|
+
this.resetToDefault();
|
|
45789
46260
|
return;
|
|
46261
|
+
}
|
|
45790
46262
|
// Check for resize handle overlays (selection group)
|
|
45791
46263
|
const resizeHandleOverlay = elementsAtPoint.find(el => el.classList.contains('resize-handle-overlay'));
|
|
45792
46264
|
if (resizeHandleOverlay) {
|
|
@@ -45796,19 +46268,19 @@ class KritzelCursorManager {
|
|
|
45796
46268
|
const isTopLeft = resizeHandleOverlay.classList.contains('top-left');
|
|
45797
46269
|
const isBottomRight = resizeHandleOverlay.classList.contains('bottom-right');
|
|
45798
46270
|
const rotationOffset = (isTopLeft || isBottomRight) ? -45 : 45;
|
|
45799
|
-
this._core.store.state.cursor = { icon: '
|
|
46271
|
+
this._core.store.state.cursor = { icon: 'moveVertical', rotation: rotationDegrees + rotationOffset };
|
|
45800
46272
|
return;
|
|
45801
46273
|
}
|
|
45802
46274
|
// Check for rotation handle overlay
|
|
45803
46275
|
const rotationHandleOverlay = elementsAtPoint.find(el => el.classList.contains('rotation-handle-overlay'));
|
|
45804
46276
|
if (rotationHandleOverlay) {
|
|
45805
|
-
this._core.store.state.cursor = { icon: 'hand', iconActive: '
|
|
46277
|
+
this._core.store.state.cursor = { icon: 'hand', iconActive: 'handGrab' };
|
|
45806
46278
|
return;
|
|
45807
46279
|
}
|
|
45808
46280
|
// Check for line handle overlays (selection line)
|
|
45809
46281
|
const lineHandleOverlay = elementsAtPoint.find(el => el.classList.contains('selection-line-handle-overlay'));
|
|
45810
46282
|
if (lineHandleOverlay) {
|
|
45811
|
-
this._core.store.state.cursor = { icon: 'hand', iconActive: '
|
|
46283
|
+
this._core.store.state.cursor = { icon: 'hand', iconActive: 'handGrab' };
|
|
45812
46284
|
return;
|
|
45813
46285
|
}
|
|
45814
46286
|
// Reset cursor if not hovering any handle
|
|
@@ -45843,7 +46315,8 @@ class KritzelCursorManager {
|
|
|
45843
46315
|
cleanup() {
|
|
45844
46316
|
if (this._targetElement) {
|
|
45845
46317
|
this._targetElement.style.cursor = '';
|
|
45846
|
-
this._targetElement.style.removeProperty('--kritzel-
|
|
46318
|
+
this._targetElement.style.removeProperty('--kritzel-global-default-cursor');
|
|
46319
|
+
this._targetElement.style.removeProperty('--kritzel-global-pointer-cursor');
|
|
45847
46320
|
}
|
|
45848
46321
|
this._targetElement = null;
|
|
45849
46322
|
this._shadowRoot = null;
|
|
@@ -46768,7 +47241,7 @@ class KritzelCore {
|
|
|
46768
47241
|
this._store.state.translateY = viewportHeight / 2 - (viewport.centerWorldY ?? 0) * scale;
|
|
46769
47242
|
this._store.state.scale = scale;
|
|
46770
47243
|
await objectsMap.initialize(this, activeWorkspace.id, this._syncConfig);
|
|
46771
|
-
this.seedWorkspaceObjects(activeWorkspace, objectsMap);
|
|
47244
|
+
await this.seedWorkspaceObjects(activeWorkspace, objectsMap);
|
|
46772
47245
|
// Set local user in awareness after object map is initialized
|
|
46773
47246
|
if (this._user) {
|
|
46774
47247
|
objectsMap.setLocalUser(this._user);
|
|
@@ -46782,15 +47255,21 @@ class KritzelCore {
|
|
|
46782
47255
|
this.engine.emitObjectsChange();
|
|
46783
47256
|
this.rerender();
|
|
46784
47257
|
}
|
|
46785
|
-
seedWorkspaceObjects(workspace, objectsMap) {
|
|
47258
|
+
async seedWorkspaceObjects(workspace, objectsMap) {
|
|
46786
47259
|
if (!workspace.objects?.length) {
|
|
46787
47260
|
return;
|
|
46788
47261
|
}
|
|
47262
|
+
const pendingObjects = workspace.objects.filter(object => !objectsMap.findById(object.id));
|
|
47263
|
+
// Mirrors engine.addObject()/addObjects(): image asset upload is async and must
|
|
47264
|
+
// happen before the (synchronous) Yjs transaction that inserts the objects.
|
|
47265
|
+
for (const object of pendingObjects) {
|
|
47266
|
+
object._core = this;
|
|
47267
|
+
if (KritzelClassHelper.isInstanceOf(object, 'KritzelImage')) {
|
|
47268
|
+
await object.prepareForInsert();
|
|
47269
|
+
}
|
|
47270
|
+
}
|
|
46789
47271
|
objectsMap.transaction(() => {
|
|
46790
|
-
for (const object of
|
|
46791
|
-
if (objectsMap.findById(object.id)) {
|
|
46792
|
-
continue;
|
|
46793
|
-
}
|
|
47272
|
+
for (const object of pendingObjects) {
|
|
46794
47273
|
this.prepareObjectForWorkspace(object, workspace.id, this._store.currentZIndex, this._store.state.scale);
|
|
46795
47274
|
objectsMap.insert(object);
|
|
46796
47275
|
}
|
|
@@ -46829,16 +47308,30 @@ class KritzelCore {
|
|
|
46829
47308
|
* @param scaleFallback - Scale applied to objects that do not define one
|
|
46830
47309
|
* @returns The objects that were added, updated and removed
|
|
46831
47310
|
*/
|
|
46832
|
-
reconcileWorkspaceObjects(objectsMap, workspaceId, desiredObjects, nextZIndex, scaleFallback) {
|
|
47311
|
+
async reconcileWorkspaceObjects(objectsMap, workspaceId, desiredObjects, nextZIndex, scaleFallback) {
|
|
46833
47312
|
const existingObjects = objectsMap.allObjects().filter(o => !(o instanceof KritzelSelectionGroup) && !(o instanceof KritzelSelectionBox));
|
|
46834
47313
|
const existingById = new Map(existingObjects.map(object => [object.id, object]));
|
|
46835
47314
|
const desiredIds = new Set();
|
|
46836
47315
|
const diff = { added: [], updated: [], removed: [] };
|
|
47316
|
+
// Assign IDs up front so the insert-vs-update lookup below is stable, and so the
|
|
47317
|
+
// async image-prepare pass and the (synchronous) transaction agree on identity.
|
|
47318
|
+
for (const object of desiredObjects) {
|
|
47319
|
+
if (!object.id) {
|
|
47320
|
+
object.id = object.generateId();
|
|
47321
|
+
}
|
|
47322
|
+
}
|
|
47323
|
+
// Mirrors engine.addObject()/addObjects(): image asset upload is async and must
|
|
47324
|
+
// happen before the (synchronous) Yjs transaction that inserts the objects.
|
|
47325
|
+
for (const object of desiredObjects) {
|
|
47326
|
+
const existingObject = existingById.get(object.id);
|
|
47327
|
+
const isNewOrReplaced = !existingObject || existingObject !== object;
|
|
47328
|
+
if (isNewOrReplaced && KritzelClassHelper.isInstanceOf(object, 'KritzelImage')) {
|
|
47329
|
+
object._core = this;
|
|
47330
|
+
await object.prepareForInsert();
|
|
47331
|
+
}
|
|
47332
|
+
}
|
|
46837
47333
|
objectsMap.transaction(() => {
|
|
46838
47334
|
for (const object of desiredObjects) {
|
|
46839
|
-
if (!object.id) {
|
|
46840
|
-
object.id = object.generateId();
|
|
46841
|
-
}
|
|
46842
47335
|
desiredIds.add(object.id);
|
|
46843
47336
|
const existingObject = existingById.get(object.id);
|
|
46844
47337
|
if (!existingObject) {
|
|
@@ -46876,7 +47369,7 @@ class KritzelCore {
|
|
|
46876
47369
|
* object set stays exactly what the caller declared.
|
|
46877
47370
|
*/
|
|
46878
47371
|
detachObject(object) {
|
|
46879
|
-
if (
|
|
47372
|
+
if (ObjectHelper.isKritzelEmbeddedObject(object)) {
|
|
46880
47373
|
object.unmount();
|
|
46881
47374
|
}
|
|
46882
47375
|
object.isMounted = false;
|
|
@@ -47052,13 +47545,13 @@ class KritzelCore {
|
|
|
47052
47545
|
activeWorkspace.viewport = { centerWorldX, centerWorldY, scale };
|
|
47053
47546
|
}
|
|
47054
47547
|
}
|
|
47055
|
-
applyObjectsToActiveWorkspace(workspace, desiredObjects) {
|
|
47548
|
+
async applyObjectsToActiveWorkspace(workspace, desiredObjects) {
|
|
47056
47549
|
const objectsMap = this._store.objects;
|
|
47057
47550
|
if (!objectsMap) {
|
|
47058
47551
|
return null;
|
|
47059
47552
|
}
|
|
47060
47553
|
this.clearSelection();
|
|
47061
|
-
const diff = this.reconcileWorkspaceObjects(objectsMap, workspace.id, desiredObjects, () => this._store.currentZIndex, this._store.state.scale);
|
|
47554
|
+
const diff = await this.reconcileWorkspaceObjects(objectsMap, workspace.id, desiredObjects, () => this._store.currentZIndex, this._store.state.scale);
|
|
47062
47555
|
this._anchorManager.rebuildIndex();
|
|
47063
47556
|
this.rerender();
|
|
47064
47557
|
return diff;
|
|
@@ -47077,7 +47570,7 @@ class KritzelCore {
|
|
|
47077
47570
|
try {
|
|
47078
47571
|
await objectsMap.initialize(this, workspace.id, this._syncConfig, { headless: true, workspaceName: workspace.name });
|
|
47079
47572
|
await objectsMap.whenNetworkSynced();
|
|
47080
|
-
return this.reconcileWorkspaceObjects(objectsMap, workspace.id, desiredObjects, () => this.nextZIndexOf(objectsMap), this._store.state.scale);
|
|
47573
|
+
return await this.reconcileWorkspaceObjects(objectsMap, workspace.id, desiredObjects, () => this.nextZIndexOf(objectsMap), this._store.state.scale);
|
|
47081
47574
|
}
|
|
47082
47575
|
finally {
|
|
47083
47576
|
objectsMap.destroy();
|
|
@@ -47163,8 +47656,7 @@ class KritzelCore {
|
|
|
47163
47656
|
this.removeObject(child);
|
|
47164
47657
|
});
|
|
47165
47658
|
}
|
|
47166
|
-
|
|
47167
|
-
if (KritzelClassHelper.isInstanceOf(object, 'KritzelDynamicObject')) {
|
|
47659
|
+
if (ObjectHelper.isKritzelEmbeddedObject(object)) {
|
|
47168
47660
|
object.unmount();
|
|
47169
47661
|
}
|
|
47170
47662
|
// Handle anchor cleanup
|
|
@@ -47210,14 +47702,8 @@ class KritzelCore {
|
|
|
47210
47702
|
this.removeLocalSelectionGroups();
|
|
47211
47703
|
this.removeSelectionBox();
|
|
47212
47704
|
for (const object of selectionGroup.objects ?? []) {
|
|
47213
|
-
if (
|
|
47214
|
-
|
|
47215
|
-
if (typeof dynamicObject.setIsInteractive === 'function') {
|
|
47216
|
-
dynamicObject.setIsInteractive(true);
|
|
47217
|
-
}
|
|
47218
|
-
else {
|
|
47219
|
-
dynamicObject.isInteractive = true;
|
|
47220
|
-
}
|
|
47705
|
+
if (ObjectHelper.isKritzelEmbeddedObject(object)) {
|
|
47706
|
+
object.setIsInteractive(true);
|
|
47221
47707
|
}
|
|
47222
47708
|
}
|
|
47223
47709
|
this._store.objects.insert(selectionGroup);
|
|
@@ -47238,14 +47724,8 @@ class KritzelCore {
|
|
|
47238
47724
|
teardownSelectionGroup(selectionGroup) {
|
|
47239
47725
|
selectionGroup.deselectAllChildren?.();
|
|
47240
47726
|
for (const object of selectionGroup.objects ?? []) {
|
|
47241
|
-
if (
|
|
47242
|
-
|
|
47243
|
-
if (typeof dynamicObject.setIsInteractive === 'function') {
|
|
47244
|
-
dynamicObject.setIsInteractive(false);
|
|
47245
|
-
}
|
|
47246
|
-
else {
|
|
47247
|
-
dynamicObject.isInteractive = false;
|
|
47248
|
-
}
|
|
47727
|
+
if (ObjectHelper.isKritzelEmbeddedObject(object)) {
|
|
47728
|
+
object.setIsInteractive(false);
|
|
47249
47729
|
}
|
|
47250
47730
|
}
|
|
47251
47731
|
}
|
|
@@ -48691,13 +49171,7 @@ class KritzelWheelHelper {
|
|
|
48691
49171
|
return this.canElementConsumeWheel(scrollContainer, ev.deltaX, ev.deltaY);
|
|
48692
49172
|
}
|
|
48693
49173
|
static getScrollableContainerFromEventPath(path, dynamicObject) {
|
|
48694
|
-
const potentialRoots =
|
|
48695
|
-
if (dynamicObject.element instanceof HTMLElement) {
|
|
48696
|
-
potentialRoots.push(dynamicObject.element);
|
|
48697
|
-
}
|
|
48698
|
-
if (dynamicObject.elementRef instanceof HTMLElement) {
|
|
48699
|
-
potentialRoots.push(dynamicObject.elementRef);
|
|
48700
|
-
}
|
|
49174
|
+
const potentialRoots = dynamicObject.getEmbeddedContentRoots();
|
|
48701
49175
|
const legacyElementRef = dynamicObject.elmeentRef;
|
|
48702
49176
|
if (legacyElementRef instanceof HTMLElement) {
|
|
48703
49177
|
potentialRoots.push(legacyElementRef);
|
|
@@ -48855,8 +49329,8 @@ class KritzelSvgExportHelper {
|
|
|
48855
49329
|
.join('\n ');
|
|
48856
49330
|
const xmlDecl = includeXmlDeclaration ? '<?xml version="1.0" encoding="UTF-8"?>\n' : '';
|
|
48857
49331
|
const defsContent = defs.length > 0 ? `\n <defs>\n ${defs.join('\n ')}\n </defs>` : '';
|
|
48858
|
-
return `${xmlDecl}<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}" width="${viewBoxWidth}" height="${viewBoxHeight}">${defsContent}
|
|
48859
|
-
${elements}
|
|
49332
|
+
return `${xmlDecl}<svg xmlns="http://www.w3.org/2000/svg" viewBox="${viewBoxX} ${viewBoxY} ${viewBoxWidth} ${viewBoxHeight}" width="${viewBoxWidth}" height="${viewBoxHeight}">${defsContent}
|
|
49333
|
+
${elements}
|
|
48860
49334
|
</svg>`;
|
|
48861
49335
|
}
|
|
48862
49336
|
/**
|
|
@@ -49008,8 +49482,8 @@ class KritzelSvgExportHelper {
|
|
|
49008
49482
|
const orient = end === 'start' ? 'auto-start-reverse' : 'auto';
|
|
49009
49483
|
const refX = 0;
|
|
49010
49484
|
const refY = size / 2;
|
|
49011
|
-
return `<marker id="${markerId}" markerWidth="${size}" markerHeight="${size}" refX="${refX}" refY="${refY}" orient="${orient}" markerUnits="userSpaceOnUse">
|
|
49012
|
-
<path d="${path}" fill="${fill}" transform="scale(${size / 10})"/>
|
|
49485
|
+
return `<marker id="${markerId}" markerWidth="${size}" markerHeight="${size}" refX="${refX}" refY="${refY}" orient="${orient}" markerUnits="userSpaceOnUse">
|
|
49486
|
+
<path d="${path}" fill="${fill}" transform="scale(${size / 10})"/>
|
|
49013
49487
|
</marker>`;
|
|
49014
49488
|
}
|
|
49015
49489
|
/**
|
|
@@ -49038,6 +49512,9 @@ class KritzelSvgExportHelper {
|
|
|
49038
49512
|
if (KritzelClassHelper.isInstanceOf(object, 'KritzelDynamicObject')) {
|
|
49039
49513
|
return this.dynamicObjectToSvg(object, rasterSafeForCanvas);
|
|
49040
49514
|
}
|
|
49515
|
+
if (KritzelClassHelper.isInstanceOf(object, 'KritzelIframeObject')) {
|
|
49516
|
+
return this.iframeObjectToSvg(object);
|
|
49517
|
+
}
|
|
49041
49518
|
if (KritzelClassHelper.isInstanceOf(object, 'KritzelGroup')) {
|
|
49042
49519
|
return this.groupToSvg(object, theme, imageDataUrls, rasterSafeForCanvas);
|
|
49043
49520
|
}
|
|
@@ -49056,10 +49533,10 @@ class KritzelSvgExportHelper {
|
|
|
49056
49533
|
const opacity = path.opacity !== 1 ? ` opacity="${path.opacity}"` : '';
|
|
49057
49534
|
const scale = this.getObjectScale(path);
|
|
49058
49535
|
// Path needs to be wrapped in a g with translation since path.d uses local coordinates
|
|
49059
|
-
return `<g transform="${transform}"${opacity}>
|
|
49060
|
-
<svg viewBox="${path.viewBox}" width="${path.totalWidth / scale}" height="${path.totalHeight / scale}" overflow="visible">
|
|
49061
|
-
<path d="${path.d}" fill="${fill || 'none'}" stroke="${stroke || 'none'}"${path.strokeWidth ? ` stroke-width="${path.strokeWidth}"` : ''}/>
|
|
49062
|
-
</svg>
|
|
49536
|
+
return `<g transform="${transform}"${opacity}>
|
|
49537
|
+
<svg viewBox="${path.viewBox}" width="${path.totalWidth / scale}" height="${path.totalHeight / scale}" overflow="visible">
|
|
49538
|
+
<path d="${path.d}" fill="${fill || 'none'}" stroke="${stroke || 'none'}"${path.strokeWidth ? ` stroke-width="${path.strokeWidth}"` : ''}/>
|
|
49539
|
+
</svg>
|
|
49063
49540
|
</g>`;
|
|
49064
49541
|
}
|
|
49065
49542
|
/**
|
|
@@ -49075,10 +49552,10 @@ class KritzelSvgExportHelper {
|
|
|
49075
49552
|
const scale = this.getObjectScale(line);
|
|
49076
49553
|
const markerStart = line.hasStartArrow ? ` marker-start="url(#${line.startMarkerId})"` : '';
|
|
49077
49554
|
const markerEnd = line.hasEndArrow ? ` marker-end="url(#${line.endMarkerId})"` : '';
|
|
49078
|
-
return `<g transform="${transform}"${opacity}>
|
|
49079
|
-
<svg viewBox="${line.viewBox}" width="${line.totalWidth / scale}" height="${line.totalHeight / scale}" overflow="visible">
|
|
49080
|
-
<path d="${line.d}" fill="none" stroke="${stroke}" stroke-width="${line.strokeWidth}" stroke-linecap="round"${markerStart}${markerEnd}/>
|
|
49081
|
-
</svg>
|
|
49555
|
+
return `<g transform="${transform}"${opacity}>
|
|
49556
|
+
<svg viewBox="${line.viewBox}" width="${line.totalWidth / scale}" height="${line.totalHeight / scale}" overflow="visible">
|
|
49557
|
+
<path d="${line.d}" fill="none" stroke="${stroke}" stroke-width="${line.strokeWidth}" stroke-linecap="round"${markerStart}${markerEnd}/>
|
|
49558
|
+
</svg>
|
|
49082
49559
|
</g>`;
|
|
49083
49560
|
}
|
|
49084
49561
|
/**
|
|
@@ -49102,18 +49579,18 @@ class KritzelSvgExportHelper {
|
|
|
49102
49579
|
const textHtml = this.prosemirrorToHtml(shape.content, shape, theme);
|
|
49103
49580
|
if (textHtml) {
|
|
49104
49581
|
const fontColor = KritzelColorHelper.resolveThemeColor(shape.fontColor, theme);
|
|
49105
|
-
textContent = `
|
|
49106
|
-
<foreignObject x="${shape.x}" y="${shape.y}" width="${shape.width}" height="${shape.height}">
|
|
49107
|
-
<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;">
|
|
49108
|
-
${textHtml}
|
|
49109
|
-
</div>
|
|
49582
|
+
textContent = `
|
|
49583
|
+
<foreignObject x="${shape.x}" y="${shape.y}" width="${shape.width}" height="${shape.height}">
|
|
49584
|
+
<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;">
|
|
49585
|
+
${textHtml}
|
|
49586
|
+
</div>
|
|
49110
49587
|
</foreignObject>`;
|
|
49111
49588
|
}
|
|
49112
49589
|
}
|
|
49113
|
-
return `<g transform="${transform}"${opacity}>
|
|
49114
|
-
<svg viewBox="${shape.viewBox}" width="${shape.totalWidth / scale}" height="${shape.totalHeight / scale}" overflow="visible" preserveAspectRatio="none">
|
|
49115
|
-
<path d="${pathD}" fill="${fill || 'transparent'}" stroke="${stroke}" stroke-width="${shape.strokeWidth}"/>${textContent}
|
|
49116
|
-
</svg>
|
|
49590
|
+
return `<g transform="${transform}"${opacity}>
|
|
49591
|
+
<svg viewBox="${shape.viewBox}" width="${shape.totalWidth / scale}" height="${shape.totalHeight / scale}" overflow="visible" preserveAspectRatio="none">
|
|
49592
|
+
<path d="${pathD}" fill="${fill || 'transparent'}" stroke="${stroke}" stroke-width="${shape.strokeWidth}"/>${textContent}
|
|
49593
|
+
</svg>
|
|
49117
49594
|
</g>`;
|
|
49118
49595
|
}
|
|
49119
49596
|
/**
|
|
@@ -49144,10 +49621,10 @@ class KritzelSvgExportHelper {
|
|
|
49144
49621
|
// adjusted font-size already accounts for it – keeping both would double-scale
|
|
49145
49622
|
// the content and overflow the foreignObject.
|
|
49146
49623
|
const svgFontSizePx = (text.fontSize * (4 / 3) * (text.scaleFactor || 1) / scale).toFixed(4);
|
|
49147
|
-
return `<g transform="${transform}"${opacity}>
|
|
49148
|
-
<foreignObject x="0" y="0" width="${width}" height="${height}" overflow="visible">
|
|
49149
|
-
<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>
|
|
49150
|
-
</foreignObject>
|
|
49624
|
+
return `<g transform="${transform}"${opacity}>
|
|
49625
|
+
<foreignObject x="0" y="0" width="${width}" height="${height}" overflow="visible">
|
|
49626
|
+
<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>
|
|
49627
|
+
</foreignObject>
|
|
49151
49628
|
</g>`;
|
|
49152
49629
|
}
|
|
49153
49630
|
/**
|
|
@@ -49181,9 +49658,9 @@ class KritzelSvgExportHelper {
|
|
|
49181
49658
|
return `<tspan x="0" y="${y}" xml:space="preserve">${this.escapeHtml(line)}</tspan>`;
|
|
49182
49659
|
})
|
|
49183
49660
|
.join('');
|
|
49184
|
-
return `<g transform="${transform}"${opacity}>
|
|
49185
|
-
${bgRect}
|
|
49186
|
-
<text font-family="${this.escapeHtml(text.fontFamily)}" font-size="${resolvedFontSizePx}" fill="${fontColor}">${tspans}</text>
|
|
49661
|
+
return `<g transform="${transform}"${opacity}>
|
|
49662
|
+
${bgRect}
|
|
49663
|
+
<text font-family="${this.escapeHtml(text.fontFamily)}" font-size="${resolvedFontSizePx}" fill="${fontColor}">${tspans}</text>
|
|
49187
49664
|
</g>`;
|
|
49188
49665
|
}
|
|
49189
49666
|
/**
|
|
@@ -49211,8 +49688,8 @@ class KritzelSvgExportHelper {
|
|
|
49211
49688
|
const width = image.totalWidth / scale;
|
|
49212
49689
|
const height = image.totalHeight / scale;
|
|
49213
49690
|
const href = imageDataUrls?.get(image.id) || image.resolvedSrc || image.src || '';
|
|
49214
|
-
return `<g transform="${transform}"${opacity}>
|
|
49215
|
-
<image href="${href}" x="0" y="0" width="${width}" height="${height}" preserveAspectRatio="xMidYMid meet"/>
|
|
49691
|
+
return `<g transform="${transform}"${opacity}>
|
|
49692
|
+
<image href="${href}" x="0" y="0" width="${width}" height="${height}" preserveAspectRatio="xMidYMid meet"/>
|
|
49216
49693
|
</g>`;
|
|
49217
49694
|
}
|
|
49218
49695
|
/**
|
|
@@ -49232,19 +49709,30 @@ class KritzelSvgExportHelper {
|
|
|
49232
49709
|
if (rasterSafeForCanvas) {
|
|
49233
49710
|
// PNG export: render placeholder rect (foreignObject doesn't rasterize to PNG well)
|
|
49234
49711
|
console.warn('[KritzelDynamicObject SVG Export] Dynamic objects do not serialize well to PNG. Use SVG export or screenshot instead.');
|
|
49235
|
-
return `<g transform="${transform}"${opacity}>
|
|
49236
|
-
<rect x="0" y="0" width="${width}" height="${height}" fill="#f0f0f0" stroke="#999" stroke-width="1" />
|
|
49237
|
-
<text x="${width / 2}" y="${height / 2}" text-anchor="middle" dominant-baseline="middle" font-size="12" fill="#999">[Dynamic Object]</text>
|
|
49712
|
+
return `<g transform="${transform}"${opacity}>
|
|
49713
|
+
<rect x="0" y="0" width="${width}" height="${height}" fill="#f0f0f0" stroke="#999" stroke-width="1" />
|
|
49714
|
+
<text x="${width / 2}" y="${height / 2}" text-anchor="middle" dominant-baseline="middle" font-size="12" fill="#999">[Dynamic Object]</text>
|
|
49238
49715
|
</g>`;
|
|
49239
49716
|
}
|
|
49240
49717
|
// SVG export: use foreignObject to embed HTML
|
|
49241
49718
|
const html = obj.element?.outerHTML || '<div style="border:1px dashed #ccc">Empty</div>';
|
|
49242
|
-
return `<g transform="${transform}"${opacity}>
|
|
49243
|
-
<foreignObject x="0" y="0" width="${width}" height="${height}">
|
|
49244
|
-
<div xmlns="http://www.w3.org/1999/xhtml" style="width:100%;height:100%;overflow:hidden;">
|
|
49245
|
-
${html}
|
|
49246
|
-
</div>
|
|
49247
|
-
</foreignObject>
|
|
49719
|
+
return `<g transform="${transform}"${opacity}>
|
|
49720
|
+
<foreignObject x="0" y="0" width="${width}" height="${height}">
|
|
49721
|
+
<div xmlns="http://www.w3.org/1999/xhtml" style="width:100%;height:100%;overflow:hidden;">
|
|
49722
|
+
${html}
|
|
49723
|
+
</div>
|
|
49724
|
+
</foreignObject>
|
|
49725
|
+
</g>`;
|
|
49726
|
+
}
|
|
49727
|
+
static iframeObjectToSvg(object) {
|
|
49728
|
+
const transform = this.buildTransform(object);
|
|
49729
|
+
const opacity = object.opacity !== 1 ? ` opacity="${object.opacity}"` : '';
|
|
49730
|
+
const scale = this.getObjectScale(object);
|
|
49731
|
+
const width = object.totalWidth / scale;
|
|
49732
|
+
const height = object.totalHeight / scale;
|
|
49733
|
+
return `<g transform="${transform}"${opacity}>
|
|
49734
|
+
<rect x="0" y="0" width="${width}" height="${height}" fill="#f0f0f0" stroke="#999" stroke-width="1" />
|
|
49735
|
+
<text x="${width / 2}" y="${height / 2}" text-anchor="middle" dominant-baseline="middle" font-size="12" fill="#999">[Iframe]</text>
|
|
49248
49736
|
</g>`;
|
|
49249
49737
|
}
|
|
49250
49738
|
/**
|
|
@@ -49264,8 +49752,8 @@ class KritzelSvgExportHelper {
|
|
|
49264
49752
|
return '';
|
|
49265
49753
|
}
|
|
49266
49754
|
const opacity = group.opacity !== 1 ? ` opacity="${group.opacity}"` : '';
|
|
49267
|
-
return `<g${opacity}>
|
|
49268
|
-
${children}
|
|
49755
|
+
return `<g${opacity}>
|
|
49756
|
+
${children}
|
|
49269
49757
|
</g>`;
|
|
49270
49758
|
}
|
|
49271
49759
|
/**
|
|
@@ -49450,12 +49938,26 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
49450
49938
|
/** Authoritative workspace catalog for this engine instance. When provided, provider-only workspaces are hidden but not deleted. */
|
|
49451
49939
|
workspaces;
|
|
49452
49940
|
async onWorkspacesPropChange() {
|
|
49453
|
-
|
|
49941
|
+
this._workspacesRevision++;
|
|
49942
|
+
if (!this._isYjsInitialized || this._syncInitPromise) {
|
|
49454
49943
|
return;
|
|
49455
49944
|
}
|
|
49456
|
-
|
|
49457
|
-
|
|
49458
|
-
|
|
49945
|
+
const previousReconciliation = this._workspacePropReconciliationPromise;
|
|
49946
|
+
const reconciliationPromise = (async () => {
|
|
49947
|
+
await previousReconciliation;
|
|
49948
|
+
await this.reconcileProvidedWorkspaces();
|
|
49949
|
+
await this.ensureActiveWorkspaceIsVisible();
|
|
49950
|
+
this.workspacesChange.emit(this.getVisibleWorkspaces());
|
|
49951
|
+
})();
|
|
49952
|
+
this._workspacePropReconciliationPromise = reconciliationPromise;
|
|
49953
|
+
try {
|
|
49954
|
+
await reconciliationPromise;
|
|
49955
|
+
}
|
|
49956
|
+
finally {
|
|
49957
|
+
if (this._workspacePropReconciliationPromise === reconciliationPromise) {
|
|
49958
|
+
this._workspacePropReconciliationPromise = null;
|
|
49959
|
+
}
|
|
49960
|
+
}
|
|
49459
49961
|
}
|
|
49460
49962
|
/** Optional unique identifier for namespacing storage keys across multiple editor instances. */
|
|
49461
49963
|
editorId;
|
|
@@ -49509,6 +50011,12 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
49509
50011
|
onUserChange(newValue) {
|
|
49510
50012
|
this.core.setUser(newValue);
|
|
49511
50013
|
}
|
|
50014
|
+
/** Tool definitions to register with this engine instance. */
|
|
50015
|
+
tools = [];
|
|
50016
|
+
onToolsChange() {
|
|
50017
|
+
this._toolsRevision++;
|
|
50018
|
+
void this.registerConfiguredTools();
|
|
50019
|
+
}
|
|
49512
50020
|
/** Context menu items shown when right-clicking the canvas background. */
|
|
49513
50021
|
globalContextMenuItems;
|
|
49514
50022
|
onGlobalContextMenuItemsChange(newValue) {
|
|
@@ -49699,7 +50207,7 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
49699
50207
|
}
|
|
49700
50208
|
const hoveredObject = this.core.getObjectFromPointerEvent(ev);
|
|
49701
50209
|
if (hoveredObject &&
|
|
49702
|
-
ObjectHelper.
|
|
50210
|
+
ObjectHelper.isKritzelEmbeddedObject(hoveredObject) &&
|
|
49703
50211
|
KritzelWheelHelper.shouldKeepWheelInDynamicObject(ev, hoveredObject)) {
|
|
49704
50212
|
return;
|
|
49705
50213
|
}
|
|
@@ -49801,7 +50309,7 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
49801
50309
|
return false;
|
|
49802
50310
|
}
|
|
49803
50311
|
const object = this.core.store.objects.findById(objectElement.id);
|
|
49804
|
-
if (!object || !
|
|
50312
|
+
if (!object || !ObjectHelper.isKritzelEmbeddedObject(object)) {
|
|
49805
50313
|
return false;
|
|
49806
50314
|
}
|
|
49807
50315
|
const isSelected = !!this.core.store.selectionGroup?.objects?.some(selectedObject => selectedObject.id === object.id);
|
|
@@ -49811,13 +50319,7 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
49811
50319
|
if (object.isInteractive !== true) {
|
|
49812
50320
|
return false;
|
|
49813
50321
|
}
|
|
49814
|
-
const potentialRoots =
|
|
49815
|
-
if (object.element instanceof H) {
|
|
49816
|
-
potentialRoots.push(object.element);
|
|
49817
|
-
}
|
|
49818
|
-
if (object.elementRef instanceof H) {
|
|
49819
|
-
potentialRoots.push(object.elementRef);
|
|
49820
|
-
}
|
|
50322
|
+
const potentialRoots = object.getEmbeddedContentRoots();
|
|
49821
50323
|
if (potentialRoots.length === 0) {
|
|
49822
50324
|
return false;
|
|
49823
50325
|
}
|
|
@@ -49991,7 +50493,7 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
49991
50493
|
* Switches the active drawing tool by its registered name.
|
|
49992
50494
|
* @param toolName - The name the tool was registered with (e.g., 'brush', 'eraser').
|
|
49993
50495
|
*/
|
|
49994
|
-
async
|
|
50496
|
+
async setActiveTool(toolName) {
|
|
49995
50497
|
const tool = this.core.toolRegistry.getTool(toolName);
|
|
49996
50498
|
if (!tool) {
|
|
49997
50499
|
console.warn(`[KritzelEngine] No tool registered with name: ${toolName}`);
|
|
@@ -51297,9 +51799,13 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
51297
51799
|
_stateChangeListenersRegistered = false;
|
|
51298
51800
|
_workspaceInitializationPromise = null;
|
|
51299
51801
|
_workspaceInitializationTargetKey = null;
|
|
51802
|
+
_workspacePropReconciliationPromise = null;
|
|
51300
51803
|
_syncInitPromise = null;
|
|
51804
|
+
_toolsInitPromise = null;
|
|
51805
|
+
_toolsRevision = 0;
|
|
51301
51806
|
_syncConfigRevision = 0;
|
|
51302
51807
|
_assetStorageConfigRevision = 0;
|
|
51808
|
+
_workspacesRevision = 0;
|
|
51303
51809
|
_hasLoggedUnlicensedWelcomeBanner = false;
|
|
51304
51810
|
_previousVisibleDynamicObjects = new Set();
|
|
51305
51811
|
_revealedImageKeys = new Set();
|
|
@@ -51312,6 +51818,37 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
51312
51818
|
undoStackSize: 0,
|
|
51313
51819
|
redoStackSize: 0,
|
|
51314
51820
|
};
|
|
51821
|
+
/** Returns a tool registered in this engine instance. */
|
|
51822
|
+
async getTool(toolName) {
|
|
51823
|
+
await this.registerConfiguredTools();
|
|
51824
|
+
return this.core.toolRegistry.getTool(toolName);
|
|
51825
|
+
}
|
|
51826
|
+
async registerConfiguredTools() {
|
|
51827
|
+
if (this._toolsInitPromise) {
|
|
51828
|
+
return this._toolsInitPromise;
|
|
51829
|
+
}
|
|
51830
|
+
this._toolsInitPromise = (async () => {
|
|
51831
|
+
do {
|
|
51832
|
+
const revision = this._toolsRevision;
|
|
51833
|
+
for (const definition of this.tools) {
|
|
51834
|
+
let toolClass = definition.tool;
|
|
51835
|
+
if (typeof toolClass !== 'function') {
|
|
51836
|
+
toolClass = toolClass.constructor;
|
|
51837
|
+
}
|
|
51838
|
+
await this.registerTool(definition.name, toolClass, definition.config);
|
|
51839
|
+
}
|
|
51840
|
+
if (revision === this._toolsRevision) {
|
|
51841
|
+
break;
|
|
51842
|
+
}
|
|
51843
|
+
} while (true);
|
|
51844
|
+
})();
|
|
51845
|
+
try {
|
|
51846
|
+
await this._toolsInitPromise;
|
|
51847
|
+
}
|
|
51848
|
+
finally {
|
|
51849
|
+
this._toolsInitPromise = null;
|
|
51850
|
+
}
|
|
51851
|
+
}
|
|
51315
51852
|
setLoadingState(isLoading) {
|
|
51316
51853
|
if (this.core.store.state.isLoading === isLoading) {
|
|
51317
51854
|
return;
|
|
@@ -51443,6 +51980,8 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
51443
51980
|
this.core.licenseManager.destroy();
|
|
51444
51981
|
}
|
|
51445
51982
|
componentWillLoad() {
|
|
51983
|
+
this._toolsRevision++;
|
|
51984
|
+
void this.registerConfiguredTools();
|
|
51446
51985
|
this.core.setEditorId(this.editorId);
|
|
51447
51986
|
if (this.themes && this.themes.length > 0) {
|
|
51448
51987
|
this.core.themeManager.registerThemes(this.themes);
|
|
@@ -51482,7 +52021,9 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
51482
52021
|
const editorElement = this.host.closest('kritzel-editor');
|
|
51483
52022
|
this.core.themeManager.setTargetElement(editorElement || this.host);
|
|
51484
52023
|
// Initialize sync config and Yjs
|
|
52024
|
+
await this.registerConfiguredTools();
|
|
51485
52025
|
await this.initializeSyncAndWorkspace();
|
|
52026
|
+
await this.waitForWorkspaceAndSceneReady();
|
|
51486
52027
|
if (this.core.store.state.isReady === false) {
|
|
51487
52028
|
this.core.store.state.isReady = true;
|
|
51488
52029
|
this.logUnlicensedWelcomeBanner();
|
|
@@ -51504,6 +52045,20 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
51504
52045
|
this._syncInitPromise = null;
|
|
51505
52046
|
}
|
|
51506
52047
|
}
|
|
52048
|
+
async waitForSceneRender() {
|
|
52049
|
+
await new Promise(resolve => {
|
|
52050
|
+
requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
|
|
52051
|
+
});
|
|
52052
|
+
}
|
|
52053
|
+
async waitForWorkspaceAndSceneReady() {
|
|
52054
|
+
let observedRevision;
|
|
52055
|
+
do {
|
|
52056
|
+
observedRevision = this._workspacesRevision;
|
|
52057
|
+
await this._workspacePropReconciliationPromise;
|
|
52058
|
+
await this.waitForSceneRender();
|
|
52059
|
+
} while (observedRevision !== this._workspacesRevision ||
|
|
52060
|
+
this._workspacePropReconciliationPromise);
|
|
52061
|
+
}
|
|
51507
52062
|
/**
|
|
51508
52063
|
* Initializes the asset storage layer with the latest config. Mirrors
|
|
51509
52064
|
* the in-flight replay logic of {@link doInitializeSyncAndWorkspace} for
|
|
@@ -51886,7 +52441,7 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
51886
52441
|
if (!KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup')) {
|
|
51887
52442
|
return 'auto';
|
|
51888
52443
|
}
|
|
51889
|
-
if (object.objects.length === 1 &&
|
|
52444
|
+
if (object.objects.length === 1 && ObjectHelper.isKritzelEmbeddedObject(object.objects[0])) {
|
|
51890
52445
|
return 'none';
|
|
51891
52446
|
}
|
|
51892
52447
|
return 'auto';
|
|
@@ -51894,7 +52449,7 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
51894
52449
|
// Track visible dynamic objects and unmount culled ones
|
|
51895
52450
|
const currentVisibleDynamicObjects = new Set();
|
|
51896
52451
|
visibleObjects.forEach(object => {
|
|
51897
|
-
if (
|
|
52452
|
+
if (ObjectHelper.isKritzelEmbeddedObject(object)) {
|
|
51898
52453
|
currentVisibleDynamicObjects.add(object.id);
|
|
51899
52454
|
}
|
|
51900
52455
|
});
|
|
@@ -51902,7 +52457,7 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
51902
52457
|
this._previousVisibleDynamicObjects.forEach(id => {
|
|
51903
52458
|
if (!currentVisibleDynamicObjects.has(id)) {
|
|
51904
52459
|
const object = this.core.store.objects.findById(id);
|
|
51905
|
-
if (object &&
|
|
52460
|
+
if (object && ObjectHelper.isKritzelEmbeddedObject(object)) {
|
|
51906
52461
|
object.unmount();
|
|
51907
52462
|
}
|
|
51908
52463
|
}
|
|
@@ -51995,7 +52550,7 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
51995
52550
|
display: 'flex',
|
|
51996
52551
|
alignItems: 'center',
|
|
51997
52552
|
justifyContent: 'center',
|
|
51998
|
-
} }, h("kritzel-icon", { name: object.loadState === 'error' ? '
|
|
52553
|
+
} }, h("kritzel-icon", { name: object.loadState === 'error' ? 'imageOff' : 'image', size: Math.max(16, Math.min(object.totalWidth, object.totalHeight) * 0.3), style: {
|
|
51999
52554
|
color: KritzelColorHelper.resolveThemeColor({ light: '#9ca3af', dark: '#6b7280' }, currentTheme),
|
|
52000
52555
|
} }))), KritzelClassHelper.isInstanceOf(object, 'KritzelDynamicObject') && (h("div", { ref: el => el && object.mount(el), style: {
|
|
52001
52556
|
position: 'absolute',
|
|
@@ -52014,7 +52569,37 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
52014
52569
|
padding: object.padding + 'px',
|
|
52015
52570
|
overflow: 'visible',
|
|
52016
52571
|
display: 'block',
|
|
52017
|
-
} })), KritzelClassHelper.isInstanceOf(object, '
|
|
52572
|
+
} })), KritzelClassHelper.isInstanceOf(object, 'KritzelIframeObject') && (h("div", { style: {
|
|
52573
|
+
position: 'absolute',
|
|
52574
|
+
left: '0',
|
|
52575
|
+
top: '0',
|
|
52576
|
+
width: object.totalWidth + 'px',
|
|
52577
|
+
height: object.totalHeight + 'px',
|
|
52578
|
+
transform: object.rotationDegrees !== 0 ? `rotate(${object.rotationDegrees}deg)` : undefined,
|
|
52579
|
+
transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
|
|
52580
|
+
opacity: effectiveOpacityString,
|
|
52581
|
+
backgroundColor: KritzelColorHelper.resolveThemeColor(object.backgroundColor, currentTheme),
|
|
52582
|
+
borderColor: KritzelColorHelper.resolveThemeColor(object.borderColor, currentTheme),
|
|
52583
|
+
borderWidth: object.borderWidth + 'px',
|
|
52584
|
+
borderStyle: 'solid',
|
|
52585
|
+
borderRadius: object.borderRadius !== undefined ? (typeof object.borderRadius === 'number' ? `${object.borderRadius}px` : object.borderRadius) : undefined,
|
|
52586
|
+
boxShadow: object.boxShadow,
|
|
52587
|
+
overflow: 'hidden',
|
|
52588
|
+
display: 'block',
|
|
52589
|
+
pointerEvents: object.markedForRemoval ? 'none' : 'auto',
|
|
52590
|
+
} }, h("iframe", { ref: element => element && object.mount(element), title: object.title, sandbox: object.sandboxAttribute, style: {
|
|
52591
|
+
display: 'block',
|
|
52592
|
+
width: '100%',
|
|
52593
|
+
height: '100%',
|
|
52594
|
+
border: '0',
|
|
52595
|
+
borderRadius: object.borderRadius !== undefined ? (typeof object.borderRadius === 'number' ? `${object.borderRadius}px` : object.borderRadius) : undefined,
|
|
52596
|
+
pointerEvents: object.isInteractive ? 'auto' : 'none',
|
|
52597
|
+
} }), h("div", { style: {
|
|
52598
|
+
position: 'absolute',
|
|
52599
|
+
inset: '0',
|
|
52600
|
+
borderRadius: object.borderRadius !== undefined ? (typeof object.borderRadius === 'number' ? `${object.borderRadius}px` : object.borderRadius) : undefined,
|
|
52601
|
+
pointerEvents: object.isInteractive ? 'none' : 'auto',
|
|
52602
|
+
} }))), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup') && !this.core.displaySelectionLineUI(object) && (h("div", { ref: el => el && object.mount(el), style: {
|
|
52018
52603
|
position: 'absolute',
|
|
52019
52604
|
left: '0',
|
|
52020
52605
|
top: '0',
|
|
@@ -52372,6 +52957,9 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
52372
52957
|
"user": [{
|
|
52373
52958
|
"onUserChange": 0
|
|
52374
52959
|
}],
|
|
52960
|
+
"tools": [{
|
|
52961
|
+
"onToolsChange": 0
|
|
52962
|
+
}],
|
|
52375
52963
|
"globalContextMenuItems": [{
|
|
52376
52964
|
"onGlobalContextMenuItemsChange": 0
|
|
52377
52965
|
}],
|
|
@@ -52432,6 +53020,7 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
52432
53020
|
"syncConfig": [16],
|
|
52433
53021
|
"assetStorageConfig": [16],
|
|
52434
53022
|
"user": [16],
|
|
53023
|
+
"tools": [16],
|
|
52435
53024
|
"globalContextMenuItems": [16],
|
|
52436
53025
|
"objectContextMenuItems": [16],
|
|
52437
53026
|
"scaleMax": [1026, "scale-max"],
|
|
@@ -52456,7 +53045,7 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
52456
53045
|
"beginSceneBootstrap": [64],
|
|
52457
53046
|
"endSceneBootstrap": [64],
|
|
52458
53047
|
"registerTool": [64],
|
|
52459
|
-
"
|
|
53048
|
+
"setActiveTool": [64],
|
|
52460
53049
|
"disable": [64],
|
|
52461
53050
|
"enable": [64],
|
|
52462
53051
|
"delete": [64],
|
|
@@ -52532,7 +53121,8 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
52532
53121
|
"getAvailableLocales": [64],
|
|
52533
53122
|
"getAvailableLocaleOptions": [64],
|
|
52534
53123
|
"t": [64],
|
|
52535
|
-
"getResolvedTerms": [64]
|
|
53124
|
+
"getResolvedTerms": [64],
|
|
53125
|
+
"getTool": [64]
|
|
52536
53126
|
}, [[1, "wheel", "handleWheel"], [0, "pointerdown", "handlePointerDown"], [0, "pointermove", "handlePointerMove"], [0, "pointerup", "handlePointerUp"], [0, "pointercancel", "handlePointerCancel"], [1, "pointerleave", "handlePointerLeave"], [1, "longpress", "handleLongPress"], [0, "contextmenu", "handleContextMenu"], [9, "resize", "handleResize"], [8, "keydown", "handleKeyDown"], [8, "keyup", "handleKeyUp"], [8, "copy", "handleCopy"], [8, "cut", "handleCut"], [8, "paste", "handlePaste"], [4, "dblclick", "preventDoubleTapZoomOnTouchDevices"]], {
|
|
52537
53127
|
"workspaces": [{
|
|
52538
53128
|
"onWorkspacesPropChange": 0
|
|
@@ -52549,6 +53139,9 @@ const KritzelEngine$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEngine ext
|
|
|
52549
53139
|
"user": [{
|
|
52550
53140
|
"onUserChange": 0
|
|
52551
53141
|
}],
|
|
53142
|
+
"tools": [{
|
|
53143
|
+
"onToolsChange": 0
|
|
53144
|
+
}],
|
|
52552
53145
|
"globalContextMenuItems": [{
|
|
52553
53146
|
"onGlobalContextMenuItemsChange": 0
|
|
52554
53147
|
}],
|
|
@@ -52638,4 +53231,4 @@ function defineCustomElement$1() {
|
|
|
52638
53231
|
const KritzelEngine = KritzelEngine$1;
|
|
52639
53232
|
const defineCustomElement = defineCustomElement$1;
|
|
52640
53233
|
|
|
52641
|
-
export { AssetNotFoundError as A,
|
|
53234
|
+
export { AssetNotFoundError as A, KritzelDynamicObjectRendererRegistry as B, KritzelFontRegistry as C, DEFAULT_STROKE_SIZES as D, DEFAULT_SYNC_CONFIG as E, EN_LOCALE as F, DE_LOCALE as G, FR_LOCALE as H, IndexedDBAssetProvider as I, KritzelAlignment as J, KritzelText as K, KritzelEngine, runMigrations as L, APP_STATE_MIGRATIONS as M, WORKSPACE_MIGRATIONS as N, CURRENT_APP_STATE_SCHEMA_VERSION as O, CURRENT_WORKSPACE_SCHEMA_VERSION as P, resolveTextToolAvailableFonts as Q, ShapeType as S, WORKSPACE_EXPORT_VERSION as W, DEFAULT_FONT_SIZES as a, DEFAULT_TEXT_TOOL_AVAILABLE_FONTS as b, KritzelImage as c, KritzelGroup as d, defineCustomElement, KritzelShape as e, KritzelDynamicObject as f, KritzelIframeObject as g, KritzelSelectionGroup as h, KritzelSelectionBox as i, KritzelBaseTool as j, KritzelBrushTool as k, KritzelLineTool as l, KritzelEraserTool as m, KritzelImageTool as n, KritzelTextTool as o, KritzelShapeTool as p, KritzelCursorHelper as q, KritzelKeyboardHelper as r, KritzelDevicesHelper as s, KritzelHTMLHelper as t, KritzelSelectionTool as u, KritzelAssetResolver as v, KritzelWorkspace as w, KritzelAnchorManager as x, KritzelLocalizationManager as y, KritzelLicenseManager as z };
|