slate 0.47.4 → 0.47.8

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/slate.js CHANGED
@@ -654,7 +654,7 @@ function transform(path, operation) {
654
654
  p = operation.path;
655
655
 
656
656
 
657
- if (type === 'add_mark' || type === 'insert_text' || type === 'remove_mark' || type === 'remove_text' || type === 'set_mark' || type === 'set_node' || type === 'set_selection' || type === 'set_value' || path.size === 0) {
657
+ if (type === 'add_mark' || type === 'insert_text' || type === 'remove_mark' || type === 'remove_text' || type === 'set_mark' || type === 'set_node' || type === 'set_selection' || type === 'set_value' || type === 'add_annotation' || type === 'remove_annotation' || type === 'set_annotation' || path.size === 0) {
658
658
  return immutable.List([path]);
659
659
  }
660
660
 
@@ -2816,7 +2816,7 @@ var Text = function (_Record) {
2816
2816
  }
2817
2817
 
2818
2818
  // If the range starts after the leaf, or ends before it, continue.
2819
- if (start.offset > offset + length || end.offset <= offset) {
2819
+ if (start.offset > offset + length || end.offset < offset || end.offset === offset && offset !== 0) {
2820
2820
  next.push(leaf);
2821
2821
  continue;
2822
2822
  }
@@ -3532,10 +3532,14 @@ var Value = function (_Record) {
3532
3532
  annotation = Annotation.create(annotation);
3533
3533
  var value = this;
3534
3534
  var _value = value,
3535
- annotations = _value.annotations;
3535
+ annotations = _value.annotations,
3536
+ document = _value.document;
3536
3537
  var _annotation = annotation,
3537
3538
  key = _annotation.key;
3538
3539
 
3540
+ annotation = annotation.updatePoints(function (point) {
3541
+ return point.normalize(document);
3542
+ });
3539
3543
  annotations = annotations.set(key, annotation);
3540
3544
  value = value.set('annotations', annotations);
3541
3545
  return value;
@@ -3768,16 +3772,16 @@ var Value = function (_Record) {
3768
3772
 
3769
3773
  value = value.mapRanges(function (range) {
3770
3774
  var _range = range,
3771
- start = _range.start,
3772
- end = _range.end;
3775
+ anchor = _range.anchor,
3776
+ focus = _range.focus;
3773
3777
 
3774
3778
 
3775
- if (node.hasNode(start.key)) {
3776
- range = prev ? range.moveStartTo(prev.key, prev.text.length) : next ? range.moveStartTo(next.key, 0) : range.unset();
3779
+ if (node.hasNode(anchor.key)) {
3780
+ range = prev ? range.moveAnchorTo(prev.key, prev.text.length) : next ? range.moveAnchorTo(next.key, 0) : range.unset();
3777
3781
  }
3778
3782
 
3779
- if (node.hasNode(end.key)) {
3780
- range = prev ? range.moveEndTo(prev.key, prev.text.length) : next ? range.moveEndTo(next.key, 0) : range.unset();
3783
+ if (node.hasNode(focus.key)) {
3784
+ range = prev ? range.moveFocusTo(prev.key, prev.text.length) : next ? range.moveFocusTo(next.key, 0) : range.unset();
3781
3785
  }
3782
3786
 
3783
3787
  range = range.updatePoints(function (point) {
@@ -3977,18 +3981,18 @@ var Value = function (_Record) {
3977
3981
  value = value.mapRanges(function (range) {
3978
3982
  var next = newDocument.getNextText(node.key);
3979
3983
  var _range2 = range,
3980
- start = _range2.start,
3981
- end = _range2.end;
3984
+ anchor = _range2.anchor,
3985
+ focus = _range2.focus;
3982
3986
 
3983
- // If the start was after the split, move it to the next node.
3987
+ // If the anchor was after the split, move it to the next node.
3984
3988
 
3985
- if (node.key === start.key && position <= start.offset) {
3986
- range = range.moveStartTo(next.key, start.offset - position);
3989
+ if (node.key === anchor.key && position <= anchor.offset) {
3990
+ range = range.moveAnchorTo(next.key, anchor.offset - position);
3987
3991
  }
3988
3992
 
3989
- // If the end was after the split, move it to the next node.
3990
- if (node.key === end.key && position <= end.offset) {
3991
- range = range.moveEndTo(next.key, end.offset - position);
3993
+ // If the focus was after the split, move it to the next node.
3994
+ if (node.key === focus.key && position <= focus.offset) {
3995
+ range = range.moveFocusTo(next.key, focus.offset - position);
3992
3996
  }
3993
3997
 
3994
3998
  range = range.updatePoints(function (point) {
@@ -4427,7 +4431,7 @@ var Value = function (_Record) {
4427
4431
 
4428
4432
  if (isPlainObject(a)) {
4429
4433
  var p = {};
4430
- if ('annotations' in a) p.annotations = Annotation.createList(a.annotations);
4434
+ if ('annotations' in a) p.annotations = Annotation.createMap(a.annotations);
4431
4435
  if ('data' in a) p.data = Data.create(a.data);
4432
4436
  return p;
4433
4437
  }
@@ -6798,7 +6802,7 @@ Commands$1.deleteBackwardAtRange = function (editor, range) {
6798
6802
 
6799
6803
  // If the focus offset is farther than the number of characters to delete,
6800
6804
  // just remove the characters backwards inside the current node.
6801
- if (n < focus.offset) {
6805
+ if (n <= focus.offset) {
6802
6806
  range = range.moveFocusBackward(n);
6803
6807
  editor.deleteAtRange(range);
6804
6808
  return;
@@ -7174,7 +7178,7 @@ Commands$1.insertFragmentAtRange = function (editor, range, fragment) {
7174
7178
 
7175
7179
  // Regenerate the keys for all of the fragments nodes, so that they're
7176
7180
  // guaranteed not to collide with the existing keys in the document. Otherwise
7177
- // they will be rengerated automatically and we won't have an easy way to
7181
+ // they will be regenerated automatically and we won't have an easy way to
7178
7182
  // reference them.
7179
7183
  fragment = fragment.mapDescendants(function (child) {
7180
7184
  return child.regenerateKey();
@@ -9779,6 +9783,63 @@ Commands$2.addMarksByPath = function (editor, path, offset, length, marks) {
9779
9783
  });
9780
9784
  };
9781
9785
 
9786
+ /**
9787
+ * Sets specific set of marks on the path
9788
+ * @param {Editor} editor
9789
+ * @param {Array} path
9790
+ * @param {Number} offset
9791
+ * @param {Number} length
9792
+ * @param {Array<Object|Mark>} marks
9793
+ */
9794
+
9795
+ Commands$2.replaceMarksByPath = function (editor, path, offset, length, marks) {
9796
+ var marksSet = Mark.createSet(marks);
9797
+
9798
+ var value = editor.value;
9799
+ var document = value.document;
9800
+
9801
+ var node = document.assertNode(path);
9802
+
9803
+ if (node.marks.equals(marksSet)) {
9804
+ return;
9805
+ }
9806
+
9807
+ editor.withoutNormalizing(function () {
9808
+ // If it ends before the end of the node, we'll need to split to create a new
9809
+ // text with different marks.
9810
+ if (offset + length < node.text.length) {
9811
+ editor.splitNodeByPath(path, offset + length);
9812
+ }
9813
+
9814
+ // Same thing if it starts after the start. But in that case, we need to
9815
+ // update our path and offset to point to the new start.
9816
+ if (offset > 0) {
9817
+ editor.splitNodeByPath(path, offset);
9818
+ path = PathUtils.increment(path);
9819
+ offset = 0;
9820
+ }
9821
+
9822
+ var marksToApply = marksSet.subtract(node.marks);
9823
+ var marksToRemove = node.marks.subtract(marksSet);
9824
+
9825
+ marksToRemove.forEach(function (mark) {
9826
+ editor.applyOperation({
9827
+ type: 'remove_mark',
9828
+ path: path,
9829
+ mark: Mark.create(mark)
9830
+ });
9831
+ });
9832
+
9833
+ marksToApply.forEach(function (mark) {
9834
+ editor.applyOperation({
9835
+ type: 'add_mark',
9836
+ path: path,
9837
+ mark: Mark.create(mark)
9838
+ });
9839
+ });
9840
+ });
9841
+ };
9842
+
9782
9843
  /**
9783
9844
  * Insert a `fragment` at `index` in a node by `path`.
9784
9845
  *
@@ -9822,7 +9883,6 @@ Commands$2.insertNodeByPath = function (editor, path, index, node) {
9822
9883
  */
9823
9884
 
9824
9885
  Commands$2.insertTextByPath = function (editor, path, offset, text, marks) {
9825
- marks = Mark.createSet(marks);
9826
9886
  var value = editor.value;
9827
9887
  var annotations = value.annotations,
9828
9888
  document = value.document;
@@ -9876,8 +9936,8 @@ Commands$2.insertTextByPath = function (editor, path, offset, text, marks) {
9876
9936
  text: text
9877
9937
  });
9878
9938
 
9879
- if (marks.size) {
9880
- editor.addMarksByPath(path, offset, text.length, marks);
9939
+ if (marks) {
9940
+ editor.replaceMarksByPath(path, offset, text.length, marks);
9881
9941
  }
9882
9942
  });
9883
9943
  };
@@ -9972,6 +10032,10 @@ Commands$2.removeMarksByPath = function (editor, path, offset, length, marks) {
9972
10032
 
9973
10033
  var node = document.assertNode(path);
9974
10034
 
10035
+ if (marks.intersect(node.marks).isEmpty()) {
10036
+ return;
10037
+ }
10038
+
9975
10039
  editor.withoutNormalizing(function () {
9976
10040
  // If it ends before the end of the node, we'll need to split to create a new
9977
10041
  // text with different marks.
@@ -10528,7 +10592,7 @@ Commands$2.wrapNodeByPath = function (editor, path, node) {
10528
10592
  * Mix in `*ByKey` variants.
10529
10593
  */
10530
10594
 
10531
- var COMMANDS = ['addMark', 'insertFragment', 'insertNode', 'insertText', 'mergeNode', 'removeAllMarks', 'removeMark', 'removeNode', 'removeText', 'replaceNode', 'replaceText', 'setMark', 'setNode', 'setText', 'splitNode', 'unwrapBlock', 'unwrapChildren', 'unwrapInline', 'unwrapNode', 'wrapBlock', 'wrapInline', 'wrapNode'];
10595
+ var COMMANDS = ['addMark', 'insertFragment', 'insertNode', 'insertText', 'mergeNode', 'removeAllMarks', 'removeMark', 'removeNode', 'removeText', 'replaceMarks', 'replaceNode', 'replaceText', 'setMark', 'setNode', 'setText', 'splitNode', 'unwrapBlock', 'unwrapChildren', 'unwrapInline', 'unwrapNode', 'wrapBlock', 'wrapInline', 'wrapNode'];
10532
10596
 
10533
10597
  var _loop = function _loop(method) {
10534
10598
  Commands$2[method + 'ByKey'] = function (editor, key) {
@@ -12289,7 +12353,7 @@ Commands$3.save = function (editor, operation) {
12289
12353
  save = _editor$tmp.save,
12290
12354
  merge = _editor$tmp.merge;
12291
12355
 
12292
- if (save === false) return;
12356
+ if (save === false || !isValidOperation(operation)) return;
12293
12357
 
12294
12358
  var undos = data.get('undos') || immutable.List();
12295
12359
  var lastBatch = undos.last();
@@ -12350,13 +12414,13 @@ Commands$3.redo = function (editor) {
12350
12414
  batch.forEach(function (op) {
12351
12415
  var _op = op,
12352
12416
  type = _op.type,
12353
- properties = _op.properties;
12417
+ newProperties = _op.newProperties;
12354
12418
 
12355
12419
  // When the operation mutates the selection, omit its `isFocused` value to
12356
12420
  // prevent the editor focus from changing during redoing.
12357
12421
 
12358
12422
  if (type === 'set_selection') {
12359
- op = op.set('properties', omit_1(properties, 'isFocused'));
12423
+ op = op.set('newProperties', omit_1(newProperties, 'isFocused'));
12360
12424
  }
12361
12425
 
12362
12426
  editor.applyOperation(op);
@@ -12394,13 +12458,13 @@ Commands$3.undo = function (editor) {
12394
12458
  }).forEach(function (inverse) {
12395
12459
  var _inverse = inverse,
12396
12460
  type = _inverse.type,
12397
- properties = _inverse.properties;
12461
+ newProperties = _inverse.newProperties;
12398
12462
 
12399
12463
  // When the operation mutates the selection, omit its `isFocused` value to
12400
12464
  // prevent the editor focus from changing during undoing.
12401
12465
 
12402
12466
  if (type === 'set_selection') {
12403
- inverse = inverse.set('properties', omit_1(properties, 'isFocused'));
12467
+ inverse = inverse.set('newProperties', omit_1(newProperties, 'isFocused'));
12404
12468
  }
12405
12469
 
12406
12470
  editor.applyOperation(inverse);
@@ -12461,6 +12525,28 @@ function shouldMerge(o, p) {
12461
12525
  return merge;
12462
12526
  }
12463
12527
 
12528
+ /**
12529
+ * Check weather an operation needs to be saved to the history
12530
+ * @param {Object} o - operation
12531
+ * @returns {Boolean}
12532
+ */
12533
+
12534
+ function isValidOperation(o) {
12535
+ if (o.type === 'set_selection') {
12536
+ var _o$newProperties = o.newProperties,
12537
+ isFocused = _o$newProperties.isFocused,
12538
+ anchor = _o$newProperties.anchor,
12539
+ focus = _o$newProperties.focus;
12540
+
12541
+ // this is blur/focus operation, dont need to store it into the history
12542
+
12543
+ if (isFocused !== undefined && !anchor && !focus) {
12544
+ return false;
12545
+ }
12546
+ }
12547
+ return true;
12548
+ }
12549
+
12464
12550
  var Commands$4 = {};
12465
12551
 
12466
12552
  Commands$4.blur = function (editor) {
@@ -13492,6 +13578,20 @@ Commands$5.setAnnotation = function (editor, annotation, newProperties) {
13492
13578
  });
13493
13579
  };
13494
13580
 
13581
+ Commands$5.setAnnotations = function (editor) {
13582
+ var annotations = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
13583
+ var value = editor.value;
13584
+
13585
+ var newProperties = Value.createProperties({ annotations: annotations });
13586
+ var prevProperties = pick_1(value, Object.keys(newProperties));
13587
+
13588
+ editor.applyOperation({
13589
+ type: 'set_value',
13590
+ properties: prevProperties,
13591
+ newProperties: newProperties
13592
+ });
13593
+ };
13594
+
13495
13595
  /**
13496
13596
  * A plugin that adds a set of queries to the editor.
13497
13597
  *
@@ -14581,27 +14681,14 @@ Commands$6.insertFragment = function (editor, fragment) {
14581
14681
  var _value = value,
14582
14682
  document = _value.document,
14583
14683
  selection = _value.selection;
14584
- var start = selection.start,
14585
- end = selection.end;
14586
- var _value2 = value,
14587
- startText = _value2.startText,
14588
- endText = _value2.endText,
14589
- startInline = _value2.startInline;
14590
-
14591
- var lastText = fragment.getLastText();
14592
- var lastInline = fragment.getClosestInline(lastText.key);
14593
- var lastBlock = fragment.getClosestBlock(lastText.key);
14594
- var firstChild = fragment.nodes.first();
14595
- var lastChild = fragment.nodes.last();
14684
+ var start = selection.start;
14685
+
14596
14686
  var keys = Array.from(document.texts(), function (_ref) {
14597
14687
  var _ref2 = slicedToArray(_ref, 1),
14598
14688
  text = _ref2[0];
14599
14689
 
14600
14690
  return text.key;
14601
14691
  });
14602
- var isAppending = !startInline || start.isAtStartOfNode(startText) || end.isAtStartOfNode(startText) || start.isAtEndOfNode(endText) || end.isAtEndOfNode(endText);
14603
-
14604
- var isInserting = firstChild.hasBlockChildren() || lastChild.hasBlockChildren();
14605
14692
 
14606
14693
  editor.insertFragmentAtRange(selection, fragment);
14607
14694
  value = editor.value;
@@ -14610,25 +14697,28 @@ Commands$6.insertFragment = function (editor, fragment) {
14610
14697
  var newTexts = document.getTexts().filter(function (n) {
14611
14698
  return !keys.includes(n.key);
14612
14699
  });
14613
- var newText = isAppending ? newTexts.last() : newTexts.takeLast(2).first();
14614
-
14615
- if (newText && (lastInline || isInserting)) {
14616
- editor.moveToEndOfNode(newText);
14617
- } else if (newText) {
14618
- // The position within the last text node needs to be calculated. This is the length
14619
- // of all text nodes within the last block, but if the last block contains inline nodes,
14620
- // these have to be skipped.
14621
- var nodes = lastBlock.nodes;
14622
-
14623
- var lastIndex = nodes.findLastIndex(function (node) {
14624
- return node && node.object === 'inline';
14625
- });
14626
- var remainingTexts = nodes.takeLast(nodes.size - lastIndex - 1);
14627
- var remainingTextLength = remainingTexts.reduce(function (acc, val) {
14628
- return acc + val.text.length;
14629
- }, 0);
14630
- editor.moveToStartOfNode(newText).moveForward(remainingTextLength);
14700
+ if (newTexts.size === 0) return;
14701
+ var fragmentLength = fragment.text.length;
14702
+
14703
+ // Either startText is still here, or we want the first un-previously known text
14704
+ var startText = document.getNode(start.key) || newTexts.first();
14705
+ // We want the last un-previously known text
14706
+ var endText = newTexts.last() || startText;
14707
+
14708
+ if (startText === endText) {
14709
+ editor.moveTo(endText.key, fragmentLength);
14710
+ return;
14631
14711
  }
14712
+
14713
+ // Everything will be calculated relative to the first common ancestor to optimize speed
14714
+ var parent = document.getCommonAncestor(startText.key, endText.key);
14715
+
14716
+ var startOffset = parent.getOffset(startText.key) + (start.key === startText.key ? start.offset : 0);
14717
+
14718
+ // endText might not be the last un-previously known text node, so we precisely pick it by offset
14719
+ endText = parent.getTextAtOffset(startOffset + fragmentLength - 1) || endText;
14720
+
14721
+ editor.moveTo(endText.key, startOffset + fragmentLength - parent.getOffset(endText.key));
14632
14722
  };
14633
14723
 
14634
14724
  /**
@@ -15191,14 +15281,27 @@ var Editor = function () {
15191
15281
 
15192
15282
  // Get the paths of the affected nodes, and mark them as dirty.
15193
15283
  var newDirtyPaths = getDirtyPaths(operation);
15194
- var dirty = this.tmp.dirty.reduce(function (memo, path) {
15284
+
15285
+ var dirty = this.tmp.dirty.map(function (path) {
15195
15286
  path = PathUtils.create(path);
15196
15287
  var transformed = PathUtils.transform(path, operation);
15197
- memo = memo.concat(transformed.toArray());
15198
- return memo;
15199
- }, newDirtyPaths);
15288
+ return transformed.toArray();
15289
+ });
15200
15290
 
15201
- this.tmp.dirty = dirty;
15291
+ var pathIndex = {};
15292
+ var dirtyPaths = Array.prototype.concat.apply(newDirtyPaths, dirty);
15293
+ this.tmp.dirty = [];
15294
+
15295
+ // PERF: De-dupe the paths so we don't do extra normalization.
15296
+ dirtyPaths.forEach(function (dirtyPath) {
15297
+ var key = dirtyPath.join(',');
15298
+
15299
+ if (!pathIndex[key]) {
15300
+ _this.tmp.dirty.push(dirtyPath);
15301
+ }
15302
+
15303
+ pathIndex[key] = true;
15304
+ });
15202
15305
 
15203
15306
  // If we're not already, queue the flushing process on the next tick.
15204
15307
  if (!this.tmp.flushing) {