kritzel-stencil 0.0.141 → 0.0.142

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 (91) hide show
  1. package/dist/cjs/{index-BKstgWru.js → index-SaGfCHX3.js} +276 -805
  2. package/dist/cjs/index-SaGfCHX3.js.map +1 -0
  3. package/dist/cjs/index.cjs.js +1 -1
  4. package/dist/cjs/kritzel-color_22.cjs.entry.js +114 -77
  5. package/dist/collection/classes/commands/add-object.command.js +1 -0
  6. package/dist/collection/classes/commands/add-object.command.js.map +1 -1
  7. package/dist/collection/classes/commands/base.command.js +2 -0
  8. package/dist/collection/classes/commands/base.command.js.map +1 -1
  9. package/dist/collection/classes/commands/remove-object.command.js +1 -3
  10. package/dist/collection/classes/commands/remove-object.command.js.map +1 -1
  11. package/dist/collection/classes/commands/update-object.command.js +2 -0
  12. package/dist/collection/classes/commands/update-object.command.js.map +1 -1
  13. package/dist/collection/classes/core/command-manager.class.js +51 -0
  14. package/dist/collection/classes/core/command-manager.class.js.map +1 -0
  15. package/dist/collection/classes/core/core.class.js +23 -14
  16. package/dist/collection/classes/core/core.class.js.map +1 -1
  17. package/dist/collection/classes/core/history.class.js +2 -40
  18. package/dist/collection/classes/core/history.class.js.map +1 -1
  19. package/dist/collection/classes/core/viewport.class.js +16 -5
  20. package/dist/collection/classes/core/viewport.class.js.map +1 -1
  21. package/dist/collection/classes/handlers/context-menu.handler.js +1 -1
  22. package/dist/collection/classes/handlers/context-menu.handler.js.map +1 -1
  23. package/dist/collection/classes/handlers/move.handler.js +11 -6
  24. package/dist/collection/classes/handlers/move.handler.js.map +1 -1
  25. package/dist/collection/classes/handlers/resize.handler.js +29 -5
  26. package/dist/collection/classes/handlers/resize.handler.js.map +1 -1
  27. package/dist/collection/classes/handlers/rotation.handler.js +2 -2
  28. package/dist/collection/classes/handlers/rotation.handler.js.map +1 -1
  29. package/dist/collection/classes/handlers/selection.handler.js +4 -4
  30. package/dist/collection/classes/handlers/selection.handler.js.map +1 -1
  31. package/dist/collection/classes/objects/base-object.class.js +15 -14
  32. package/dist/collection/classes/objects/base-object.class.js.map +1 -1
  33. package/dist/collection/classes/objects/custom-element.class.js +7 -1
  34. package/dist/collection/classes/objects/custom-element.class.js.map +1 -1
  35. package/dist/collection/classes/objects/text.class.js +109 -49
  36. package/dist/collection/classes/objects/text.class.js.map +1 -1
  37. package/dist/collection/classes/tools/brush-tool.class.js +2 -2
  38. package/dist/collection/classes/tools/brush-tool.class.js.map +1 -1
  39. package/dist/collection/classes/tools/eraser-tool.class.js +2 -2
  40. package/dist/collection/classes/tools/eraser-tool.class.js.map +1 -1
  41. package/dist/collection/classes/tools/image-tool.class.js +1 -1
  42. package/dist/collection/classes/tools/image-tool.class.js.map +1 -1
  43. package/dist/collection/classes/tools/selection-tool.class.js +2 -2
  44. package/dist/collection/classes/tools/selection-tool.class.js.map +1 -1
  45. package/dist/collection/classes/tools/text-tool.class.js +17 -11
  46. package/dist/collection/classes/tools/text-tool.class.js.map +1 -1
  47. package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +1 -1
  48. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +21 -15
  49. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
  50. package/dist/collection/interfaces/object.interface.js.map +1 -1
  51. package/dist/components/index.js +2 -2
  52. package/dist/components/kritzel-controls.js +1 -1
  53. package/dist/components/kritzel-editor.js +3 -3
  54. package/dist/components/kritzel-engine.js +1 -1
  55. package/dist/components/{p-ChLi4Ufe.js → p-C8calcQF.js} +3 -3
  56. package/dist/components/{p-ChLi4Ufe.js.map → p-C8calcQF.js.map} +1 -1
  57. package/dist/components/{p-BuDVaqTF.js → p-CZk591FE.js} +165 -728
  58. package/dist/components/p-CZk591FE.js.map +1 -0
  59. package/dist/components/{p-C4nj29RW.js → p-CziwfEQh.js} +227 -156
  60. package/dist/components/p-CziwfEQh.js.map +1 -0
  61. package/dist/esm/{index-D0Q2MKPn.js → index-SIM_s7ed.js} +276 -805
  62. package/dist/esm/index-SIM_s7ed.js.map +1 -0
  63. package/dist/esm/index.js +1 -1
  64. package/dist/esm/kritzel-color_22.entry.js +114 -77
  65. package/dist/stencil/index.esm.js +1 -1
  66. package/dist/stencil/p-SIM_s7ed.js +2 -0
  67. package/dist/stencil/p-SIM_s7ed.js.map +1 -0
  68. package/dist/stencil/p-b697b2c1.entry.js +2 -0
  69. package/dist/stencil/p-b697b2c1.entry.js.map +1 -0
  70. package/dist/stencil/stencil.esm.js +1 -1
  71. package/dist/types/classes/commands/add-object.command.d.ts +2 -2
  72. package/dist/types/classes/commands/base.command.d.ts +2 -1
  73. package/dist/types/classes/commands/remove-object.command.d.ts +2 -2
  74. package/dist/types/classes/commands/update-object.command.d.ts +2 -2
  75. package/dist/types/classes/core/command-manager.class.d.ts +16 -0
  76. package/dist/types/classes/core/core.class.d.ts +4 -0
  77. package/dist/types/classes/core/history.class.d.ts +0 -8
  78. package/dist/types/classes/core/viewport.class.d.ts +2 -0
  79. package/dist/types/classes/handlers/resize.handler.d.ts +1 -0
  80. package/dist/types/classes/objects/base-object.class.d.ts +6 -4
  81. package/dist/types/classes/objects/text.class.d.ts +13 -2
  82. package/dist/types/interfaces/object.interface.d.ts +1 -3
  83. package/package.json +1 -1
  84. package/dist/cjs/index-BKstgWru.js.map +0 -1
  85. package/dist/components/p-BuDVaqTF.js.map +0 -1
  86. package/dist/components/p-C4nj29RW.js.map +0 -1
  87. package/dist/esm/index-D0Q2MKPn.js.map +0 -1
  88. package/dist/stencil/p-73784709.entry.js +0 -2
  89. package/dist/stencil/p-73784709.entry.js.map +0 -1
  90. package/dist/stencil/p-D0Q2MKPn.js +0 -2
  91. package/dist/stencil/p-D0Q2MKPn.js.map +0 -1
@@ -211,18 +211,6 @@ class KritzelBaseObject {
211
211
  this.elementRef = element;
212
212
  this.isMounted = true;
213
213
  }
214
- unmount() {
215
- if (!this.isMounted) {
216
- return;
217
- }
218
- this.isMounted = false;
219
- }
220
- remount() {
221
- if (!this.isMounted) {
222
- return;
223
- }
224
- this.isMounted = false;
225
- }
226
214
  generateId() {
227
215
  return ObjectHelper.generateUUID();
228
216
  }
@@ -268,8 +256,9 @@ class KritzelBaseObject {
268
256
  this.rotation = value;
269
257
  }
270
258
  clone() {
271
- const clone = new KritzelBaseObject();
259
+ const clone = Object.create(Object.getPrototypeOf(this));
272
260
  Object.assign(clone, this);
261
+ clone.id = this.id;
273
262
  return clone;
274
263
  }
