kritzel-stencil 0.0.141 → 0.0.143
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-Cg50mv2K.js} +293 -811
- package/dist/cjs/index-Cg50mv2K.js.map +1 -0
- package/dist/cjs/index.cjs.js +1 -1
- package/dist/cjs/kritzel-color_22.cjs.entry.js +116 -79
- 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 +17 -7
- 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 +126 -52
- 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 +22 -16
- package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
- package/dist/collection/helpers/event.helper.js +0 -3
- package/dist/collection/helpers/event.helper.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-BAw249L9.js} +3 -3
- package/dist/components/{p-ChLi4Ufe.js.map → p-BAw249L9.js.map} +1 -1
- package/dist/components/{p-BuDVaqTF.js → p-CoFmi-t6.js} +182 -734
- package/dist/components/p-CoFmi-t6.js.map +1 -0
- package/dist/components/{p-C4nj29RW.js → p-EO13AYoE.js} +229 -158
- package/dist/components/p-EO13AYoE.js.map +1 -0
- package/dist/esm/{index-D0Q2MKPn.js → index-Bj5QIJYQ.js} +294 -812
- package/dist/esm/index-Bj5QIJYQ.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/kritzel-color_22.entry.js +116 -79
- package/dist/stencil/index.esm.js +1 -1
- package/dist/stencil/p-Bj5QIJYQ.js +2 -0
- package/dist/stencil/p-Bj5QIJYQ.js.map +1 -0
- package/dist/stencil/p-b4185842.entry.js +2 -0
- package/dist/stencil/p-b4185842.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/helpers/event.helper.d.ts +0 -1
- 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,80 @@ 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) {
|
|
14009
|
+
const previousTotalWidth = this.totalWidth;
|
|
14010
|
+
const previousTotalHeight = this.totalHeight;
|
|
14607
14011
|
const newWidth = element.scrollWidth;
|
|
14608
14012
|
const newHeight = element.scrollHeight;
|
|
14609
|
-
|
|
14610
|
-
|
|
14611
|
-
|
|
14612
|
-
this.
|
|
14013
|
+
this.width = newWidth * this.scaleFactor;
|
|
14014
|
+
this.height = newHeight * this.scaleFactor;
|
|
14015
|
+
if (this.rotation !== 0) {
|
|
14016
|
+
const newTotalWidth = this.totalWidth;
|
|
14017
|
+
const newTotalHeight = this.totalHeight;
|
|
14018
|
+
const deltaWidth = (newTotalWidth - previousTotalWidth) / 2;
|
|
14019
|
+
const deltaHeight = (newTotalHeight - previousTotalHeight) / 2;
|
|
14020
|
+
if (deltaWidth !== 0 || deltaHeight !== 0) {
|
|
14021
|
+
const cos = Math.cos(this.rotation);
|
|
14022
|
+
const sin = Math.sin(this.rotation);
|
|
14023
|
+
const rotatedDeltaX = cos * deltaWidth - sin * deltaHeight;
|
|
14024
|
+
const rotatedDeltaY = sin * deltaWidth + cos * deltaHeight;
|
|
14025
|
+
this.translateX += rotatedDeltaX - deltaWidth;
|
|
14026
|
+
this.translateY += rotatedDeltaY - deltaHeight;
|
|
14027
|
+
}
|
|
14613
14028
|
}
|
|
14614
14029
|
}
|
|
14030
|
+
if (this._core) {
|
|
14031
|
+
this._core.store.state.objectsMap.update(this);
|
|
14032
|
+
this._core.rerender();
|
|
14033
|
+
}
|
|
14615
14034
|
}
|
|
14616
14035
|
resize(x, y, width, height) {
|
|
14617
14036
|
if (width <= 1 || height <= 1) {
|
|
@@ -14627,38 +14046,56 @@ class KritzelText extends KritzelBaseObject {
|
|
|
14627
14046
|
this.translateX = x;
|
|
14628
14047
|
this.translateY = y;
|
|
14629
14048
|
}
|
|
14630
|
-
focus() {
|
|
14049
|
+
focus(coords) {
|
|
14631
14050
|
if (this.editor) {
|
|
14632
|
-
const
|
|
14633
|
-
|
|
14051
|
+
const doc = this.editor.state.doc;
|
|
14052
|
+
if (coords) {
|
|
14053
|
+
const pos = this.editor.posAtCoords({ left: coords.x, top: coords.y });
|
|
14054
|
+
if (pos) {
|
|
14055
|
+
this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
|
|
14056
|
+
this.editor.focus();
|
|
14057
|
+
return;
|
|
14058
|
+
}
|
|
14059
|
+
}
|
|
14060
|
+
const end = Math.max(1, doc.content.size - 1);
|
|
14061
|
+
this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, end)));
|
|
14634
14062
|
this.editor.focus();
|
|
14635
14063
|
}
|
|
14636
14064
|
}
|
|
14637
|
-
edit() {
|
|
14638
|
-
console.log('Editing text object', this.id);
|
|
14065
|
+
edit(event) {
|
|
14639
14066
|
KritzelKeyboardHelper.disableInteractiveWidget();
|
|
14067
|
+
this.uneditedObject = this.clone();
|
|
14640
14068
|
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('text'));
|
|
14641
14069
|
this._core.store.state.activeText = this;
|
|
14642
|
-
this._core.clearSelection();
|
|
14643
|
-
// Enable the ProseMirror editor
|
|
14644
14070
|
if (this.editor) {
|
|
14645
14071
|
this.editor.setProps({ editable: () => true });
|
|
14646
14072
|
}
|
|
14647
14073
|
this.isEditing = true;
|
|
14648
|
-
|
|
14074
|
+
if (event) {
|
|
14075
|
+
this.focus({ x: event.clientX, y: event.clientY });
|
|
14076
|
+
}
|
|
14077
|
+
else {
|
|
14078
|
+
this.focus();
|
|
14079
|
+
}
|
|
14080
|
+
this._core.rerender();
|
|
14081
|
+
requestAnimationFrame(() => this.adjustSizeOnInput());
|
|
14649
14082
|
KritzelKeyboardHelper.enableInteractiveWidget();
|
|
14650
14083
|
}
|
|
14651
14084
|
save() {
|
|
14652
|
-
|
|
14653
|
-
|
|
14654
|
-
|
|
14655
|
-
|
|
14656
|
-
// Disable the ProseMirror editor
|
|
14657
|
-
this.editor.setProps({ editable: () => false });
|
|
14658
|
-
this.editor.dom.blur(); // Remove focus
|
|
14659
|
-
}
|
|
14085
|
+
requestAnimationFrame(() => this.adjustSizeOnInput());
|
|
14086
|
+
this.content = this.editor.state.doc.toJSON();
|
|
14087
|
+
this.editor.setProps({ editable: () => false });
|
|
14088
|
+
this.editor.dom.blur();
|
|
14660
14089
|
this.isEditing = false;
|
|
14661
|
-
|
|
14090
|
+
let saveCommand;
|
|
14091
|
+
if (this.isNew) {
|
|
14092
|
+
this.isNew = false;
|
|
14093
|
+
saveCommand = new AddObjectCommand(this._core, this, this);
|
|
14094
|
+
}
|
|
14095
|
+
else {
|
|
14096
|
+
saveCommand = new UpdateObjectCommand(this._core, this, this.uneditedObject, { ...this });
|
|
14097
|
+
}
|
|
14098
|
+
this._core.commandManager.executeCommand(saveCommand);
|
|
14662
14099
|
}
|
|
14663
14100
|
handlePointerDown(event) {
|
|
14664
14101
|
if (!this.isEditing) {
|
|
@@ -14678,14 +14115,37 @@ class KritzelText extends KritzelBaseObject {
|
|
|
14678
14115
|
}
|
|
14679
14116
|
event.stopPropagation();
|
|
14680
14117
|
}
|
|
14118
|
+
copy() {
|
|
14119
|
+
const copiedObject = super.copy();
|
|
14120
|
+
copiedObject.editor = copiedObject.createEditor();
|
|
14121
|
+
if (this.content) {
|
|
14122
|
+
copiedObject.setContent(this.content);
|
|
14123
|
+
}
|
|
14124
|
+
return copiedObject;
|
|
14125
|
+
}
|
|
14681
14126
|
serialize() {
|
|
14682
|
-
const { _core, _elementRef, element, totalWidth, totalHeight, editor, ...remainingProps } = this;
|
|
14127
|
+
const { _core, _elementRef, _schema, element, totalWidth, totalHeight, editor, uneditedObject, ...remainingProps } = this;
|
|
14683
14128
|
const clonedProps = structuredClone(remainingProps);
|
|
14684
14129
|
if (element && typeof element === 'object' && 'nodeType' in element && element.nodeType === 1) {
|
|
14685
14130
|
clonedProps.element = element.cloneNode(true);
|
|
14686
14131
|
}
|
|
14687
14132
|
return clonedProps;
|
|
14688
14133
|
}
|
|
14134
|
+
deserialize(object) {
|
|
14135
|
+
super.deserialize(object);
|
|
14136
|
+
this.setContent(object.content);
|
|
14137
|
+
return this;
|
|
14138
|
+
}
|
|
14139
|
+
onExecuteUpdateCommand(updatedProperties) {
|
|
14140
|
+
if ('content' in updatedProperties) {
|
|
14141
|
+
this.setContent(updatedProperties.content);
|
|
14142
|
+
}
|
|
14143
|
+
}
|
|
14144
|
+
onUndoUpdateCommand(previousProperties) {
|
|
14145
|
+
if ('content' in previousProperties && this.editor) {
|
|
14146
|
+
this.setContent(previousProperties.content);
|
|
14147
|
+
}
|
|
14148
|
+
}
|
|
14689
14149
|
}
|
|
14690
14150
|
|
|
14691
14151
|
var cjs = {};
|
|
@@ -15043,9 +14503,6 @@ class KritzelEventHelper {
|
|
|
15043
14503
|
static isLeftClick(ev) {
|
|
15044
14504
|
return ev.button === exports.KritzelMouseButton.Left;
|
|
15045
14505
|
}
|
|
15046
|
-
static isMainMouseWheel(event) {
|
|
15047
|
-
return Math.abs(event.deltaY) > 0 && Math.abs(event.deltaX) === 0 && Number.isInteger(event.deltaY);
|
|
15048
|
-
}
|
|
15049
14506
|
static isPointerEventOnContextMenu(event) {
|
|
15050
14507
|
const path = event.composedPath();
|
|
15051
14508
|
const contextMenu = path.find(element => element.classList && element.classList.contains('context-menu'));
|
|
@@ -15089,22 +14546,6 @@ class KritzelEventHelper {
|
|
|
15089
14546
|
}
|
|
15090
14547
|
}
|
|
15091
14548
|
|
|
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
14549
|
class KritzelBaseTool {
|
|
15109
14550
|
__class__ = this.constructor.name;
|
|
15110
14551
|
name = 'base-tool';
|
|
@@ -15237,7 +14678,7 @@ class KritzelBrushTool extends KritzelBaseTool {
|
|
|
15237
14678
|
const currentPath = this._core.store.state.currentPath;
|
|
15238
14679
|
currentPath.zIndex = this._core.store.currentZIndex;
|
|
15239
14680
|
this._core.store.state.currentPath = currentPath;
|
|
15240
|
-
this._core.
|
|
14681
|
+
this._core.commandManager.executeCommand(new AddObjectCommand(this._core, this, this._core.store.state.currentPath));
|
|
15241
14682
|
}
|
|
15242
14683
|
this._core.store.state.currentPath = undefined;
|
|
15243
14684
|
}
|
|
@@ -15249,7 +14690,7 @@ class KritzelBrushTool extends KritzelBaseTool {
|
|
|
15249
14690
|
const currentPath = this._core.store.state.currentPath;
|
|
15250
14691
|
currentPath.zIndex = this._core.store.currentZIndex;
|
|
15251
14692
|
this._core.store.state.currentPath = currentPath;
|
|
15252
|
-
this._core.
|
|
14693
|
+
this._core.commandManager.executeCommand(new AddObjectCommand(this._core, this, currentPath));
|
|
15253
14694
|
}
|
|
15254
14695
|
this._core.store.state.currentPath = undefined;
|
|
15255
14696
|
this._core.rerender();
|
|
@@ -15272,59 +14713,6 @@ class BatchCommand extends KritzelBaseCommand {
|
|
|
15272
14713
|
}
|
|
15273
14714
|
}
|
|
15274
14715
|
|
|
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
14716
|
class RemoveObjectCommand extends KritzelBaseCommand {
|
|
15329
14717
|
object;
|
|
15330
14718
|
constructor(core, initiator, object, skipHistory = false) {
|
|
@@ -15332,13 +14720,12 @@ class RemoveObjectCommand extends KritzelBaseCommand {
|
|
|
15332
14720
|
this.object = object;
|
|
15333
14721
|
}
|
|
15334
14722
|
execute() {
|
|
14723
|
+
this.object.isMounted = false;
|
|
15335
14724
|
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
14725
|
this._core.deleteObjectFromDatabase(this.object.id);
|
|
15338
14726
|
}
|
|
15339
14727
|
undo() {
|
|
15340
14728
|
this._core.store.state.objectsMap.insert(this.object);
|
|
15341
|
-
this._core.store.state.objectsMap.filter(object => object instanceof KritzelCustomElement).forEach(object => object.remount());
|
|
15342
14729
|
this._core.addObjectToDatabase(this.object);
|
|
15343
14730
|
}
|
|
15344
14731
|
}
|
|
@@ -15401,7 +14788,7 @@ class KritzelEraserTool extends KritzelBaseTool {
|
|
|
15401
14788
|
return new RemoveObjectCommand(this._core, this, object);
|
|
15402
14789
|
});
|
|
15403
14790
|
if (removeCommands.length > 0) {
|
|
15404
|
-
this._core.
|
|
14791
|
+
this._core.commandManager.executeCommand(new BatchCommand(this._core, this, removeCommands));
|
|
15405
14792
|
}
|
|
15406
14793
|
this._core.store.state.isErasing = false;
|
|
15407
14794
|
}
|
|
@@ -15416,7 +14803,7 @@ class KritzelEraserTool extends KritzelBaseTool {
|
|
|
15416
14803
|
return new RemoveObjectCommand(this._core, this, object);
|
|
15417
14804
|
});
|
|
15418
14805
|
if (removeCommands.length > 0) {
|
|
15419
|
-
this._core.
|
|
14806
|
+
this._core.commandManager.executeCommand(new BatchCommand(this._core, this, removeCommands));
|
|
15420
14807
|
}
|
|
15421
14808
|
this._core.store.state.isErasing = false;
|
|
15422
14809
|
}
|
|
@@ -15567,10 +14954,15 @@ class KritzelMoveHandler extends KritzelBaseHandler {
|
|
|
15567
14954
|
const clientY = event.clientY - this._core.store.offsetY;
|
|
15568
14955
|
this.endX = clientX;
|
|
15569
14956
|
this.endY = clientY;
|
|
15570
|
-
|
|
15571
|
-
|
|
15572
|
-
|
|
15573
|
-
|
|
14957
|
+
const moveDeltaX = Math.abs(clientX - this.startX);
|
|
14958
|
+
const moveDeltaY = Math.abs(clientY - this.startY);
|
|
14959
|
+
const moveThreshold = 5;
|
|
14960
|
+
if (moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
|
|
14961
|
+
this._core.store.state.selectionGroup.move(clientX, clientY, this.dragStartX, this.dragStartY);
|
|
14962
|
+
this.dragStartX = clientX;
|
|
14963
|
+
this.dragStartY = clientY;
|
|
14964
|
+
this.hasMoved = true;
|
|
14965
|
+
}
|
|
15574
14966
|
}
|
|
15575
14967
|
}
|
|
15576
14968
|
if (event.pointerType === 'touch') {
|
|
@@ -15605,7 +14997,7 @@ class KritzelMoveHandler extends KritzelBaseHandler {
|
|
|
15605
14997
|
if (this._core.store.state.isDragging) {
|
|
15606
14998
|
this._core.store.state.isDragging = false;
|
|
15607
14999
|
if (this.hasMoved) {
|
|
15608
|
-
this._core.
|
|
15000
|
+
this._core.commandManager.executeCommand(new MoveSelectionGroupCommand(this._core, this, this.endX, this.endY, this.startX, this.startY, true));
|
|
15609
15001
|
this._core.store.state.hasObjectsChanged = true;
|
|
15610
15002
|
}
|
|
15611
15003
|
}
|
|
@@ -15614,7 +15006,7 @@ class KritzelMoveHandler extends KritzelBaseHandler {
|
|
|
15614
15006
|
if (this._core.store.state.isDragging) {
|
|
15615
15007
|
this._core.store.state.isDragging = false;
|
|
15616
15008
|
if (this.hasMoved) {
|
|
15617
|
-
this._core.
|
|
15009
|
+
this._core.commandManager.executeCommand(new MoveSelectionGroupCommand(this._core, this, this.endX, this.endY, this.startX, this.startY, true));
|
|
15618
15010
|
this._core.store.state.hasObjectsChanged = true;
|
|
15619
15011
|
}
|
|
15620
15012
|
}
|
|
@@ -15664,6 +15056,7 @@ class KritzelResizeHandler extends KritzelBaseHandler {
|
|
|
15664
15056
|
initialMouseY = 0;
|
|
15665
15057
|
initialSize = { x: 0, y: 0, width: 0, height: 0 };
|
|
15666
15058
|
newSize = { x: 0, y: 0, width: 0, height: 0 };
|
|
15059
|
+
hasResized = false;
|
|
15667
15060
|
constructor(core) {
|
|
15668
15061
|
super(core);
|
|
15669
15062
|
}
|
|
@@ -15672,6 +15065,7 @@ class KritzelResizeHandler extends KritzelBaseHandler {
|
|
|
15672
15065
|
this.initialMouseY = 0;
|
|
15673
15066
|
this.initialSize = { x: 0, y: 0, width: 0, height: 0 };
|
|
15674
15067
|
this.newSize = { x: 0, y: 0, width: 0, height: 0 };
|
|
15068
|
+
this.hasResized = false;
|
|
15675
15069
|
}
|
|
15676
15070
|
handlePointerDown(event) {
|
|
15677
15071
|
if (event.pointerType === 'mouse') {
|
|
@@ -15718,6 +15112,15 @@ class KritzelResizeHandler extends KritzelBaseHandler {
|
|
|
15718
15112
|
const clientY = event.clientY - this._core.store.offsetY;
|
|
15719
15113
|
const dx = clientX - this.initialMouseX;
|
|
15720
15114
|
const dy = clientY - this.initialMouseY;
|
|
15115
|
+
const resizeDeltaX = Math.abs(dx);
|
|
15116
|
+
const resizeDeltaY = Math.abs(dy);
|
|
15117
|
+
const resizeThreshold = 5;
|
|
15118
|
+
if (resizeDeltaX > resizeThreshold || resizeDeltaY > resizeThreshold) {
|
|
15119
|
+
this.hasResized = true;
|
|
15120
|
+
}
|
|
15121
|
+
if (!this.hasResized) {
|
|
15122
|
+
return;
|
|
15123
|
+
}
|
|
15721
15124
|
switch (this._core.store.state.resizeHandleType) {
|
|
15722
15125
|
case KritzelHandleType.TopLeft:
|
|
15723
15126
|
this.newSize.width = this.initialSize.width - dx;
|
|
@@ -15758,6 +15161,16 @@ class KritzelResizeHandler extends KritzelBaseHandler {
|
|
|
15758
15161
|
const clientY = Math.round(oneFingerTouch.clientY - this._core.store.offsetY);
|
|
15759
15162
|
const dx = clientX - this.initialMouseX;
|
|
15760
15163
|
const dy = clientY - this.initialMouseY;
|
|
15164
|
+
const resizeDeltaX = Math.abs(dx);
|
|
15165
|
+
const resizeDeltaY = Math.abs(dy);
|
|
15166
|
+
const resizeThreshold = 5;
|
|
15167
|
+
if (resizeDeltaX > resizeThreshold || resizeDeltaY > resizeThreshold) {
|
|
15168
|
+
clearTimeout(this._core.store.state.longTouchTimeout);
|
|
15169
|
+
this.hasResized = true;
|
|
15170
|
+
}
|
|
15171
|
+
if (!this.hasResized) {
|
|
15172
|
+
return;
|
|
15173
|
+
}
|
|
15761
15174
|
switch (this._core.store.state.resizeHandleType) {
|
|
15762
15175
|
case KritzelHandleType.TopLeft:
|
|
15763
15176
|
this.newSize.width = this.initialSize.width - dx;
|
|
@@ -15785,24 +15198,27 @@ class KritzelResizeHandler extends KritzelBaseHandler {
|
|
|
15785
15198
|
break;
|
|
15786
15199
|
}
|
|
15787
15200
|
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
15201
|
}
|
|
15790
15202
|
}
|
|
15791
15203
|
}
|
|
15792
15204
|
handlePointerUp(event) {
|
|
15793
15205
|
if (event.pointerType === 'mouse') {
|
|
15794
15206
|
if (this._core.store.state.isResizing) {
|
|
15795
|
-
this._core.history.executeCommand(new ResizeSelectionGroupCommand(this._core, this, structuredClone(this.initialSize), structuredClone(this.newSize)));
|
|
15796
15207
|
this._core.store.state.isResizing = false;
|
|
15797
|
-
this.
|
|
15208
|
+
if (this.hasResized) {
|
|
15209
|
+
this._core.commandManager.executeCommand(new ResizeSelectionGroupCommand(this._core, this, structuredClone(this.initialSize), structuredClone(this.newSize)));
|
|
15210
|
+
this._core.store.state.hasObjectsChanged = true;
|
|
15211
|
+
}
|
|
15798
15212
|
this.reset();
|
|
15799
15213
|
}
|
|
15800
15214
|
}
|
|
15801
15215
|
if (event.pointerType === 'touch') {
|
|
15802
15216
|
if (this._core.store.state.isResizing) {
|
|
15803
|
-
this._core.history.executeCommand(new ResizeSelectionGroupCommand(this._core, this, structuredClone(this.initialSize), structuredClone(this.newSize)));
|
|
15804
15217
|
this._core.store.state.isResizing = false;
|
|
15805
|
-
this.
|
|
15218
|
+
if (this.hasResized) {
|
|
15219
|
+
this._core.commandManager.executeCommand(new ResizeSelectionGroupCommand(this._core, this, structuredClone(this.initialSize), structuredClone(this.newSize)));
|
|
15220
|
+
this._core.store.state.hasObjectsChanged = true;
|
|
15221
|
+
}
|
|
15806
15222
|
this.reset();
|
|
15807
15223
|
clearTimeout(this._core.store.state.longTouchTimeout);
|
|
15808
15224
|
}
|
|
@@ -15928,7 +15344,7 @@ class KritzelRotationHandler extends KritzelBaseHandler {
|
|
|
15928
15344
|
handlePointerUp(event) {
|
|
15929
15345
|
if (event.pointerType === 'mouse') {
|
|
15930
15346
|
if (this._core.store.state.isRotating) {
|
|
15931
|
-
this._core.
|
|
15347
|
+
this._core.commandManager.executeCommand(new RotateSelectionGroupCommand(this._core, this, this.rotation, this.initialSelectionGroupRotation));
|
|
15932
15348
|
this._core.store.state.isRotating = false;
|
|
15933
15349
|
this._core.store.state.hasObjectsChanged = true;
|
|
15934
15350
|
this.reset();
|
|
@@ -15936,7 +15352,7 @@ class KritzelRotationHandler extends KritzelBaseHandler {
|
|
|
15936
15352
|
}
|
|
15937
15353
|
if (event.pointerType === 'touch') {
|
|
15938
15354
|
if (this._core.store.state.isRotating) {
|
|
15939
|
-
this._core.
|
|
15355
|
+
this._core.commandManager.executeCommand(new RotateSelectionGroupCommand(this._core, this, this.rotation, this.initialSelectionGroupRotation));
|
|
15940
15356
|
this._core.store.state.isRotating = false;
|
|
15941
15357
|
this._core.store.state.hasObjectsChanged = true;
|
|
15942
15358
|
this.reset();
|
|
@@ -16040,7 +15456,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
|
|
|
16040
15456
|
if (KritzelEventHelper.isLeftClick(event)) {
|
|
16041
15457
|
const hasObjectsMoved = this._core.store.state.hasObjectsChanged;
|
|
16042
15458
|
if (this._core.store.state.selectionGroup?.objects.length === 1 && hasObjectsMoved === false) {
|
|
16043
|
-
this._core.store.state.selectionGroup.objects[0].edit();
|
|
15459
|
+
this._core.store.state.selectionGroup.objects[0].edit(event);
|
|
16044
15460
|
}
|
|
16045
15461
|
this._core.store.state.hasObjectsChanged = false;
|
|
16046
15462
|
if (this._core.store.state.isSelecting) {
|
|
@@ -16059,7 +15475,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
|
|
|
16059
15475
|
clearTimeout(this.touchStartTimeout);
|
|
16060
15476
|
const hasObjectsMoved = this._core.store.state.hasObjectsChanged;
|
|
16061
15477
|
if (this._core.store.state.selectionGroup?.objects.length === 1 && hasObjectsMoved === false) {
|
|
16062
|
-
this._core.store.state.selectionGroup.objects[0].edit();
|
|
15478
|
+
this._core.store.state.selectionGroup.objects[0].edit(event);
|
|
16063
15479
|
}
|
|
16064
15480
|
this._core.store.state.hasObjectsChanged = false;
|
|
16065
15481
|
if (this._core.store.state.isSelecting) {
|
|
@@ -16202,7 +15618,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
|
|
|
16202
15618
|
selectionGroup.addOrRemove(object);
|
|
16203
15619
|
selectionGroup.isSelected = true;
|
|
16204
15620
|
selectionGroup.rotation = object.rotation;
|
|
16205
|
-
this._core.
|
|
15621
|
+
this._core.commandManager.executeCommand(new AddSelectionGroupCommand(this._core, this, selectionGroup));
|
|
16206
15622
|
}
|
|
16207
15623
|
addSelectedObjectsToSelectionGroup() {
|
|
16208
15624
|
const selectedObjects = this._core.store.selectedObjects;
|
|
@@ -16219,7 +15635,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
|
|
|
16219
15635
|
if (selectionGroup.length === 1) {
|
|
16220
15636
|
selectionGroup.rotation = selectionGroup.objects[0].rotation;
|
|
16221
15637
|
}
|
|
16222
|
-
this._core.
|
|
15638
|
+
this._core.commandManager.executeCommand(new AddSelectionGroupCommand(this._core, this, selectionGroup));
|
|
16223
15639
|
}
|
|
16224
15640
|
}
|
|
16225
15641
|
|
|
@@ -16268,7 +15684,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
|
|
|
16268
15684
|
this._core.store.state.selectionGroup &&
|
|
16269
15685
|
!this._core.store.state.isResizeHandleSelected &&
|
|
16270
15686
|
!this._core.store.state.isRotationHandleSelected) {
|
|
16271
|
-
this._core.
|
|
15687
|
+
this._core.commandManager.executeCommand(new RemoveSelectionGroupCommand(this._core, this._core.store.state.selectionGroup));
|
|
16272
15688
|
}
|
|
16273
15689
|
if (selectedObject && selectedObject.isSelected === false && selectedObject?.objects.length === 1 && selectedObject.objects[0].isInteractive) {
|
|
16274
15690
|
return;
|
|
@@ -16297,7 +15713,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
|
|
|
16297
15713
|
this._core.store.state.selectionGroup &&
|
|
16298
15714
|
!this._core.store.state.isResizeHandleSelected &&
|
|
16299
15715
|
!this._core.store.state.isRotationHandleSelected) {
|
|
16300
|
-
this._core.
|
|
15716
|
+
this._core.commandManager.executeCommand(new RemoveSelectionGroupCommand(this._core, this._core.store.state.selectionGroup));
|
|
16301
15717
|
}
|
|
16302
15718
|
}
|
|
16303
15719
|
this.rotationHandler.handlePointerDown(event);
|
|
@@ -16423,14 +15839,15 @@ class KritzelTextTool extends KritzelBaseTool {
|
|
|
16423
15839
|
const path = event.composedPath().slice(1);
|
|
16424
15840
|
const objectElement = path.find(element => element.classList && element.classList.contains('object'));
|
|
16425
15841
|
const object = this._core.findObjectById(objectElement?.id);
|
|
16426
|
-
if (object instanceof KritzelText) {
|
|
15842
|
+
if (this._core.store.state.activeText === null && object instanceof KritzelText) {
|
|
16427
15843
|
this._core.store.state.activeText = object;
|
|
16428
|
-
object.
|
|
15844
|
+
object.edit(event);
|
|
16429
15845
|
return;
|
|
16430
15846
|
}
|
|
16431
15847
|
if (this._core.store.state.activeText !== null && object instanceof KritzelText) {
|
|
15848
|
+
this._core.store.state.activeText.save();
|
|
16432
15849
|
this._core.store.state.activeText = object;
|
|
16433
|
-
object.
|
|
15850
|
+
object.edit(event);
|
|
16434
15851
|
return;
|
|
16435
15852
|
}
|
|
16436
15853
|
if (this._core.store.state.activeText !== null && object instanceof KritzelText === false) {
|
|
@@ -16444,26 +15861,30 @@ class KritzelTextTool extends KritzelBaseTool {
|
|
|
16444
15861
|
const clientX = event.clientX - this._core.store.offsetX;
|
|
16445
15862
|
const clientY = event.clientY - this._core.store.offsetY;
|
|
16446
15863
|
const text = KritzelText.create(this._core, this.fontSize, this.fontFamily);
|
|
15864
|
+
text.isNew = true;
|
|
16447
15865
|
text.fontColor = this.fontColor;
|
|
16448
15866
|
text.translateX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;
|
|
16449
15867
|
text.translateY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;
|
|
16450
15868
|
text.zIndex = this._core.store.currentZIndex;
|
|
16451
15869
|
this._core.store.state.activeText = text;
|
|
16452
|
-
this._core.
|
|
15870
|
+
this._core.store.state.objectsMap.insert(text);
|
|
15871
|
+
this._core.rerender();
|
|
15872
|
+
requestAnimationFrame(() => text.edit(event));
|
|
16453
15873
|
}
|
|
16454
15874
|
if (event.pointerType === 'touch') {
|
|
16455
15875
|
const activePointers = Array.from(this._core.store.state.pointers.values());
|
|
16456
15876
|
const path = event.composedPath().slice(1);
|
|
16457
15877
|
const objectElement = path.find(element => element.classList && element.classList.contains('object'));
|
|
16458
15878
|
const object = this._core.findObjectById(objectElement?.id);
|
|
16459
|
-
if (object instanceof KritzelText) {
|
|
15879
|
+
if (this._core.store.state.activeText === null && object instanceof KritzelText) {
|
|
16460
15880
|
this._core.store.state.activeText = object;
|
|
16461
|
-
object.
|
|
15881
|
+
object.edit(event);
|
|
16462
15882
|
return;
|
|
16463
15883
|
}
|
|
16464
15884
|
if (this._core.store.state.activeText !== null && object instanceof KritzelText) {
|
|
15885
|
+
this._core.store.state.activeText.save();
|
|
16465
15886
|
this._core.store.state.activeText = object;
|
|
16466
|
-
object.
|
|
15887
|
+
object.edit(event);
|
|
16467
15888
|
return;
|
|
16468
15889
|
}
|
|
16469
15890
|
if (this._core.store.state.activeText !== null && object instanceof KritzelText === false) {
|
|
@@ -16478,12 +15899,14 @@ class KritzelTextTool extends KritzelBaseTool {
|
|
|
16478
15899
|
const clientX = Math.round(activePointers[0].clientX - this._core.store.offsetX);
|
|
16479
15900
|
const clientY = Math.round(activePointers[0].clientY - this._core.store.offsetY);
|
|
16480
15901
|
const text = KritzelText.create(this._core, this.fontSize, this.fontFamily);
|
|
15902
|
+
text.isNew = true;
|
|
16481
15903
|
text.fontColor = this.fontColor;
|
|
16482
15904
|
text.translateX = (clientX - this._core.store.state.translateX) / this._core.store.state.scale;
|
|
16483
15905
|
text.translateY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;
|
|
16484
15906
|
text.zIndex = this._core.store.currentZIndex;
|
|
16485
15907
|
this._core.store.state.activeText = text;
|
|
16486
|
-
this._core.
|
|
15908
|
+
this._core.store.state.objectsMap.insert(text);
|
|
15909
|
+
this._core.rerender();
|
|
16487
15910
|
}
|
|
16488
15911
|
}
|
|
16489
15912
|
handlePointerUp(event) {
|
|
@@ -16491,15 +15914,74 @@ class KritzelTextTool extends KritzelBaseTool {
|
|
|
16491
15914
|
event.preventDefault();
|
|
16492
15915
|
}
|
|
16493
15916
|
if (event.pointerType === 'mouse') {
|
|
16494
|
-
this._core.store.state.activeText?.edit();
|
|
15917
|
+
this._core.store.state.activeText?.edit(event);
|
|
16495
15918
|
}
|
|
16496
15919
|
if (event.pointerType === 'touch') {
|
|
16497
|
-
this._core.store.state.activeText?.edit();
|
|
15920
|
+
this._core.store.state.activeText?.edit(event);
|
|
16498
15921
|
KritzelKeyboardHelper.enableInteractiveWidget();
|
|
16499
15922
|
}
|
|
16500
15923
|
}
|
|
16501
15924
|
}
|
|
16502
15925
|
|
|
15926
|
+
class KritzelCustomElement extends KritzelBaseObject {
|
|
15927
|
+
__class__ = 'KritzelCustomElement';
|
|
15928
|
+
element;
|
|
15929
|
+
isInteractive = true;
|
|
15930
|
+
constructor(config) {
|
|
15931
|
+
super();
|
|
15932
|
+
if (config) {
|
|
15933
|
+
this.translateX = config.translateX || 0;
|
|
15934
|
+
this.translateY = config.translateY || 0;
|
|
15935
|
+
this.scale = config.scale || 1;
|
|
15936
|
+
this.element = config.element;
|
|
15937
|
+
this.height = config.height || 0;
|
|
15938
|
+
this.width = config.width || 0;
|
|
15939
|
+
}
|
|
15940
|
+
}
|
|
15941
|
+
static create(core, config) {
|
|
15942
|
+
const object = new KritzelCustomElement(config);
|
|
15943
|
+
object._core = core;
|
|
15944
|
+
object.id = object.generateId();
|
|
15945
|
+
object.workspaceId = core.store.state.activeWorkspace.id;
|
|
15946
|
+
return object;
|
|
15947
|
+
}
|
|
15948
|
+
mount(element) {
|
|
15949
|
+
if (element === null) {
|
|
15950
|
+
return;
|
|
15951
|
+
}
|
|
15952
|
+
// If already mounted to the same element and content is still attached, skip
|
|
15953
|
+
if (this.isMounted && this.elementRef === element && this.element.parentElement === element) {
|
|
15954
|
+
return;
|
|
15955
|
+
}
|
|
15956
|
+
this.elementRef = element;
|
|
15957
|
+
this.isMounted = true;
|
|
15958
|
+
// Clear existing content and append the element
|
|
15959
|
+
this.elementRef.innerHTML = '';
|
|
15960
|
+
this.elementRef.appendChild(this.element);
|
|
15961
|
+
}
|
|
15962
|
+
resize(x, y, width, height) {
|
|
15963
|
+
if (width <= 1 || height <= 1) {
|
|
15964
|
+
return;
|
|
15965
|
+
}
|
|
15966
|
+
this.width = width;
|
|
15967
|
+
this.height = height;
|
|
15968
|
+
this.translateX = x;
|
|
15969
|
+
this.translateY = y;
|
|
15970
|
+
if (this.element) {
|
|
15971
|
+
this.element.style.width = `${width}px`;
|
|
15972
|
+
this.element.style.height = `${height}px`;
|
|
15973
|
+
}
|
|
15974
|
+
}
|
|
15975
|
+
copy() {
|
|
15976
|
+
const copiedObject = Object.create(Object.getPrototypeOf(this));
|
|
15977
|
+
Object.assign(copiedObject, this);
|
|
15978
|
+
copiedObject.id = this.generateId();
|
|
15979
|
+
copiedObject.isMounted = false;
|
|
15980
|
+
copiedObject.element = this.element.cloneNode(true);
|
|
15981
|
+
return copiedObject;
|
|
15982
|
+
}
|
|
15983
|
+
}
|
|
15984
|
+
|
|
16503
15985
|
const DEFAULT_BRUSH_CONFIG = {
|
|
16504
15986
|
type: 'pen',
|
|
16505
15987
|
color: '#000000',
|
|
@@ -16941,7 +16423,7 @@ class KritzelImageTool extends KritzelBaseTool {
|
|
|
16941
16423
|
selectionGroup.isSelected = true;
|
|
16942
16424
|
const addImageCommand = new AddObjectCommand(this._core, this, image);
|
|
16943
16425
|
const addSelectionGroupCommand = new AddSelectionGroupCommand(this._core, this, selectionGroup);
|
|
16944
|
-
this._core.
|
|
16426
|
+
this._core.commandManager.executeCommand(new BatchCommand(this._core, this, [addImageCommand, addSelectionGroupCommand]));
|
|
16945
16427
|
this._core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
|
|
16946
16428
|
}
|
|
16947
16429
|
handleCancel() {
|
|
@@ -16976,6 +16458,6 @@ exports.ObjectHelper = ObjectHelper;
|
|
|
16976
16458
|
exports.RemoveObjectCommand = RemoveObjectCommand;
|
|
16977
16459
|
exports.RemoveSelectionGroupCommand = RemoveSelectionGroupCommand;
|
|
16978
16460
|
exports.UpdateObjectCommand = UpdateObjectCommand;
|
|
16979
|
-
//# sourceMappingURL=index-
|
|
16461
|
+
//# sourceMappingURL=index-Cg50mv2K.js.map
|
|
16980
16462
|
|
|
16981
|
-
//# sourceMappingURL=index-
|
|
16463
|
+
//# sourceMappingURL=index-Cg50mv2K.js.map
|