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.
- package/dist/cjs/{index-BKstgWru.js → index-SaGfCHX3.js} +276 -805
- package/dist/cjs/index-SaGfCHX3.js.map +1 -0
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/kritzel-color_22.cjs.entry.js +114 -77
- package/dist/collection/classes/commands/add-object.command.js +1 -0
- package/dist/collection/classes/commands/add-object.command.js.map +1 -1
- package/dist/collection/classes/commands/base.command.js +2 -0
- package/dist/collection/classes/commands/base.command.js.map +1 -1
- package/dist/collection/classes/commands/remove-object.command.js +1 -3
- package/dist/collection/classes/commands/remove-object.command.js.map +1 -1
- package/dist/collection/classes/commands/update-object.command.js +2 -0
- package/dist/collection/classes/commands/update-object.command.js.map +1 -1
- package/dist/collection/classes/core/command-manager.class.js +51 -0
- package/dist/collection/classes/core/command-manager.class.js.map +1 -0
- package/dist/collection/classes/core/core.class.js +23 -14
- package/dist/collection/classes/core/core.class.js.map +1 -1
- package/dist/collection/classes/core/history.class.js +2 -40
- package/dist/collection/classes/core/history.class.js.map +1 -1
- package/dist/collection/classes/core/viewport.class.js +16 -5
- package/dist/collection/classes/core/viewport.class.js.map +1 -1
- package/dist/collection/classes/handlers/context-menu.handler.js +1 -1
- package/dist/collection/classes/handlers/context-menu.handler.js.map +1 -1
- package/dist/collection/classes/handlers/move.handler.js +11 -6
- package/dist/collection/classes/handlers/move.handler.js.map +1 -1
- package/dist/collection/classes/handlers/resize.handler.js +29 -5
- package/dist/collection/classes/handlers/resize.handler.js.map +1 -1
- package/dist/collection/classes/handlers/rotation.handler.js +2 -2
- package/dist/collection/classes/handlers/rotation.handler.js.map +1 -1
- package/dist/collection/classes/handlers/selection.handler.js +4 -4
- package/dist/collection/classes/handlers/selection.handler.js.map +1 -1
- package/dist/collection/classes/objects/base-object.class.js +15 -14
- package/dist/collection/classes/objects/base-object.class.js.map +1 -1
- package/dist/collection/classes/objects/custom-element.class.js +7 -1
- package/dist/collection/classes/objects/custom-element.class.js.map +1 -1
- package/dist/collection/classes/objects/text.class.js +109 -49
- package/dist/collection/classes/objects/text.class.js.map +1 -1
- package/dist/collection/classes/tools/brush-tool.class.js +2 -2
- package/dist/collection/classes/tools/brush-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/eraser-tool.class.js +2 -2
- package/dist/collection/classes/tools/eraser-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/image-tool.class.js +1 -1
- package/dist/collection/classes/tools/image-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/selection-tool.class.js +2 -2
- package/dist/collection/classes/tools/selection-tool.class.js.map +1 -1
- package/dist/collection/classes/tools/text-tool.class.js +17 -11
- package/dist/collection/classes/tools/text-tool.class.js.map +1 -1
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +1 -1
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +21 -15
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
- package/dist/collection/interfaces/object.interface.js.map +1 -1
- package/dist/components/index.js +2 -2
- package/dist/components/kritzel-controls.js +1 -1
- package/dist/components/kritzel-editor.js +3 -3
- package/dist/components/kritzel-engine.js +1 -1
- package/dist/components/{p-ChLi4Ufe.js → p-C8calcQF.js} +3 -3
- package/dist/components/{p-ChLi4Ufe.js.map → p-C8calcQF.js.map} +1 -1
- package/dist/components/{p-BuDVaqTF.js → p-CZk591FE.js} +165 -728
- package/dist/components/p-CZk591FE.js.map +1 -0
- package/dist/components/{p-C4nj29RW.js → p-CziwfEQh.js} +227 -156
- package/dist/components/p-CziwfEQh.js.map +1 -0
- package/dist/esm/{index-D0Q2MKPn.js → index-SIM_s7ed.js} +276 -805
- package/dist/esm/index-SIM_s7ed.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/kritzel-color_22.entry.js +114 -77
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/p-SIM_s7ed.js +2 -0
- package/dist/stencil/p-SIM_s7ed.js.map +1 -0
- package/dist/stencil/p-b697b2c1.entry.js +2 -0
- package/dist/stencil/p-b697b2c1.entry.js.map +1 -0
- package/dist/stencil/stencil.esm.js +1 -1
- package/dist/types/classes/commands/add-object.command.d.ts +2 -2
- package/dist/types/classes/commands/base.command.d.ts +2 -1
- package/dist/types/classes/commands/remove-object.command.d.ts +2 -2
- package/dist/types/classes/commands/update-object.command.d.ts +2 -2
- package/dist/types/classes/core/command-manager.class.d.ts +16 -0
- package/dist/types/classes/core/core.class.d.ts +4 -0
- package/dist/types/classes/core/history.class.d.ts +0 -8
- package/dist/types/classes/core/viewport.class.d.ts +2 -0
- package/dist/types/classes/handlers/resize.handler.d.ts +1 -0
- package/dist/types/classes/objects/base-object.class.d.ts +6 -4
- package/dist/types/classes/objects/text.class.d.ts +13 -2
- package/dist/types/interfaces/object.interface.d.ts +1 -3
- package/package.json +1 -1
- package/dist/cjs/index-BKstgWru.js.map +0 -1
- package/dist/components/p-BuDVaqTF.js.map +0 -1
- package/dist/components/p-C4nj29RW.js.map +0 -1
- package/dist/esm/index-D0Q2MKPn.js.map +0 -1
- package/dist/stencil/p-73784709.entry.js +0 -2
- package/dist/stencil/p-73784709.entry.js.map +0 -1
- package/dist/stencil/p-D0Q2MKPn.js +0 -2
- 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 =
|
|
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;
|
|
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 (
|
|
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
|
-
|
|
14581
|
-
|
|
14582
|
-
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
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
|
|
14633
|
-
|
|
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
|
-
|
|
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
|
-
|
|
14653
|
-
|
|
14654
|
-
|
|
14655
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
15571
|
-
|
|
15572
|
-
|
|
15573
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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-
|
|
16450
|
+
//# sourceMappingURL=index-SaGfCHX3.js.map
|
|
16980
16451
|
|
|
16981
|
-
//# sourceMappingURL=index-
|
|
16452
|
+
//# sourceMappingURL=index-SaGfCHX3.js.map
|