275
264
  copy() {
@@ -297,7 +286,7 @@ class KritzelBaseObject {
297
286
  isClass(className) {
298
287
  return this.__class__ === className;
299
288
  }
300
- edit() {
289
+ edit(_event) {
301
290
  // This method can be overridden by subclasses to handle edit actions.
302
291
  }
303
292
  hitTest(_x, _y) {
@@ -312,6 +301,18 @@ class KritzelBaseObject {
312
301
  this.translateY = y;
313
302
  this._core.store.state.objectsMap.update(this);
314
303
  }
304
+ onExecuteAddCommand(_object) {
305
+ // This method can be overridden by subclasses to handle actions after an add command is executed.
306
+ }
307
+ onUndoAddCommand(_object) {
308
+ // This method can be overridden by subclasses to handle actions after an add command is undone.
309
+ }
310
+ onExecuteUpdateCommand(_updatedProperties) {
311
+ // This method can be overridden by subclasses to handle actions after an update command is executed.
312
+ }
313
+ onUndoUpdateCommand(_previousProperties) {
314
+ // This method can be overridden by subclasses to handle actions after an update command is undone.
315
+ }
315
316
  }
316
317
 
317
318
  class KritzelKeyboardHelper {
@@ -367,10 +368,12 @@ class KritzelBaseCommand {
367
368
  _core;
368
369
  initiator;
369
370
  skipHistory;
371
+ timestamp;
370
372
  constructor(core, initiator, skipHistory = false) {
371
373
  this._core = core;
372
374
  this.initiator = initiator?.constructor?.name ?? 'Unknown';
373
375
  this.skipHistory = skipHistory;
376
+ this.timestamp = new Date();
374
377
  }
375
378
  execute() {
376
379
  throw new Error('Method not implemented.');
@@ -401,6 +404,7 @@ class UpdateObjectCommand extends KritzelBaseCommand {
401
404
  this.object[key] = this.updatedProperties[key];
402
405
  }
403
406
  }
407
+ this.object.onExecuteUpdateCommand(this.updatedProperties);
404
408
  this._core.store.state.objectsMap.update(this.object);
405
409
  this._core.updateObjectInDatabase(this.object);
406
410
  }
@@ -410,6 +414,7 @@ class UpdateObjectCommand extends KritzelBaseCommand {
410
414
  this.object[key] = this.previousProperties[key];
411
415
  }
412
416
  }
417
+ this.object.onUndoUpdateCommand(this.previousProperties);
413
418
  this._core.store.state.objectsMap.update(this.object);
414
419
  this._core.updateObjectInDatabase(this.object);
415
420
  }
@@ -7072,27 +7077,6 @@ function createKey(name) {
7072
7077
  keys[name] = 0;
7073
7078
  return name + "$";
7074
7079
  }
7075
- /**
7076
- A key is used to [tag](https://prosemirror.net/docs/ref/#state.PluginSpec.key) plugins in a way
7077
- that makes it possible to find them, given an editor state.
7078
- Assigning a key does mean only one plugin of that type can be
7079
- active in a state.
7080
- */
7081
- class PluginKey {
7082
- /**
7083
- Create a plugin key.
7084
- */
7085
- constructor(name = "key") { this.key = createKey(name); }
7086
- /**
7087
- Get the active plugin with this key, if any, from an editor
7088
- state.
7089
- */
7090
- get(state) { return state.config.pluginsByKey[this.key]; }
7091
- /**
7092
- Get the plugin's state from an editor state.
7093
- */
7094
- getState(state) { return state[this.key]; }
7095
- }
7096
7080
 
7097
7081
  const domIndex = function (node) {
7098
7082
  for (var index = 0;; index++) {
@@ -13386,621 +13370,6 @@ function keydownHandler(bindings) {
13386
13370
  };
13387
13371
  }
13388
13372
 
13389
- var GOOD_LEAF_SIZE = 200;
13390
-
13391
- // :: class<T> A rope sequence is a persistent sequence data structure
13392
- // that supports appending, prepending, and slicing without doing a
13393
- // full copy. It is represented as a mostly-balanced tree.
13394
- var RopeSequence = function RopeSequence () {};
13395
-
13396
- RopeSequence.prototype.append = function append (other) {
13397
- if (!other.length) { return this }
13398
- other = RopeSequence.from(other);
13399
-
13400
- return (!this.length && other) ||
13401
- (other.length < GOOD_LEAF_SIZE && this.leafAppend(other)) ||
13402
- (this.length < GOOD_LEAF_SIZE && other.leafPrepend(this)) ||
13403
- this.appendInner(other)
13404
- };
13405
-
13406
- // :: (union<[T], RopeSequence<T>>) → RopeSequence<T>
13407
- // Prepend an array or other rope to this one, returning a new rope.
13408
- RopeSequence.prototype.prepend = function prepend (other) {
13409
- if (!other.length) { return this }
13410
- return RopeSequence.from(other).append(this)
13411
- };
13412
-
13413
- RopeSequence.prototype.appendInner = function appendInner (other) {
13414
- return new Append(this, other)
13415
- };
13416
-
13417
- // :: (?number, ?number) → RopeSequence<T>
13418
- // Create a rope repesenting a sub-sequence of this rope.
13419
- RopeSequence.prototype.slice = function slice (from, to) {
13420
- if ( from === void 0 ) from = 0;
13421
- if ( to === void 0 ) to = this.length;
13422
-
13423
- if (from >= to) { return RopeSequence.empty }
13424
- return this.sliceInner(Math.max(0, from), Math.min(this.length, to))
13425
- };
13426
-
13427
- // :: (number) → T
13428
- // Retrieve the element at the given position from this rope.
13429
- RopeSequence.prototype.get = function get (i) {
13430
- if (i < 0 || i >= this.length) { return undefined }
13431
- return this.getInner(i)
13432
- };
13433
-
13434
- // :: ((element: T, index: number) → ?bool, ?number, ?number)
13435
- // Call the given function for each element between the given
13436
- // indices. This tends to be more efficient than looping over the
13437
- // indices and calling `get`, because it doesn't have to descend the
13438
- // tree for every element.
13439
- RopeSequence.prototype.forEach = function forEach (f, from, to) {
13440
- if ( from === void 0 ) from = 0;
13441
- if ( to === void 0 ) to = this.length;
13442
-
13443
- if (from <= to)
13444
- { this.forEachInner(f, from, to, 0); }
13445
- else
13446
- { this.forEachInvertedInner(f, from, to, 0); }
13447
- };
13448
-
13449
- // :: ((element: T, index: number) → U, ?number, ?number) → [U]
13450
- // Map the given functions over the elements of the rope, producing
13451
- // a flat array.
13452
- RopeSequence.prototype.map = function map (f, from, to) {
13453
- if ( from === void 0 ) from = 0;
13454
- if ( to === void 0 ) to = this.length;
13455
-
13456
- var result = [];
13457
- this.forEach(function (elt, i) { return result.push(f(elt, i)); }, from, to);
13458
- return result
13459
- };
13460
-
13461
- // :: (?union<[T], RopeSequence<T>>) → RopeSequence<T>
13462
- // Create a rope representing the given array, or return the rope
13463
- // itself if a rope was given.
13464
- RopeSequence.from = function from (values) {
13465
- if (values instanceof RopeSequence) { return values }
13466
- return values && values.length ? new Leaf(values) : RopeSequence.empty
13467
- };
13468
-
13469
- var Leaf = /*@__PURE__*/(function (RopeSequence) {
13470
- function Leaf(values) {
13471
- RopeSequence.call(this);
13472
- this.values = values;
13473
- }
13474
-
13475
- if ( RopeSequence ) Leaf.__proto__ = RopeSequence;
13476
- Leaf.prototype = Object.create( RopeSequence && RopeSequence.prototype );
13477
- Leaf.prototype.constructor = Leaf;
13478
-
13479
- var prototypeAccessors = { length: { configurable: true },depth: { configurable: true } };
13480
-
13481
- Leaf.prototype.flatten = function flatten () {
13482
- return this.values
13483
- };
13484
-
13485
- Leaf.prototype.sliceInner = function sliceInner (from, to) {
13486
- if (from == 0 && to == this.length) { return this }
13487
- return new Leaf(this.values.slice(from, to))
13488
- };
13489
-
13490
- Leaf.prototype.getInner = function getInner (i) {
13491
- return this.values[i]
13492
- };
13493
-
13494
- Leaf.prototype.forEachInner = function forEachInner (f, from, to, start) {
13495
- for (var i = from; i < to; i++)
13496
- { if (f(this.values[i], start + i) === false) { return false } }
13497
- };
13498
-
13499
- Leaf.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
13500
- for (var i = from - 1; i >= to; i--)
13501
- { if (f(this.values[i], start + i) === false) { return false } }
13502
- };
13503
-
13504
- Leaf.prototype.leafAppend = function leafAppend (other) {
13505
- if (this.length + other.length <= GOOD_LEAF_SIZE)
13506
- { return new Leaf(this.values.concat(other.flatten())) }
13507
- };
13508
-
13509
- Leaf.prototype.leafPrepend = function leafPrepend (other) {
13510
- if (this.length + other.length <= GOOD_LEAF_SIZE)
13511
- { return new Leaf(other.flatten().concat(this.values)) }
13512
- };
13513
-
13514
- prototypeAccessors.length.get = function () { return this.values.length };
13515
-
13516
- prototypeAccessors.depth.get = function () { return 0 };
13517
-
13518
- Object.defineProperties( Leaf.prototype, prototypeAccessors );
13519
-
13520
- return Leaf;
13521
- }(RopeSequence));
13522
-
13523
- // :: RopeSequence
13524
- // The empty rope sequence.
13525
- RopeSequence.empty = new Leaf([]);
13526
-
13527
- var Append = /*@__PURE__*/(function (RopeSequence) {
13528
- function Append(left, right) {
13529
- RopeSequence.call(this);
13530
- this.left = left;
13531
- this.right = right;
13532
- this.length = left.length + right.length;
13533
- this.depth = Math.max(left.depth, right.depth) + 1;
13534
- }
13535
-
13536
- if ( RopeSequence ) Append.__proto__ = RopeSequence;
13537
- Append.prototype = Object.create( RopeSequence && RopeSequence.prototype );
13538
- Append.prototype.constructor = Append;
13539
-
13540
- Append.prototype.flatten = function flatten () {
13541
- return this.left.flatten().concat(this.right.flatten())
13542
- };
13543
-
13544
- Append.prototype.getInner = function getInner (i) {
13545
- return i < this.left.length ? this.left.get(i) : this.right.get(i - this.left.length)
13546
- };
13547
-
13548
- Append.prototype.forEachInner = function forEachInner (f, from, to, start) {
13549
- var leftLen = this.left.length;
13550
- if (from < leftLen &&
13551
- this.left.forEachInner(f, from, Math.min(to, leftLen), start) === false)
13552
- { return false }
13553
- if (to > leftLen &&
13554
- this.right.forEachInner(f, Math.max(from - leftLen, 0), Math.min(this.length, to) - leftLen, start + leftLen) === false)
13555
- { return false }
13556
- };
13557
-
13558
- Append.prototype.forEachInvertedInner = function forEachInvertedInner (f, from, to, start) {
13559
- var leftLen = this.left.length;
13560
- if (from > leftLen &&
13561
- this.right.forEachInvertedInner(f, from - leftLen, Math.max(to, leftLen) - leftLen, start + leftLen) === false)
13562
- { return false }
13563
- if (to < leftLen &&
13564
- this.left.forEachInvertedInner(f, Math.min(from, leftLen), to, start) === false)
13565
- { return false }
13566
- };
13567
-
13568
- Append.prototype.sliceInner = function sliceInner (from, to) {
13569
- if (from == 0 && to == this.length) { return this }
13570
- var leftLen = this.left.length;
13571
- if (to <= leftLen) { return this.left.slice(from, to) }
13572
- if (from >= leftLen) { return this.right.slice(from - leftLen, to - leftLen) }
13573
- return this.left.slice(from, leftLen).append(this.right.slice(0, to - leftLen))
13574
- };
13575
-
13576
- Append.prototype.leafAppend = function leafAppend (other) {
13577
- var inner = this.right.leafAppend(other);
13578
- if (inner) { return new Append(this.left, inner) }
13579
- };
13580
-
13581
- Append.prototype.leafPrepend = function leafPrepend (other) {
13582
- var inner = this.left.leafPrepend(other);
13583
- if (inner) { return new Append(inner, this.right) }
13584
- };
13585
-
13586
- Append.prototype.appendInner = function appendInner (other) {
13587
- if (this.left.depth >= Math.max(this.right.depth, other.depth) + 1)
13588
- { return new Append(this.left, new Append(this.right, other)) }
13589
- return new Append(this, other)
13590
- };
13591
-
13592
- return Append;
13593
- }(RopeSequence));
13594
-
13595
- // ProseMirror's history isn't simply a way to roll back to a previous
13596
- // state, because ProseMirror supports applying changes without adding
13597
- // them to the history (for example during collaboration).
13598
- //
13599
- // To this end, each 'Branch' (one for the undo history and one for
13600
- // the redo history) keeps an array of 'Items', which can optionally
13601
- // hold a step (an actual undoable change), and always hold a position
13602
- // map (which is needed to move changes below them to apply to the
13603
- // current document).
13604
- //
13605
- // An item that has both a step and a selection bookmark is the start
13606
- // of an 'event' — a group of changes that will be undone or redone at
13607
- // once. (It stores only the bookmark, since that way we don't have to
13608
- // provide a document until the selection is actually applied, which
13609
- // is useful when compressing.)
13610
- // Used to schedule history compression
13611
- const max_empty_items = 500;
13612
- class Branch {
13613
- constructor(items, eventCount) {
13614
- this.items = items;
13615
- this.eventCount = eventCount;
13616
- }
13617
- // Pop the latest event off the branch's history and apply it
13618
- // to a document transform.
13619
- popEvent(state, preserveItems) {
13620
- if (this.eventCount == 0)
13621
- return null;
13622
- let end = this.items.length;
13623
- for (;; end--) {
13624
- let next = this.items.get(end - 1);
13625
- if (next.selection) {
13626
- --end;
13627
- break;
13628
- }
13629
- }
13630
- let remap, mapFrom;
13631
- if (preserveItems) {
13632
- remap = this.remapping(end, this.items.length);
13633
- mapFrom = remap.maps.length;
13634
- }
13635
- let transform = state.tr;
13636
- let selection, remaining;
13637
- let addAfter = [], addBefore = [];
13638
- this.items.forEach((item, i) => {
13639
- if (!item.step) {
13640
- if (!remap) {
13641
- remap = this.remapping(end, i + 1);
13642
- mapFrom = remap.maps.length;
13643
- }
13644
- mapFrom--;
13645
- addBefore.push(item);
13646
- return;
13647
- }
13648
- if (remap) {
13649
- addBefore.push(new Item(item.map));
13650
- let step = item.step.map(remap.slice(mapFrom)), map;
13651
- if (step && transform.maybeStep(step).doc) {
13652
- map = transform.mapping.maps[transform.mapping.maps.length - 1];
13653
- addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length));
13654
- }
13655
- mapFrom--;
13656
- if (map)
13657
- remap.appendMap(map, mapFrom);
13658
- }
13659
- else {
13660
- transform.maybeStep(item.step);
13661
- }
13662
- if (item.selection) {
13663
- selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;
13664
- remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1);
13665
- return false;
13666
- }
13667
- }, this.items.length, 0);
13668
- return { remaining: remaining, transform, selection: selection };
13669
- }
13670
- // Create a new branch with the given transform added.
13671
- addTransform(transform, selection, histOptions, preserveItems) {
13672
- let newItems = [], eventCount = this.eventCount;
13673
- let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
13674
- for (let i = 0; i < transform.steps.length; i++) {
13675
- let step = transform.steps[i].invert(transform.docs[i]);
13676
- let item = new Item(transform.mapping.maps[i], step, selection), merged;
13677
- if (merged = lastItem && lastItem.merge(item)) {
13678
- item = merged;
13679
- if (i)
13680
- newItems.pop();
13681
- else
13682
- oldItems = oldItems.slice(0, oldItems.length - 1);
13683
- }
13684
- newItems.push(item);
13685
- if (selection) {
13686
- eventCount++;
13687
- selection = undefined;
13688
- }
13689
- if (!preserveItems)
13690
- lastItem = item;
13691
- }
13692
- let overflow = eventCount - histOptions.depth;
13693
- if (overflow > DEPTH_OVERFLOW) {
13694
- oldItems = cutOffEvents(oldItems, overflow);
13695
- eventCount -= overflow;
13696
- }
13697
- return new Branch(oldItems.append(newItems), eventCount);
13698
- }
13699
- remapping(from, to) {
13700
- let maps = new Mapping;
13701
- this.items.forEach((item, i) => {
13702
- let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from
13703
- ? maps.maps.length - item.mirrorOffset : undefined;
13704
- maps.appendMap(item.map, mirrorPos);
13705
- }, from, to);
13706
- return maps;
13707
- }
13708
- addMaps(array) {
13709
- if (this.eventCount == 0)
13710
- return this;
13711
- return new Branch(this.items.append(array.map(map => new Item(map))), this.eventCount);
13712
- }
13713
- // When the collab module receives remote changes, the history has
13714
- // to know about those, so that it can adjust the steps that were
13715
- // rebased on top of the remote changes, and include the position
13716
- // maps for the remote changes in its array of items.
13717
- rebased(rebasedTransform, rebasedCount) {
13718
- if (!this.eventCount)
13719
- return this;
13720
- let rebasedItems = [], start = Math.max(0, this.items.length - rebasedCount);
13721
- let mapping = rebasedTransform.mapping;
13722
- let newUntil = rebasedTransform.steps.length;
13723
- let eventCount = this.eventCount;
13724
- this.items.forEach(item => { if (item.selection)
13725
- eventCount--; }, start);
13726
- let iRebased = rebasedCount;
13727
- this.items.forEach(item => {
13728
- let pos = mapping.getMirror(--iRebased);
13729
- if (pos == null)
13730
- return;
13731
- newUntil = Math.min(newUntil, pos);
13732
- let map = mapping.maps[pos];
13733
- if (item.step) {
13734
- let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);
13735
- let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
13736
- if (selection)
13737
- eventCount++;
13738
- rebasedItems.push(new Item(map, step, selection));
13739
- }
13740
- else {
13741
- rebasedItems.push(new Item(map));
13742
- }
13743
- }, start);
13744
- let newMaps = [];
13745
- for (let i = rebasedCount; i < newUntil; i++)
13746
- newMaps.push(new Item(mapping.maps[i]));
13747
- let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
13748
- let branch = new Branch(items, eventCount);
13749
- if (branch.emptyItemCount() > max_empty_items)
13750
- branch = branch.compress(this.items.length - rebasedItems.length);
13751
- return branch;
13752
- }
13753
- emptyItemCount() {
13754
- let count = 0;
13755
- this.items.forEach(item => { if (!item.step)
13756
- count++; });
13757
- return count;
13758
- }
13759
- // Compressing a branch means rewriting it to push the air (map-only
13760
- // items) out. During collaboration, these naturally accumulate
13761
- // because each remote change adds one. The `upto` argument is used
13762
- // to ensure that only the items below a given level are compressed,
13763
- // because `rebased` relies on a clean, untouched set of items in
13764
- // order to associate old items with rebased steps.
13765
- compress(upto = this.items.length) {
13766
- let remap = this.remapping(0, upto), mapFrom = remap.maps.length;
13767
- let items = [], events = 0;
13768
- this.items.forEach((item, i) => {
13769
- if (i >= upto) {
13770
- items.push(item);
13771
- if (item.selection)
13772
- events++;
13773
- }
13774
- else if (item.step) {
13775
- let step = item.step.map(remap.slice(mapFrom)), map = step && step.getMap();
13776
- mapFrom--;
13777
- if (map)
13778
- remap.appendMap(map, mapFrom);
13779
- if (step) {
13780
- let selection = item.selection && item.selection.map(remap.slice(mapFrom));
13781
- if (selection)
13782
- events++;
13783
- let newItem = new Item(map.invert(), step, selection), merged, last = items.length - 1;
13784
- if (merged = items.length && items[last].merge(newItem))
13785
- items[last] = merged;
13786
- else
13787
- items.push(newItem);
13788
- }
13789
- }
13790
- else if (item.map) {
13791
- mapFrom--;
13792
- }
13793
- }, this.items.length, 0);
13794
- return new Branch(RopeSequence.from(items.reverse()), events);
13795
- }
13796
- }
13797
- Branch.empty = new Branch(RopeSequence.empty, 0);
13798
- function cutOffEvents(items, n) {
13799
- let cutPoint;
13800
- items.forEach((item, i) => {
13801
- if (item.selection && (n-- == 0)) {
13802
- cutPoint = i;
13803
- return false;
13804
- }
13805
- });
13806
- return items.slice(cutPoint);
13807
- }
13808
- class Item {
13809
- constructor(
13810
- // The (forward) step map for this item.
13811
- map,
13812
- // The inverted step
13813
- step,
13814
- // If this is non-null, this item is the start of a group, and
13815
- // this selection is the starting selection for the group (the one
13816
- // that was active before the first step was applied)
13817
- selection,
13818
- // If this item is the inverse of a previous mapping on the stack,
13819
- // this points at the inverse's offset
13820
- mirrorOffset) {
13821
- this.map = map;
13822
- this.step = step;
13823
- this.selection = selection;
13824
- this.mirrorOffset = mirrorOffset;
13825
- }
13826
- merge(other) {
13827
- if (this.step && other.step && !other.selection) {
13828
- let step = other.step.merge(this.step);
13829
- if (step)
13830
- return new Item(step.getMap().invert(), step, this.selection);
13831
- }
13832
- }
13833
- }
13834
- // The value of the state field that tracks undo/redo history for that
13835
- // state. Will be stored in the plugin state when the history plugin
13836
- // is active.
13837
- class HistoryState {
13838
- constructor(done, undone, prevRanges, prevTime, prevComposition) {
13839
- this.done = done;
13840
- this.undone = undone;
13841
- this.prevRanges = prevRanges;
13842
- this.prevTime = prevTime;
13843
- this.prevComposition = prevComposition;
13844
- }
13845
- }
13846
- const DEPTH_OVERFLOW = 20;
13847
- // Record a transformation in undo history.
13848
- function applyTransaction(history, state, tr, options) {
13849
- let historyTr = tr.getMeta(historyKey), rebased;
13850
- if (historyTr)
13851
- return historyTr.historyState;
13852
- if (tr.getMeta(closeHistoryKey))
13853
- history = new HistoryState(history.done, history.undone, null, 0, -1);
13854
- let appended = tr.getMeta("appendedTransaction");
13855
- if (tr.steps.length == 0) {
13856
- return history;
13857
- }
13858
- else if (appended && appended.getMeta(historyKey)) {
13859
- if (appended.getMeta(historyKey).redo)
13860
- return new HistoryState(history.done.addTransform(tr, undefined, options, mustPreserveItems(state)), history.undone, rangesFor(tr.mapping.maps), history.prevTime, history.prevComposition);
13861
- else
13862
- return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);
13863
- }
13864
- else if (tr.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) {
13865
- // Group transforms that occur in quick succession into one event.
13866
- let composition = tr.getMeta("composition");
13867
- let newGroup = history.prevTime == 0 ||
13868
- (!appended && history.prevComposition != composition &&
13869
- (history.prevTime < (tr.time || 0) - options.newGroupDelay || !isAdjacentTo(tr, history.prevRanges)));
13870
- let prevRanges = appended ? mapRanges(history.prevRanges, tr.mapping) : rangesFor(tr.mapping.maps);
13871
- return new HistoryState(history.done.addTransform(tr, newGroup ? state.selection.getBookmark() : undefined, options, mustPreserveItems(state)), Branch.empty, prevRanges, tr.time, composition == null ? history.prevComposition : composition);
13872
- }
13873
- else if (rebased = tr.getMeta("rebased")) {
13874
- // Used by the collab module to tell the history that some of its
13875
- // content has been rebased.
13876
- return new HistoryState(history.done.rebased(tr, rebased), history.undone.rebased(tr, rebased), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
13877
- }
13878
- else {
13879
- return new HistoryState(history.done.addMaps(tr.mapping.maps), history.undone.addMaps(tr.mapping.maps), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
13880
- }
13881
- }
13882
- function isAdjacentTo(transform, prevRanges) {
13883
- if (!prevRanges)
13884
- return false;
13885
- if (!transform.docChanged)
13886
- return true;
13887
- let adjacent = false;
13888
- transform.mapping.maps[0].forEach((start, end) => {
13889
- for (let i = 0; i < prevRanges.length; i += 2)
13890
- if (start <= prevRanges[i + 1] && end >= prevRanges[i])
13891
- adjacent = true;
13892
- });
13893
- return adjacent;
13894
- }
13895
- function rangesFor(maps) {
13896
- let result = [];
13897
- for (let i = maps.length - 1; i >= 0 && result.length == 0; i--)
13898
- maps[i].forEach((_from, _to, from, to) => result.push(from, to));
13899
- return result;
13900
- }
13901
- function mapRanges(ranges, mapping) {
13902
- if (!ranges)
13903
- return null;
13904
- let result = [];
13905
- for (let i = 0; i < ranges.length; i += 2) {
13906
- let from = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1);
13907
- if (from <= to)
13908
- result.push(from, to);
13909
- }
13910
- return result;
13911
- }
13912
- // Apply the latest event from one branch to the document and shift the event
13913
- // onto the other branch.
13914
- function histTransaction(history, state, redo) {
13915
- let preserveItems = mustPreserveItems(state);
13916
- let histOptions = historyKey.get(state).spec.config;
13917
- let pop = (redo ? history.undone : history.done).popEvent(state, preserveItems);
13918
- if (!pop)
13919
- return null;
13920
- let selection = pop.selection.resolve(pop.transform.doc);
13921
- let added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);
13922
- let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1);
13923
- return pop.transform.setSelection(selection).setMeta(historyKey, { redo, historyState: newHist });
13924
- }
13925
- let cachedPreserveItems = false, cachedPreserveItemsPlugins = null;
13926
- // Check whether any plugin in the given state has a
13927
- // `historyPreserveItems` property in its spec, in which case we must
13928
- // preserve steps exactly as they came in, so that they can be
13929
- // rebased.
13930
- function mustPreserveItems(state) {
13931
- let plugins = state.plugins;
13932
- if (cachedPreserveItemsPlugins != plugins) {
13933
- cachedPreserveItems = false;
13934
- cachedPreserveItemsPlugins = plugins;
13935
- for (let i = 0; i < plugins.length; i++)
13936
- if (plugins[i].spec.historyPreserveItems) {
13937
- cachedPreserveItems = true;
13938
- break;
13939
- }
13940
- }
13941
- return cachedPreserveItems;
13942
- }
13943
- const historyKey = new PluginKey("history");
13944
- const closeHistoryKey = new PluginKey("closeHistory");
13945
- /**
13946
- Returns a plugin that enables the undo history for an editor. The
13947
- plugin will track undo and redo stacks, which can be used with the
13948
- [`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.
13949
-
13950
- You can set an `"addToHistory"` [metadata
13951
- property](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction
13952
- to prevent it from being rolled back by undo.
13953
- */
13954
- function history(config = {}) {
13955
- config = { depth: config.depth || 100,
13956
- newGroupDelay: config.newGroupDelay || 500 };
13957
- return new Plugin({
13958
- key: historyKey,
13959
- state: {
13960
- init() {
13961
- return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);
13962
- },
13963
- apply(tr, hist, state) {
13964
- return applyTransaction(hist, state, tr, config);
13965
- }
13966
- },
13967
- config,
13968
- props: {
13969
- handleDOMEvents: {
13970
- beforeinput(view, e) {
13971
- let inputType = e.inputType;
13972
- let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
13973
- if (!command)
13974
- return false;
13975
- e.preventDefault();
13976
- return command(view.state, view.dispatch);
13977
- }
13978
- }
13979
- }
13980
- });
13981
- }
13982
- function buildCommand(redo, scroll) {
13983
- return (state, dispatch) => {
13984
- let hist = historyKey.getState(state);
13985
- if (!hist || (redo ? hist.undone : hist.done).eventCount == 0)
13986
- return false;
13987
- if (dispatch) {
13988
- let tr = histTransaction(hist, state, redo);
13989
- if (tr)
13990
- dispatch(scroll ? tr.scrollIntoView() : tr);
13991
- }
13992
- return true;
13993
- };
13994
- }
13995
- /**
13996
- A command function that undoes the last change, if any.
13997
- */
13998
- const undo = buildCommand(false, true);
13999
- /**
14000
- A command function that redoes the last undone change, if any.
14001
- */
14002
- const redo = buildCommand(true, true);
14003
-
14004
13373
  /**
14005
13374
  Delete the selection, if there is one.
14006
13375
  */
@@ -14508,6 +13877,23 @@ Depending on the detected platform, this will hold
14508
13877
  */
14509
13878
  const baseKeymap = mac ? macBaseKeymap : pcBaseKeymap;
14510
13879
 
13880
+ class AddObjectCommand extends KritzelBaseCommand {
13881
+ object;
13882
+ constructor(core, initiator, object, skipHistory = false) {
13883
+ super(core, initiator, skipHistory);
13884
+ this.object = object;
13885
+ }
13886
+ execute() {
13887
+ this._core.store.state.objectsMap.insert(this.object);
13888
+ this._core.addObjectToDatabase(this.object);
13889
+ }
13890
+ undo() {
13891
+ this.object.isMounted = false;
13892
+ this._core.store.state.objectsMap.remove(object => object.id === this.object.id);
13893
+ this._core.deleteObjectFromDatabase(this.object.id);
13894
+ }
13895
+ }
13896
+
14511
13897
  class KritzelText extends KritzelBaseObject {
14512
13898
  __class__ = 'KritzelText';
14513
13899
  fontFamily = 'Arial';
@@ -14522,19 +13908,21 @@ class KritzelText extends KritzelBaseObject {
14522
13908
  isEditable = true;
14523
13909
  isEditing = false;
14524
13910
  editor = null;
14525
- content = null; // Store ProseMirror document content
13911
+ content = null;
13912
+ _schema = new Schema({
13913
+ nodes: addListNodes(schema.spec.nodes, 'paragraph block*', 'block'),
13914
+ marks: schema.spec.marks,
13915
+ });
13916
+ uneditedObject = null;
14526
13917
  rows = 1;
14527
13918
  get isEmpty() {
14528
13919
  if (!this.editor) {
14529
13920
  return true;
14530
13921
  }
14531
13922
  const doc = this.editor.state.doc;
14532
- // Check if document is empty (only has empty paragraph(s))
14533
- // A truly empty doc has size of 4: start of doc (1) + paragraph (1) + end of paragraph (1) + end of doc (1)
14534
13923
  if (doc.content.size === 0) {
14535
13924
  return true;
14536
13925
  }
14537
- // Check if all content is whitespace
14538
13926
  const text = doc.textContent.trim();
14539
13927
  return text.length === 0;
14540
13928
  }
@@ -14569,49 +13957,66 @@ class KritzelText extends KritzelBaseObject {
14569
13957
  object.scaleFactor = 1;
14570
13958
  object.scale = object._core.store.state.scale;
14571
13959
  object.zIndex = core.store.currentZIndex;
13960
+ object.editor = object.createEditor();
14572
13961
  return object;
14573
13962
  }
14574
13963
  mount(element) {
14575
- if ((this.isMounted && this.elementRef === element) || this.isInViewport() === false) {
13964
+ if (element === null || this.isInViewport() === false) {
13965
+ return;
13966
+ }
13967
+ if (this.isMounted && this.elementRef === element && this.editor.dom.parentElement === element) {
14576
13968
  return;
14577
13969
  }
14578
- console.log('Mounting text object', this.id);
14579
13970
  this.elementRef = element;
14580
- setTimeout(() => {
14581
- const mySchema = new Schema({
14582
- nodes: addListNodes(schema.spec.nodes, 'paragraph block*', 'block'),
14583
- marks: schema.spec.marks,
14584
- });
14585
- const doc = this.content
14586
- ? mySchema.nodeFromJSON(this.content)
14587
- : mySchema.node('doc', null, [mySchema.node('paragraph')]);
14588
- this.editor = new EditorView(this.elementRef, {
14589
- state: EditorState.create({
14590
- doc: doc,
14591
- plugins: [history(), keymap({ 'Mod-z': undo, 'Mod-y': redo }), keymap(baseKeymap)],
14592
- }),
14593
- editable: () => false, // Start disabled, enable in edit()
14594
- dispatchTransaction: (transaction) => {
14595
- const newState = this.editor.state.apply(transaction);
14596
- this.editor.updateState(newState);
14597
- // Adjust size after content changes
14598
- this.adjustSizeOnInput();
14599
- },
14600
- });
14601
- }, 0);
13971
+ this.elementRef.style.fontFamily = this.fontFamily;
13972
+ this.elementRef.style.fontSize = `${this.fontSize}pt`;
13973
+ this.elementRef.style.color = this.fontColor;
13974
+ this.elementRef.style.whiteSpace = 'pre-wrap';
13975
+ this.elementRef.style.wordWrap = 'break-word';
13976
+ this.elementRef.innerHTML = '';
13977
+ this.elementRef.appendChild(this.editor.dom);
14602
13978
  this.isMounted = true;
13979
+ requestAnimationFrame(() => this.adjustSizeOnInput());
13980
+ }
13981
+ createEditor() {
13982
+ const doc = this._schema.node('doc', null, [this._schema.node('paragraph')]);
13983
+ return new EditorView(null, {
13984
+ state: EditorState.create({
13985
+ doc: doc,
13986
+ plugins: [keymap(baseKeymap)],
13987
+ }),
13988
+ editable: () => false,
13989
+ dispatchTransaction: transaction => {
13990
+ const newState = this.editor.state.apply(transaction);
13991
+ this.editor.updateState(newState);
13992
+ this.adjustSizeOnInput();
13993
+ this._core.store.state.objectsMap.update(this);
13994
+ this._core.rerender();
13995
+ },
13996
+ });
13997
+ }
13998
+ setContent(content) {
13999
+ this.content = content;
14000
+ if (this.editor) {
14001
+ const newDoc = this.editor.state.schema.nodeFromJSON(content);
14002
+ const tr = this.editor.state.tr.replaceWith(0, this.editor.state.doc.content.size, newDoc.content);
14003
+ this.editor.dispatch(tr);
14004
+ }
14603
14005
  }
14604
14006
  adjustSizeOnInput() {
14605
14007
  const element = this.elementRef;
14606
- if (element) {
14008
+ if (element && this.isMounted && element.scrollWidth > 0) {
14607
14009
  const newWidth = element.scrollWidth;
14608
14010
  const newHeight = element.scrollHeight;
14609
14011
  if (this.width !== newWidth * this.scaleFactor || this.height !== newHeight * this.scaleFactor) {
14610
14012
  this.width = newWidth * this.scaleFactor;
14611
14013
  this.height = newHeight * this.scaleFactor;
14612
- this._core.rerender();
14613
14014
  }
14614
14015
  }
14016
+ if (this._core) {
14017
+ this._core.store.state.objectsMap.update(this);
14018
+ this._core.rerender();
14019
+ }
14615
14020
  }
14616
14021
  resize(x, y, width, height) {
14617
14022
  if (width <= 1 || height <= 1) {
@@ -14627,38 +14032,56 @@ class KritzelText extends KritzelBaseObject {
14627
14032
  this.translateX = x;
14628
14033
  this.translateY = y;
14629
14034
  }
14630
- focus() {
14035
+ focus(coords) {
14631
14036
  if (this.editor) {
14632
- const end = this.editor.state.doc.content.size;
14633
- this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(this.editor.state.doc, end)));
14037
+ const doc = this.editor.state.doc;
14038
+ if (coords) {
14039
+ const pos = this.editor.posAtCoords({ left: coords.x, top: coords.y });
14040
+ if (pos) {
14041
+ this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
14042
+ this.editor.focus();
14043
+ return;
14044
+ }
14045
+ }
14046
+ const end = Math.max(1, doc.content.size - 1);
14047
+ this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, end)));
14634
14048
  this.editor.focus();
14635
14049
  }
14636
14050
  }
14637
- edit() {
14638
- console.log('Editing text object', this.id);
14051
+ edit(event) {
14639
14052
  KritzelKeyboardHelper.disableInteractiveWidget();
14053
+ this.uneditedObject = this.clone();
14640
14054
  this._core.store.setState('activeTool', KritzelToolRegistry.getTool('text'));
14641
14055
  this._core.store.state.activeText = this;
14642
- this._core.clearSelection();
14643
- // Enable the ProseMirror editor
14644
14056
  if (this.editor) {
14645
14057
  this.editor.setProps({ editable: () => true });
14646
14058
  }
14647
14059
  this.isEditing = true;
14648
- this.focus();
14060
+ if (event) {
14061
+ this.focus({ x: event.clientX, y: event.clientY });
14062
+ }
14063
+ else {
14064
+ this.focus();
14065
+ }
14066
+ this._core.rerender();
14067
+ requestAnimationFrame(() => this.adjustSizeOnInput());
14649
14068
  KritzelKeyboardHelper.enableInteractiveWidget();
14650
14069
  }
14651
14070
  save() {
14652
- console.log('Saving text object', this.id);
14653
- // Store the current editor content
14654
- if (this.editor) {
14655
- this.content = this.editor.state.doc.toJSON();
14656
- // Disable the ProseMirror editor
14657
- this.editor.setProps({ editable: () => false });
14658
- this.editor.dom.blur(); // Remove focus
14659
- }
14071
+ requestAnimationFrame(() => this.adjustSizeOnInput());
14072
+ this.content = this.editor.state.doc.toJSON();
14073
+ this.editor.setProps({ editable: () => false });
14074
+ this.editor.dom.blur();
14660
14075
  this.isEditing = false;
14661
- this._core.history.executeCommand(new UpdateObjectCommand(this._core, this, this, this));
14076
+ let saveCommand;
14077
+ if (this.isNew) {
14078
+ this.isNew = false;
14079
+ saveCommand = new AddObjectCommand(this._core, this, this);
14080
+ }
14081
+ else {
14082
+ saveCommand = new UpdateObjectCommand(this._core, this, this.uneditedObject, { ...this });
14083
+ }
14084
+ this._core.commandManager.executeCommand(saveCommand);
14662
14085
  }
14663
14086
  handlePointerDown(event) {
14664
14087
  if (!this.isEditing) {
@@ -14678,14 +14101,37 @@ class KritzelText extends KritzelBaseObject {
14678
14101
  }
14679
14102
  event.stopPropagation();
14680
14103
  }
14104
+ copy() {
14105
+ const copiedObject = super.copy();
14106
+ copiedObject.editor = copiedObject.createEditor();
14107
+ if (this.content) {
14108
+ copiedObject.setContent(this.content);
14109
+ }
14110
+ return copiedObject;
14111
+ }
14681
14112
  serialize() {
14682
- const { _core, _elementRef, element, totalWidth, totalHeight, editor, ...remainingProps } = this;
14113
+ const { _core, _elementRef, _schema, element, totalWidth, totalHeight, editor, uneditedObject, ...remainingProps } = this;
14683
14114
  const clonedProps = structuredClone(remainingProps);
14684
14115
  if (element && typeof element === 'object' && 'nodeType' in element && element.nodeType === 1) {
14685
14116
  clonedProps.element = element.cloneNode(true);
14686
14117
  }
14687
14118
  return clonedProps;
14688
14119
  }
14120
+ deserialize(object) {
14121
+ super.deserialize(object);
14122
+ this.setContent(object.content);
14123
+ return this;
14124
+ }
14125
+ onExecuteUpdateCommand(updatedProperties) {
14126
+ if ('content' in updatedProperties) {
14127
+ this.setContent(updatedProperties.content);
14128
+ }
14129
+ }
14130
+ onUndoUpdateCommand(previousProperties) {
14131
+ if ('content' in previousProperties && this.editor) {
14132
+ this.setContent(previousProperties.content);
14133
+ }
14134
+ }
14689
14135
  }
14690
14136
 
14691
14137
  var cjs = {};
@@ -15089,22 +14535,6 @@ class KritzelEventHelper {
15089
14535
  }
15090
14536
  }
15091
14537
 
15092
- class AddObjectCommand extends KritzelBaseCommand {
15093
- object;
15094
- constructor(core, initiator, object, skipHistory = false) {
15095
- super(core, initiator, skipHistory);
15096
- this.object = object;
15097
- }
15098
- execute() {
15099
- this._core.store.state.objectsMap.insert(this.object);
15100
- this._core.addObjectToDatabase(this.object);
15101
- }
15102
- undo() {
15103
- this._core.store.state.objectsMap.remove(object => object.id === this.object.id);
15104
- this._core.deleteObjectFromDatabase(this.object.id);
15105
- }
15106
- }
15107
-
15108
14538
  class KritzelBaseTool {
15109
14539
  __class__ = this.constructor.name;
15110
14540
  name = 'base-tool';
@@ -15237,7 +14667,7 @@ class KritzelBrushTool extends KritzelBaseTool {
15237
14667
  const currentPath = this._core.store.state.currentPath;
15238
14668
  currentPath.zIndex = this._core.store.currentZIndex;
15239
14669
  this._core.store.state.currentPath = currentPath;
15240
- this._core.history.executeCommand(new AddObjectCommand(this._core, this, this._core.store.state.currentPath));
14670
+ this._core.commandManager.executeCommand(new AddObjectCommand(this._core, this, this._core.store.state.currentPath));
15241
14671
  }
15242
14672
  this._core.store.state.currentPath = undefined;
15243
14673
  }
@@ -15249,7 +14679,7 @@ class KritzelBrushTool extends KritzelBaseTool {
15249
14679
  const currentPath = this._core.store.state.currentPath;
15250
14680
  currentPath.zIndex = this._core.store.currentZIndex;
15251
14681
  this._core.store.state.currentPath = currentPath;
15252
- this._core.history.executeCommand(new AddObjectCommand(this._core, this, currentPath));
14682
+ this._core.commandManager.executeCommand(new AddObjectCommand(this._core, this, currentPath));
15253
14683
  }
15254
14684
  this._core.store.state.currentPath = undefined;
15255
14685
  this._core.rerender();
@@ -15272,59 +14702,6 @@ class BatchCommand extends KritzelBaseCommand {
15272
14702
  }
15273
14703
  }
15274
14704
 
15275
- class KritzelCustomElement extends KritzelBaseObject {
15276
- __class__ = 'KritzelCustomElement';
15277
- element;
15278
- isInteractive = true;
15279
- constructor(config) {
15280
- super();
15281
- if (config) {
15282
- this.translateX = config.translateX || 0;
15283
- this.translateY = config.translateY || 0;
15284
- this.scale = config.scale || 1;
15285
- this.element = config.element;
15286
- this.height = config.height || 0;
15287
- this.width = config.width || 0;
15288
- }
15289
- }
15290
- static create(core, config) {
15291
- const object = new KritzelCustomElement(config);
15292
- object._core = core;
15293
- object.id = object.generateId();
15294
- object.workspaceId = core.store.state.activeWorkspace.id;
15295
- return object;
15296
- }
15297
- mount(element) {
15298
- if (this.isMounted) {
15299
- return;
15300
- }
15301
- this.elementRef = element;
15302
- this.isMounted = true;
15303
- this.elementRef.appendChild(this.element);
15304
- }
15305
- resize(x, y, width, height) {
15306
- if (width <= 1 || height <= 1) {
15307
- return;
15308
- }
15309
- this.width = width;
15310
- this.height = height;
15311
- this.translateX = x;
15312
- this.translateY = y;
15313
- if (this.element) {
15314
- this.element.style.width = `${width}px`;
15315
- this.element.style.height = `${height}px`;
15316
- }
15317
- }
15318
- copy() {
15319
- const copiedObject = Object.create(Object.getPrototypeOf(this));
15320
- Object.assign(copiedObject, this);
15321
- copiedObject.id = this.generateId();
15322
- copiedObject.isMounted = false;
15323
- copiedObject.element = this.element.cloneNode(true);
15324
- return copiedObject;
15325
- }
15326
- }
15327
-
15328
14705
  class RemoveObjectCommand extends KritzelBaseCommand {
15329
14706
  object;
15330
14707
  constructor(core, initiator, object, skipHistory = false) {
@@ -15332,13 +14709,12 @@ class RemoveObjectCommand extends KritzelBaseCommand {
15332
14709
  this.object = object;
15333
14710
  }
15334
14711
  execute() {
14712
+ this.object.isMounted = false;
15335
14713
  this._core.store.state.objectsMap.remove(object => object.id === this.object.id);
15336
- this._core.store.state.objectsMap.filter(object => object instanceof KritzelCustomElement).forEach(object => object.remount());
15337
14714
  this._core.deleteObjectFromDatabase(this.object.id);
15338
14715
  }
15339
14716
  undo() {
15340
14717
  this._core.store.state.objectsMap.insert(this.object);
15341
- this._core.store.state.objectsMap.filter(object => object instanceof KritzelCustomElement).forEach(object => object.remount());
15342
14718
  this._core.addObjectToDatabase(this.object);
15343
14719
  }
15344
14720
  }
@@ -15401,7 +14777,7 @@ class KritzelEraserTool extends KritzelBaseTool {
15401
14777
  return new RemoveObjectCommand(this._core, this, object);
15402
14778
  });
15403
14779
  if (removeCommands.length > 0) {
15404
- this._core.history.executeCommand(new BatchCommand(this._core, this, removeCommands));
14780
+ this._core.commandManager.executeCommand(new BatchCommand(this._core, this, removeCommands));
15405
14781
  }
15406
14782
  this._core.store.state.isErasing = false;
15407
14783
  }
@@ -15416,7 +14792,7 @@ class KritzelEraserTool extends KritzelBaseTool {
15416
14792
  return new RemoveObjectCommand(this._core, this, object);
15417
14793
  });
15418
14794
  if (removeCommands.length > 0) {
15419
- this._core.history.executeCommand(new BatchCommand(this._core, this, removeCommands));
14795
+ this._core.commandManager.executeCommand(new BatchCommand(this._core, this, removeCommands));
15420
14796
  }
15421
14797
  this._core.store.state.isErasing = false;
15422
14798
  }
@@ -15567,10 +14943,15 @@ class KritzelMoveHandler extends KritzelBaseHandler {
15567
14943
  const clientY = event.clientY - this._core.store.offsetY;
15568
14944
  this.endX = clientX;
15569
14945
  this.endY = clientY;
15570
- this._core.store.state.selectionGroup.move(clientX, clientY, this.dragStartX, this.dragStartY);
15571
- this.dragStartX = clientX;
15572
- this.dragStartY = clientY;
15573
- this.hasMoved = true;
14946
+ const moveDeltaX = Math.abs(clientX - this.startX);
14947
+ const moveDeltaY = Math.abs(clientY - this.startY);
14948
+ const moveThreshold = 5;
14949
+ if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
14950
+ this._core.store.state.selectionGroup.move(clientX, clientY, this.dragStartX, this.dragStartY);
14951
+ this.dragStartX = clientX;
14952
+ this.dragStartY = clientY;
14953
+ this.hasMoved = true;
14954
+ }
15574
14955
  }
15575
14956
  }
15576
14957
  if (event.pointerType === 'touch') {
@@ -15605,7 +14986,7 @@ class KritzelMoveHandler extends KritzelBaseHandler {
15605
14986
  if (this._core.store.state.isDragging) {
15606
14987
  this._core.store.state.isDragging = false;
15607
14988
  if (this.hasMoved) {
15608
- this._core.history.executeCommand(new MoveSelectionGroupCommand(this._core, this, this.endX, this.endY, this.startX, this.startY, true));
14989
+ this._core.commandManager.executeCommand(new MoveSelectionGroupCommand(this._core, this, this.endX, this.endY, this.startX, this.startY, true));
15609
14990
  this._core.store.state.hasObjectsChanged = true;
15610
14991
  }
15611
14992
  }
@@ -15614,7 +14995,7 @@ class KritzelMoveHandler extends KritzelBaseHandler {
15614
14995
  if (this._core.store.state.isDragging) {
15615
14996
  this._core.store.state.isDragging = false;
15616
14997
  if (this.hasMoved) {
15617
- this._core.history.executeCommand(new MoveSelectionGroupCommand(this._core, this, this.endX, this.endY, this.startX, this.startY, true));
14998
+ this._core.commandManager.executeCommand(new MoveSelectionGroupCommand(this._core, this, this.endX, this.endY, this.startX, this.startY, true));
15618
14999
  this._core.store.state.hasObjectsChanged = true;
15619
15000
  }
15620
15001
  }
@@ -15664,6 +15045,7 @@ class KritzelResizeHandler extends KritzelBaseHandler {
15664
15045
  initialMouseY = 0;
15665
15046
  initialSize = { x: 0, y: 0, width: 0, height: 0 };
15666
15047
  newSize = { x: 0, y: 0, width: 0, height: 0 };
15048
+ hasResized = false;
15667
15049
  constructor(core) {
15668
15050
  super(core);
15669
15051
  }
@@ -15672,6 +15054,7 @@ class KritzelResizeHandler extends KritzelBaseHandler {
15672
15054
  this.initialMouseY = 0;
15673
15055
  this.initialSize = { x: 0, y: 0, width: 0, height: 0 };
15674
15056
  this.newSize = { x: 0, y: 0, width: 0, height: 0 };
15057
+ this.hasResized = false;
15675
15058
  }
15676
15059
  handlePointerDown(event) {
15677
15060
  if (event.pointerType === 'mouse') {
@@ -15718,6 +15101,15 @@ class KritzelResizeHandler extends KritzelBaseHandler {
15718
15101
  const clientY = event.clientY - this._core.store.offsetY;
15719
15102
  const dx = clientX - this.initialMouseX;
15720
15103
  const dy = clientY - this.initialMouseY;
15104
+ const resizeDeltaX = Math.abs(dx);
15105
+ const resizeDeltaY = Math.abs(dy);
15106
+ const resizeThreshold = 5;
15107
+ if (resizeDeltaX > resizeThreshold || resizeDeltaY > resizeThreshold) {
15108
+ this.hasResized = true;
15109
+ }
15110
+ if (!this.hasResized) {
15111
+ return;
15112
+ }
15721
15113
  switch (this._core.store.state.resizeHandleType) {
15722
15114
  case KritzelHandleType.TopLeft:
15723
15115
  this.newSize.width = this.initialSize.width - dx;
@@ -15758,6 +15150,16 @@ class KritzelResizeHandler extends KritzelBaseHandler {
15758
15150
  const clientY = Math.round(oneFingerTouch.clientY - this._core.store.offsetY);
15759
15151
  const dx = clientX - this.initialMouseX;
15760
15152
  const dy = clientY - this.initialMouseY;
15153
+ const resizeDeltaX = Math.abs(dx);
15154
+ const resizeDeltaY = Math.abs(dy);
15155
+ const resizeThreshold = 5;
15156
+ if (resizeDeltaX > resizeThreshold || resizeDeltaY > resizeThreshold) {
15157
+ clearTimeout(this._core.store.state.longTouchTimeout);
15158
+ this.hasResized = true;
15159
+ }
15160
+ if (!this.hasResized) {
15161
+ return;
15162
+ }
15761
15163
  switch (this._core.store.state.resizeHandleType) {
15762
15164
  case KritzelHandleType.TopLeft:
15763
15165
  this.newSize.width = this.initialSize.width - dx;
@@ -15785,24 +15187,27 @@ class KritzelResizeHandler extends KritzelBaseHandler {
15785
15187
  break;
15786
15188
  }
15787
15189
  this._core.store.state.selectionGroup.resize(this.newSize.x, this.newSize.y, this.newSize.width, this.newSize.height);
15788
- clearTimeout(this._core.store.state.longTouchTimeout);
15789
15190
  }
15790
15191
  }
15791
15192
  }
15792
15193
  handlePointerUp(event) {
15793
15194
  if (event.pointerType === 'mouse') {
15794
15195
  if (this._core.store.state.isResizing) {
15795
- this._core.history.executeCommand(new ResizeSelectionGroupCommand(this._core, this, structuredClone(this.initialSize), structuredClone(this.newSize)));
15796
15196
  this._core.store.state.isResizing = false;
15797
- this._core.store.state.hasObjectsChanged = true;
15197
+ if (this.hasResized) {
15198
+ this._core.commandManager.executeCommand(new ResizeSelectionGroupCommand(this._core, this, structuredClone(this.initialSize), structuredClone(this.newSize)));
15199
+ this._core.store.state.hasObjectsChanged = true;
15200
+ }
15798
15201
  this.reset();
15799
15202
  }
15800
15203
  }
15801
15204
  if (event.pointerType === 'touch') {
15802
15205
  if (this._core.store.state.isResizing) {
15803
- this._core.history.executeCommand(new ResizeSelectionGroupCommand(this._core, this, structuredClone(this.initialSize), structuredClone(this.newSize)));
15804
15206
  this._core.store.state.isResizing = false;
15805
- this._core.store.state.hasObjectsChanged = true;
15207
+ if (this.hasResized) {
15208
+ this._core.commandManager.executeCommand(new ResizeSelectionGroupCommand(this._core, this, structuredClone(this.initialSize), structuredClone(this.newSize)));
15209
+ this._core.store.state.hasObjectsChanged = true;
15210
+ }
15806
15211
  this.reset();
15807
15212
  clearTimeout(this._core.store.state.longTouchTimeout);
15808
15213
  }
@@ -15928,7 +15333,7 @@ class KritzelRotationHandler extends KritzelBaseHandler {
15928
15333
  handlePointerUp(event) {
15929
15334
  if (event.pointerType === 'mouse') {
15930
15335
  if (this._core.store.state.isRotating) {
15931
- this._core.history.executeCommand(new RotateSelectionGroupCommand(this._core, this, this.rotation, this.initialSelectionGroupRotation));
15336
+ this._core.commandManager.executeCommand(new RotateSelectionGroupCommand(this._core, this, this.rotation, this.initialSelectionGroupRotation));
15932
15337
  this._core.store.state.isRotating = false;
15933
15338
  this._core.store.state.hasObjectsChanged = true;
15934
15339
  this.reset();
@@ -15936,7 +15341,7 @@ class KritzelRotationHandler extends KritzelBaseHandler {
15936
15341
  }
15937
15342
  if (event.pointerType === 'touch') {
15938
15343
  if (this._core.store.state.isRotating) {
15939
- this._core.history.executeCommand(new RotateSelectionGroupCommand(this._core, this, this.rotation, this.initialSelectionGroupRotation));
15344
+ this._core.commandManager.executeCommand(new RotateSelectionGroupCommand(this._core, this, this.rotation, this.initialSelectionGroupRotation));
15940
15345
  this._core.store.state.isRotating = false;
15941
15346
  this._core.store.state.hasObjectsChanged = true;
15942
15347
  this.reset();
@@ -16040,7 +15445,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
16040
15445
  if (KritzelEventHelper.isLeftClick(event)) {
16041
15446
  const hasObjectsMoved = this._core.store.state.hasObjectsChanged;
16042
15447
  if (this._core.store.state.selectionGroup?.objects.length === 1 && hasObjectsMoved === false) {
16043
- this._core.store.state.selectionGroup.objects[0].edit();
15448
+ this._core.store.state.selectionGroup.objects[0].edit(event);
16044
15449
  }
16045
15450
  this._core.store.state.hasObjectsChanged = false;
16046
15451
  if (this._core.store.state.isSelecting) {
@@ -16059,7 +15464,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
16059
15464
  clearTimeout(this.touchStartTimeout);
16060
15465
  const hasObjectsMoved = this._core.store.state.hasObjectsChanged;
16061
15466
  if (this._core.store.state.selectionGroup?.objects.length === 1 && hasObjectsMoved === false) {
16062
- this._core.store.state.selectionGroup.objects[0].edit();
15467
+ this._core.store.state.selectionGroup.objects[0].edit(event);
16063
15468
  }
16064
15469
  this._core.store.state.hasObjectsChanged = false;
16065
15470
  if (this._core.store.state.isSelecting) {
@@ -16202,7 +15607,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
16202
15607
  selectionGroup.addOrRemove(object);
16203
15608
  selectionGroup.isSelected = true;
16204
15609
  selectionGroup.rotation = object.rotation;
16205
- this._core.history.executeCommand(new AddSelectionGroupCommand(this._core, this, selectionGroup));
15610
+ this._core.commandManager.executeCommand(new AddSelectionGroupCommand(this._core, this, selectionGroup));
16206
15611
  }
16207
15612
  addSelectedObjectsToSelectionGroup() {
16208
15613
  const selectedObjects = this._core.store.selectedObjects;
@@ -16219,7 +15624,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
16219
15624
  if (selectionGroup.length === 1) {
16220
15625
  selectionGroup.rotation = selectionGroup.objects[0].rotation;
16221
15626
  }
16222
- this._core.history.executeCommand(new AddSelectionGroupCommand(this._core, this, selectionGroup));
15627
+ this._core.commandManager.executeCommand(new AddSelectionGroupCommand(this._core, this, selectionGroup));
16223
15628
  }
16224
15629
  }
16225
15630
 
@@ -16268,7 +15673,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
16268
15673
  this._core.store.state.selectionGroup &&
16269
15674
  !this._core.store.state.isResizeHandleSelected &&
16270
15675
  !this._core.store.state.isRotationHandleSelected) {
16271
- this._core.history.executeCommand(new RemoveSelectionGroupCommand(this._core, this._core.store.state.selectionGroup));
15676
+ this._core.commandManager.executeCommand(new RemoveSelectionGroupCommand(this._core, this._core.store.state.selectionGroup));
16272
15677
  }
16273
15678
  if (selectedObject && selectedObject.isSelected === false && selectedObject?.objects.length === 1 && selectedObject.objects[0].isInteractive) {
16274
15679
  return;
@@ -16297,7 +15702,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
16297
15702
  this._core.store.state.selectionGroup &&
16298
15703
  !this._core.store.state.isResizeHandleSelected &&
16299
15704
  !this._core.store.state.isRotationHandleSelected) {
16300
- this._core.history.executeCommand(new RemoveSelectionGroupCommand(this._core, this._core.store.state.selectionGroup));
15705
+ this._core.commandManager.executeCommand(new RemoveSelectionGroupCommand(this._core, this._core.store.state.selectionGroup));
16301
15706
  }
16302
15707
  }
16303
15708
  this.rotationHandler.handlePointerDown(event);
@@ -16423,14 +15828,15 @@ class KritzelTextTool extends KritzelBaseTool {
16423
15828
  const path = event.composedPath().slice(1);
16424
15829
  const objectElement = path.find(element => element.classList && element.classList.contains('object'));
16425
15830
  const object = this._core.findObjectById(objectElement?.id);
16426
- if (object instanceof KritzelText) {
15831
+ if (this._core.store.state.activeText === null && object instanceof KritzelText) {
16427
15832
  this._core.store.state.activeText = object;
16428
- object.focus();
15833
+ object.edit(event);
16429
15834
  return;
16430
15835
  }
16431
15836
  if (this._core.store.state.activeText !== null && object instanceof KritzelText) {
15837
+ this._core.store.state.activeText.save();
16432
15838
  this._core.store.state.activeText = object;
16433
- object.focus();
15839
+ object.edit(event);
16434
15840
  return;
16435
15841
  }
16436
15842
  if (this._core.store.state.activeText !== null && object instanceof KritzelText === false) {
@@ -16444,26 +15850,30 @@ class KritzelTextTool extends KritzelBaseTool {
16444
15850
  const clientX = event.clientX - this._core.store.offsetX;
16445
15851
  const clientY = event.clientY - this._core.store.offsetY;
16446
15852
  const text = KritzelText.create(this._core, this.fontSize, this.fontFamily);
15853
+ text.isNew = true;
16447
15854
  text.fontColor = this.fontColor;
16448
15855
  text.translateX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;
16449
15856
  text.translateY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;
16450
15857
  text.zIndex = this._core.store.currentZIndex;
16451
15858
  this._core.store.state.activeText = text;
16452
- this._core.history.executeCommand(new AddObjectCommand(this._core, this, text));
15859
+ this._core.store.state.objectsMap.insert(text);
15860
+ this._core.rerender();
15861
+ requestAnimationFrame(() => text.edit(event));
16453
15862
  }
16454
15863
  if (event.pointerType === 'touch') {
16455
15864
  const activePointers = Array.from(this._core.store.state.pointers.values());
16456
15865
  const path = event.composedPath().slice(1);
16457
15866
  const objectElement = path.find(element => element.classList && element.classList.contains('object'));
16458
15867
  const object = this._core.findObjectById(objectElement?.id);
16459
- if (object instanceof KritzelText) {
15868
+ if (this._core.store.state.activeText === null && object instanceof KritzelText) {
16460
15869
  this._core.store.state.activeText = object;
16461
- object.focus();
15870
+ object.edit(event);
16462
15871
  return;
16463
15872
  }
16464
15873
  if (this._core.store.state.activeText !== null && object instanceof KritzelText) {
15874
+ this._core.store.state.activeText.save();
16465
15875
  this._core.store.state.activeText = object;
16466
- object.focus();
15876
+ object.edit(event);
16467
15877
  return;
16468
15878
  }
16469
15879
  if (this._core.store.state.activeText !== null && object instanceof KritzelText === false) {
@@ -16478,12 +15888,14 @@ class KritzelTextTool extends KritzelBaseTool {
16478
15888
  const clientX = Math.round(activePointers[0].clientX - this._core.store.offsetX);
16479
15889
  const clientY = Math.round(activePointers[0].clientY - this._core.store.offsetY);
16480
15890
  const text = KritzelText.create(this._core, this.fontSize, this.fontFamily);
15891
+ text.isNew = true;
16481
15892
  text.fontColor = this.fontColor;
16482
15893
  text.translateX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;
16483
15894
  text.translateY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;
16484
15895
  text.zIndex = this._core.store.currentZIndex;
16485
15896
  this._core.store.state.activeText = text;
16486
- this._core.history.executeCommand(new AddObjectCommand(this._core, this, text));
15897
+ this._core.store.state.objectsMap.insert(text);
15898
+ this._core.rerender();
16487
15899
  }
16488
15900
  }
16489
15901
  handlePointerUp(event) {
@@ -16491,15 +15903,74 @@ class KritzelTextTool extends KritzelBaseTool {
16491
15903
  event.preventDefault();
16492
15904
  }
16493
15905
  if (event.pointerType === 'mouse') {
16494
- this._core.store.state.activeText?.edit();
15906
+ this._core.store.state.activeText?.edit(event);
16495
15907
  }
16496
15908
  if (event.pointerType === 'touch') {
16497
- this._core.store.state.activeText?.edit();
15909
+ this._core.store.state.activeText?.edit(event);
16498
15910
  KritzelKeyboardHelper.enableInteractiveWidget();
16499
15911
  }
16500
15912
  }
16501
15913
  }
16502
15914
 
15915
+ class KritzelCustomElement extends KritzelBaseObject {
15916
+ __class__ = 'KritzelCustomElement';
15917
+ element;
15918
+ isInteractive = true;
15919
+ constructor(config) {
15920
+ super();
15921
+ if (config) {
15922
+ this.translateX = config.translateX || 0;
15923
+ this.translateY = config.translateY || 0;
15924
+ this.scale = config.scale || 1;
15925
+ this.element = config.element;
15926
+ this.height = config.height || 0;
15927
+ this.width = config.width || 0;
15928
+ }
15929
+ }
15930
+ static create(core, config) {
15931
+ const object = new KritzelCustomElement(config);
15932
+ object._core = core;
15933
+ object.id = object.generateId();
15934
+ object.workspaceId = core.store.state.activeWorkspace.id;
15935
+ return object;
15936
+ }
15937
+ mount(element) {
15938
+ if (element === null) {
15939
+ return;
15940
+ }
15941
+ // If already mounted to the same element and content is still attached, skip
15942
+ if (this.isMounted && this.elementRef === element && this.element.parentElement === element) {
15943
+ return;
15944
+ }
15945
+ this.elementRef = element;
15946
+ this.isMounted = true;
15947
+ // Clear existing content and append the element
15948
+ this.elementRef.innerHTML = '';
15949
+ this.elementRef.appendChild(this.element);
15950
+ }
15951
+ resize(x, y, width, height) {
15952
+ if (width <= 1 || height <= 1) {
15953
+ return;
15954
+ }
15955
+ this.width = width;
15956
+ this.height = height;
15957
+ this.translateX = x;
15958
+ this.translateY = y;
15959
+ if (this.element) {
15960
+ this.element.style.width = `${width}px`;
15961
+ this.element.style.height = `${height}px`;
15962
+ }
15963
+ }
15964
+ copy() {
15965
+ const copiedObject = Object.create(Object.getPrototypeOf(this));
15966
+ Object.assign(copiedObject, this);
15967
+ copiedObject.id = this.generateId();
15968
+ copiedObject.isMounted = false;
15969
+ copiedObject.element = this.element.cloneNode(true);
15970
+ return copiedObject;
15971
+ }
15972
+ }
15973
+
16503
15974
  const DEFAULT_BRUSH_CONFIG = {
16504
15975
  type: 'pen',
16505
15976
  color: '#000000',
@@ -16941,7 +16412,7 @@ class KritzelImageTool extends KritzelBaseTool {
16941
16412
  selectionGroup.isSelected = true;
16942
16413
  const addImageCommand = new AddObjectCommand(this._core, this, image);
16943
16414
  const addSelectionGroupCommand = new AddSelectionGroupCommand(this._core, this, selectionGroup);
16944
- this._core.history.executeCommand(new BatchCommand(this._core, this, [addImageCommand, addSelectionGroupCommand]));
16415
+ this._core.commandManager.executeCommand(new BatchCommand(this._core, this, [addImageCommand, addSelectionGroupCommand]));
16945
16416
  this._core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
16946
16417
  }
16947
16418
  handleCancel() {
@@ -16976,6 +16447,6 @@ exports.ObjectHelper = ObjectHelper;
16976
16447
  exports.RemoveObjectCommand = RemoveObjectCommand;
16977
16448
  exports.RemoveSelectionGroupCommand = RemoveSelectionGroupCommand;
16978
16449
  exports.UpdateObjectCommand = UpdateObjectCommand;
16979
- //# sourceMappingURL=index-BKstgWru.js.map
16450
+ //# sourceMappingURL=index-SaGfCHX3.js.map
16980
16451
 
16981
- //# sourceMappingURL=index-BKstgWru.js.map
16452
+ //# sourceMappingURL=index-SaGfCHX3.js.map