prosemirror-transform 1.12.2 → 1.12.3

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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 1.12.3 (2026-10-22)
2
+
3
+ ### Bug fixes
4
+
5
+ Fix an issue that could make inverting a mapped `AddMarkStep` or `RemoveMarkStep` sometimes produce an inverse that didn't actually cancel out with the step itself.
6
+
1
7
  ## 1.12.2 (2026-09-25)
2
8
 
3
9
  ### Bug fixes
package/dist/index.cjs CHANGED
@@ -3,6 +3,9 @@
3
3
  function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
4
4
  function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct.bind(); } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
5
5
  function _isNativeFunction(fn) { try { return Function.toString.call(fn).indexOf("[native code]") !== -1; } catch (e) { return typeof fn === "function"; } }
6
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
7
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
8
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
6
9
  function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
7
10
  function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
8
11
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
@@ -363,6 +366,7 @@ var AddMarkStep = function (_Step) {
363
366
  key: "apply",
364
367
  value: function apply(doc) {
365
368
  var _this2 = this;
369
+ if (this.from == this.to) return new StepResult(doc, null);
366
370
  var oldSlice = doc.slice(this.from, this.to),
367
371
  $from = doc.resolve(this.from);
368
372
  var parent = $from.node($from.sharedDepth(this.to));
@@ -374,16 +378,40 @@ var AddMarkStep = function (_Step) {
374
378
  }
375
379
  }, {
376
380
  key: "invert",
377
- value: function invert() {
378
- return new RemoveMarkStep(this.from, this.to, this.mark);
381
+ value: function invert(doc) {
382
+ var _this3 = this;
383
+ var steps = [];
384
+ doc.nodesBetween(this.from, this.to, function (node, pos) {
385
+ if (node.isInline && node.isAtom) {
386
+ var added = _this3.mark.addToSet(node.marks);
387
+ if (!prosemirrorModel.Mark.sameSet(added, node.marks)) {
388
+ var from = Math.max(_this3.from, pos),
389
+ to = Math.min(_this3.to, pos + node.nodeSize);
390
+ steps.push(new RemoveMarkStep(from, to, _this3.mark));
391
+ var _iterator = _createForOfIteratorHelper(node.marks),
392
+ _step;
393
+ try {
394
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
395
+ var mark = _step.value;
396
+ if (!mark.isInSet(added)) steps.push(new AddMarkStep(from, to, mark));
397
+ }
398
+ } catch (err) {
399
+ _iterator.e(err);
400
+ } finally {
401
+ _iterator.f();
402
+ }
403
+ }
404
+ }
405
+ });
406
+ return steps.length == 0 ? new RemoveMarkStep(this.from, this.from, this.mark) : steps.length == 1 ? steps[0] : new MarkSetStep(steps);
379
407
  }
380
408
  }, {
381
409
  key: "map",
382
410
  value: function map(mapping) {
383
- var from = mapping.mapResult(this.from, 1),
384
- to = mapping.mapResult(this.to, -1);
385
- if (from.deleted && to.deleted || from.pos >= to.pos) return null;
386
- return new AddMarkStep(from.pos, to.pos, this.mark);
411
+ var from = mapping.map(this.from, 1),
412
+ to = mapping.map(this.to, -1);
413
+ if (from >= to) return null;
414
+ return new AddMarkStep(from, to, this.mark);
387
415
  }
388
416
  }, {
389
417
  key: "merge",
@@ -415,36 +443,42 @@ var RemoveMarkStep = function (_Step2) {
415
443
  _inherits(RemoveMarkStep, _Step2);
416
444
  var _super2 = _createSuper(RemoveMarkStep);
417
445
  function RemoveMarkStep(from, to, mark) {
418
- var _this3;
446
+ var _this4;
419
447
  _classCallCheck(this, RemoveMarkStep);
420
- _this3 = _super2.call(this);
421
- _this3.from = from;
422
- _this3.to = to;
423
- _this3.mark = mark;
424
- return _this3;
448
+ _this4 = _super2.call(this);
449
+ _this4.from = from;
450
+ _this4.to = to;
451
+ _this4.mark = mark;
452
+ return _this4;
425
453
  }
426
454
  _createClass(RemoveMarkStep, [{
427
455
  key: "apply",
428
456
  value: function apply(doc) {
429
- var _this4 = this;
457
+ var _this5 = this;
458
+ if (this.from == this.to) return new StepResult(doc, null);
430
459
  var oldSlice = doc.slice(this.from, this.to);
431
460
  var slice = new prosemirrorModel.Slice(mapFragment(oldSlice.content, function (node) {
432
- return node.mark(_this4.mark.removeFromSet(node.marks));
461
+ return node.mark(_this5.mark.removeFromSet(node.marks));
433
462
  }, doc), oldSlice.openStart, oldSlice.openEnd);
434
463
  return StepResult.fromReplace(doc, this.from, this.to, slice);
435
464
  }
436
465
  }, {
437
466
  key: "invert",
438
- value: function invert() {
439
- return new AddMarkStep(this.from, this.to, this.mark);
467
+ value: function invert(doc) {
468
+ var _this6 = this;
469
+ var steps = [];
470
+ doc.nodesBetween(this.from, this.to, function (node, pos) {
471
+ if (node.isInline && node.isAtom && _this6.mark.isInSet(node.marks)) steps.push(new AddMarkStep(Math.max(_this6.from, pos), Math.min(_this6.to, pos + node.nodeSize), _this6.mark));
472
+ });
473
+ return steps.length == 0 ? new AddMarkStep(this.from, this.from, this.mark) : steps.length == 1 ? steps[0] : new MarkSetStep(steps);
440
474
  }
441
475
  }, {
442
476
  key: "map",
443
477
  value: function map(mapping) {
444
- var from = mapping.mapResult(this.from, 1),
445
- to = mapping.mapResult(this.to, -1);
446
- if (from.deleted && to.deleted || from.pos >= to.pos) return null;
447
- return new RemoveMarkStep(from.pos, to.pos, this.mark);
478
+ var from = mapping.map(this.from, 1),
479
+ to = mapping.map(this.to, -1);
480
+ if (from >= to) return null;
481
+ return new RemoveMarkStep(from, to, this.mark);
448
482
  }
449
483
  }, {
450
484
  key: "merge",
@@ -472,16 +506,95 @@ var RemoveMarkStep = function (_Step2) {
472
506
  return RemoveMarkStep;
473
507
  }(Step);
474
508
  Step.jsonID("removeMark", RemoveMarkStep);
475
- var AddNodeMarkStep = function (_Step3) {
476
- _inherits(AddNodeMarkStep, _Step3);
477
- var _super3 = _createSuper(AddNodeMarkStep);
509
+ var MarkSetStep = function (_Step3) {
510
+ _inherits(MarkSetStep, _Step3);
511
+ var _super3 = _createSuper(MarkSetStep);
512
+ function MarkSetStep(steps) {
513
+ var _this7;
514
+ _classCallCheck(this, MarkSetStep);
515
+ _this7 = _super3.call(this);
516
+ _this7.steps = steps;
517
+ return _this7;
518
+ }
519
+ _createClass(MarkSetStep, [{
520
+ key: "apply",
521
+ value: function apply(doc) {
522
+ var _iterator2 = _createForOfIteratorHelper(this.steps),
523
+ _step2;
524
+ try {
525
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
526
+ var step = _step2.value;
527
+ var result = step.apply(doc);
528
+ if (!result.doc) return result;
529
+ doc = result.doc;
530
+ }
531
+ } catch (err) {
532
+ _iterator2.e(err);
533
+ } finally {
534
+ _iterator2.f();
535
+ }
536
+ return new StepResult(doc, null);
537
+ }
538
+ }, {
539
+ key: "invert",
540
+ value: function invert(doc) {
541
+ return new MarkSetStep(this.steps.map(function (s) {
542
+ return s.invert(doc);
543
+ }));
544
+ }
545
+ }, {
546
+ key: "map",
547
+ value: function map(mapping) {
548
+ var result = [];
549
+ var _iterator3 = _createForOfIteratorHelper(this.steps),
550
+ _step3;
551
+ try {
552
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
553
+ var step = _step3.value;
554
+ var mapped = step.map(mapping);
555
+ if (mapped) result.push(mapped);
556
+ }
557
+ } catch (err) {
558
+ _iterator3.e(err);
559
+ } finally {
560
+ _iterator3.f();
561
+ }
562
+ return result.length ? new MarkSetStep(result) : null;
563
+ }
564
+ }, {
565
+ key: "toJSON",
566
+ value: function toJSON() {
567
+ return {
568
+ stepType: "markSet",
569
+ steps: this.steps.map(function (s) {
570
+ return s.toJSON();
571
+ })
572
+ };
573
+ }
574
+ }, {
575
+ key: "fromJSON",
576
+ value: function fromJSON(schema, json) {
577
+ if (!Array.isArray(json.steps) || !json.steps.every(function (s) {
578
+ return s.stepType == "addMark" || s.stepType == "removeMark";
579
+ })) throw new RangeError("Invalid JSON for MarkSetStep");
580
+ return new MarkSetStep(json.steps.map(function (s) {
581
+ return Step.fromJSON(schema, s);
582
+ }));
583
+ }
584
+ }]);
585
+ return MarkSetStep;
586
+ }(Step);
587
+ Step.jsonID("markSet", MarkSetStep);
588
+ var AddNodeMarkStep = function (_Step4) {
589
+ _inherits(AddNodeMarkStep, _Step4);
590
+ var _super4 = _createSuper(AddNodeMarkStep);
478
591
  function AddNodeMarkStep(pos, mark) {
479
- var _this5;
592
+ var _this8;
480
593
  _classCallCheck(this, AddNodeMarkStep);
481
- _this5 = _super3.call(this);
482
- _this5.pos = pos;
483
- _this5.mark = mark;
484
- return _this5;
594
+ _this8 = _super4.call(this);
595
+ _this8.pos = pos;
596
+ _this8.mark = mark;
597
+ return _this8;
485
598
  }
486
599
  _createClass(AddNodeMarkStep, [{
487
600
  key: "apply",
@@ -529,16 +642,16 @@ var AddNodeMarkStep = function (_Step3) {
529
642
  return AddNodeMarkStep;
530
643
  }(Step);
531
644
  Step.jsonID("addNodeMark", AddNodeMarkStep);
532
- var RemoveNodeMarkStep = function (_Step4) {
533
- _inherits(RemoveNodeMarkStep, _Step4);
534
- var _super4 = _createSuper(RemoveNodeMarkStep);
645
+ var RemoveNodeMarkStep = function (_Step5) {
646
+ _inherits(RemoveNodeMarkStep, _Step5);
647
+ var _super5 = _createSuper(RemoveNodeMarkStep);
535
648
  function RemoveNodeMarkStep(pos, mark) {
536
- var _this6;
649
+ var _this9;
537
650
  _classCallCheck(this, RemoveNodeMarkStep);
538
- _this6 = _super4.call(this);
539
- _this6.pos = pos;
540
- _this6.mark = mark;
541
- return _this6;
651
+ _this9 = _super5.call(this);
652
+ _this9.pos = pos;
653
+ _this9.mark = mark;
654
+ return _this9;
542
655
  }
543
656
  _createClass(RemoveNodeMarkStep, [{
544
657
  key: "apply",
@@ -580,19 +693,19 @@ var RemoveNodeMarkStep = function (_Step4) {
580
693
  return RemoveNodeMarkStep;
581
694
  }(Step);
582
695
  Step.jsonID("removeNodeMark", RemoveNodeMarkStep);
583
- var ReplaceStep = function (_Step5) {
584
- _inherits(ReplaceStep, _Step5);
585
- var _super5 = _createSuper(ReplaceStep);
696
+ var ReplaceStep = function (_Step6) {
697
+ _inherits(ReplaceStep, _Step6);
698
+ var _super6 = _createSuper(ReplaceStep);
586
699
  function ReplaceStep(from, to, slice) {
587
- var _this7;
700
+ var _this10;
588
701
  var structure = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
589
702
  _classCallCheck(this, ReplaceStep);
590
- _this7 = _super5.call(this);
591
- _this7.from = from;
592
- _this7.to = to;
593
- _this7.slice = slice;
594
- _this7.structure = structure;
595
- return _this7;
703
+ _this10 = _super6.call(this);
704
+ _this10.from = from;
705
+ _this10.to = to;
706
+ _this10.slice = slice;
707
+ _this10.structure = structure;
708
+ return _this10;
596
709
  }
597
710
  _createClass(ReplaceStep, [{
598
711
  key: "apply",
@@ -655,22 +768,22 @@ var ReplaceStep = function (_Step5) {
655
768
  }(Step);
656
769
  ReplaceStep.MAP_BIAS = 1;
657
770
  Step.jsonID("replace", ReplaceStep);
658
- var ReplaceAroundStep = function (_Step6) {
659
- _inherits(ReplaceAroundStep, _Step6);
660
- var _super6 = _createSuper(ReplaceAroundStep);
771
+ var ReplaceAroundStep = function (_Step7) {
772
+ _inherits(ReplaceAroundStep, _Step7);
773
+ var _super7 = _createSuper(ReplaceAroundStep);
661
774
  function ReplaceAroundStep(from, to, gapFrom, gapTo, slice, insert) {
662
- var _this8;
775
+ var _this11;
663
776
  var structure = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;
664
777
  _classCallCheck(this, ReplaceAroundStep);
665
- _this8 = _super6.call(this);
666
- _this8.from = from;
667
- _this8.to = to;
668
- _this8.gapFrom = gapFrom;
669
- _this8.gapTo = gapTo;
670
- _this8.slice = slice;
671
- _this8.insert = insert;
672
- _this8.structure = structure;
673
- return _this8;
778
+ _this11 = _super7.call(this);
779
+ _this11.from = from;
780
+ _this11.to = to;
781
+ _this11.gapFrom = gapFrom;
782
+ _this11.gapTo = gapTo;
783
+ _this11.slice = slice;
784
+ _this11.insert = insert;
785
+ _this11.structure = structure;
786
+ return _this11;
674
787
  }
675
788
  _createClass(ReplaceAroundStep, [{
676
789
  key: "apply",
@@ -747,27 +860,17 @@ function contentBetween(doc, from, to) {
747
860
  return false;
748
861
  }
749
862
  function _addMark(tr, from, to, mark) {
750
- var removed = [],
751
- added = [];
752
- var removing, adding;
863
+ var added = [],
864
+ adding;
753
865
  tr.doc.nodesBetween(from, to, function (node, pos, parent) {
754
866
  if (!node.isInline) return;
755
867
  var marks = node.marks;
756
868
  if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) {
757
869
  var start = Math.max(pos, from),
758
870
  end = Math.min(pos + node.nodeSize, to);
759
- var newSet = mark.addToSet(marks);
760
- for (var i = 0; i < marks.length; i++) {
761
- if (!marks[i].isInSet(newSet)) {
762
- if (removing && removing.to == start && removing.mark.eq(marks[i])) removing.to = end;else removed.push(removing = new RemoveMarkStep(start, end, marks[i]));
763
- }
764
- }
765
871
  if (adding && adding.to == start) adding.to = end;else added.push(adding = new AddMarkStep(start, end, mark));
766
872
  }
767
873
  });
768
- removed.forEach(function (s) {
769
- return tr.step(s);
770
- });
771
874
  added.forEach(function (s) {
772
875
  return tr.step(s);
773
876
  });
@@ -776,7 +879,7 @@ function _removeMark(tr, from, to, mark) {
776
879
  var matched = [],
777
880
  step = 0;
778
881
  tr.doc.nodesBetween(from, to, function (node, pos) {
779
- if (!node.isInline) return;
882
+ if (!node.isInline || !node.isAtom) return;
780
883
  step++;
781
884
  var toRemove = null;
782
885
  if (mark instanceof prosemirrorModel.MarkType) {
@@ -1552,17 +1655,17 @@ function coveredDepths($from, $to) {
1552
1655
  }
1553
1656
  return result;
1554
1657
  }
1555
- var AttrStep = function (_Step7) {
1556
- _inherits(AttrStep, _Step7);
1557
- var _super7 = _createSuper(AttrStep);
1658
+ var AttrStep = function (_Step8) {
1659
+ _inherits(AttrStep, _Step8);
1660
+ var _super8 = _createSuper(AttrStep);
1558
1661
  function AttrStep(pos, attr, value) {
1559
- var _this9;
1662
+ var _this12;
1560
1663
  _classCallCheck(this, AttrStep);
1561
- _this9 = _super7.call(this);
1562
- _this9.pos = pos;
1563
- _this9.attr = attr;
1564
- _this9.value = value;
1565
- return _this9;
1664
+ _this12 = _super8.call(this);
1665
+ _this12.pos = pos;
1666
+ _this12.attr = attr;
1667
+ _this12.value = value;
1668
+ return _this12;
1566
1669
  }
1567
1670
  _createClass(AttrStep, [{
1568
1671
  key: "apply",
@@ -1611,16 +1714,16 @@ var AttrStep = function (_Step7) {
1611
1714
  return AttrStep;
1612
1715
  }(Step);
1613
1716
  Step.jsonID("attr", AttrStep);
1614
- var DocAttrStep = function (_Step8) {
1615
- _inherits(DocAttrStep, _Step8);
1616
- var _super8 = _createSuper(DocAttrStep);
1717
+ var DocAttrStep = function (_Step9) {
1718
+ _inherits(DocAttrStep, _Step9);
1719
+ var _super9 = _createSuper(DocAttrStep);
1617
1720
  function DocAttrStep(attr, value) {
1618
- var _this10;
1721
+ var _this13;
1619
1722
  _classCallCheck(this, DocAttrStep);
1620
- _this10 = _super8.call(this);
1621
- _this10.attr = attr;
1622
- _this10.value = value;
1623
- return _this10;
1723
+ _this13 = _super9.call(this);
1724
+ _this13.attr = attr;
1725
+ _this13.value = value;
1726
+ return _this13;
1624
1727
  }
1625
1728
  _createClass(DocAttrStep, [{
1626
1729
  key: "apply",
@@ -1667,10 +1770,10 @@ var DocAttrStep = function (_Step8) {
1667
1770
  Step.jsonID("docAttr", DocAttrStep);
1668
1771
  exports.TransformError = function (_Error) {
1669
1772
  _inherits(TransformError, _Error);
1670
- var _super9 = _createSuper(TransformError);
1773
+ var _super10 = _createSuper(TransformError);
1671
1774
  function TransformError() {
1672
1775
  _classCallCheck(this, TransformError);
1673
- return _super9.apply(this, arguments);
1776
+ return _super10.apply(this, arguments);
1674
1777
  }
1675
1778
  return _createClass(TransformError);
1676
1779
  }(_wrapNativeSuper(Error));
@@ -1697,8 +1800,8 @@ var Transform = function () {
1697
1800
  }
1698
1801
  }, {
1699
1802
  key: "step",
1700
- value: function step(_step) {
1701
- var result = this.maybeStep(_step);
1803
+ value: function step(_step4) {
1804
+ var result = this.maybeStep(_step4);
1702
1805
  if (result.failed) throw new exports.TransformError(result.failed);
1703
1806
  return this;
1704
1807
  }
package/dist/index.d.cts CHANGED
@@ -554,7 +554,7 @@ declare class AddMarkStep extends Step {
554
554
  */
555
555
  mark: Mark);
556
556
  apply(doc: Node): StepResult;
557
- invert(): Step;
557
+ invert(doc: Node): Step;
558
558
  map(mapping: Mappable): Step | null;
559
559
  merge(other: Step): Step | null;
560
560
  toJSON(): any;
@@ -592,7 +592,7 @@ declare class RemoveMarkStep extends Step {
592
592
  */
593
593
  mark: Mark);
594
594
  apply(doc: Node): StepResult;
595
- invert(): Step;
595
+ invert(doc: Node): Step;
596
596
  map(mapping: Mappable): Step | null;
597
597
  merge(other: Step): Step | null;
598
598
  toJSON(): any;
package/dist/index.d.ts CHANGED
@@ -554,7 +554,7 @@ declare class AddMarkStep extends Step {
554
554
  */
555
555
  mark: Mark);
556
556
  apply(doc: Node): StepResult;
557
- invert(): Step;
557
+ invert(doc: Node): Step;
558
558
  map(mapping: Mappable): Step | null;
559
559
  merge(other: Step): Step | null;
560
560
  toJSON(): any;
@@ -592,7 +592,7 @@ declare class RemoveMarkStep extends Step {
592
592
  */
593
593
  mark: Mark);
594
594
  apply(doc: Node): StepResult;
595
- invert(): Step;
595
+ invert(doc: Node): Step;
596
596
  map(mapping: Mappable): Step | null;
597
597
  merge(other: Step): Step | null;
598
598
  toJSON(): any;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { ReplaceError, Slice, Fragment, MarkType, Mark } from 'prosemirror-model';
1
+ import { ReplaceError, Slice, Mark, Fragment, MarkType } from 'prosemirror-model';
2
2
 
3
3
  // Recovery values encode a range index and an offset. They are
4
4
  // represented as numbers, because tons of them will be created when
@@ -457,6 +457,8 @@ class AddMarkStep extends Step {
457
457
  this.mark = mark;
458
458
  }
459
459
  apply(doc) {
460
+ if (this.from == this.to)
461
+ return new StepResult(doc, null);
460
462
  let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from);
461
463
  let parent = $from.node($from.sharedDepth(this.to));
462
464
  let slice = new Slice(mapFragment(oldSlice.content, (node, parent) => {
@@ -466,14 +468,28 @@ class AddMarkStep extends Step {
466
468
  }, parent), oldSlice.openStart, oldSlice.openEnd);
467
469
  return StepResult.fromReplace(doc, this.from, this.to, slice);
468
470
  }
469
- invert() {
470
- return new RemoveMarkStep(this.from, this.to, this.mark);
471
+ invert(doc) {
472
+ let steps = [];
473
+ doc.nodesBetween(this.from, this.to, (node, pos) => {
474
+ if (node.isInline && node.isAtom) {
475
+ let added = this.mark.addToSet(node.marks);
476
+ if (!Mark.sameSet(added, node.marks)) {
477
+ let from = Math.max(this.from, pos), to = Math.min(this.to, pos + node.nodeSize);
478
+ steps.push(new RemoveMarkStep(from, to, this.mark));
479
+ for (let mark of node.marks)
480
+ if (!mark.isInSet(added))
481
+ steps.push(new AddMarkStep(from, to, mark));
482
+ }
483
+ }
484
+ });
485
+ return steps.length == 0 ? new RemoveMarkStep(this.from, this.from, this.mark)
486
+ : steps.length == 1 ? steps[0] : new MarkSetStep(steps);
471
487
  }
472
488
  map(mapping) {
473
- let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
474
- if (from.deleted && to.deleted || from.pos >= to.pos)
489
+ let from = mapping.map(this.from, 1), to = mapping.map(this.to, -1);
490
+ if (from >= to)
475
491
  return null;
476
- return new AddMarkStep(from.pos, to.pos, this.mark);
492
+ return new AddMarkStep(from, to, this.mark);
477
493
  }
478
494
  merge(other) {
479
495
  if (other instanceof AddMarkStep &&
@@ -522,20 +538,28 @@ class RemoveMarkStep extends Step {
522
538
  this.mark = mark;
523
539
  }
524
540
  apply(doc) {
541
+ if (this.from == this.to)
542
+ return new StepResult(doc, null);
525
543
  let oldSlice = doc.slice(this.from, this.to);
526
544
  let slice = new Slice(mapFragment(oldSlice.content, node => {
527
545
  return node.mark(this.mark.removeFromSet(node.marks));
528
546
  }, doc), oldSlice.openStart, oldSlice.openEnd);
529
547
  return StepResult.fromReplace(doc, this.from, this.to, slice);
530
548
  }
531
- invert() {
532
- return new AddMarkStep(this.from, this.to, this.mark);
549
+ invert(doc) {
550
+ let steps = [];
551
+ doc.nodesBetween(this.from, this.to, (node, pos) => {
552
+ if (node.isInline && node.isAtom && this.mark.isInSet(node.marks))
553
+ steps.push(new AddMarkStep(Math.max(this.from, pos), Math.min(this.to, pos + node.nodeSize), this.mark));
554
+ });
555
+ return steps.length == 0 ? new AddMarkStep(this.from, this.from, this.mark)
556
+ : steps.length == 1 ? steps[0] : new MarkSetStep(steps);
533
557
  }
534
558
  map(mapping) {
535
- let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
536
- if (from.deleted && to.deleted || from.pos >= to.pos)
559
+ let from = mapping.map(this.from, 1), to = mapping.map(this.to, -1);
560
+ if (from >= to)
537
561
  return null;
538
- return new RemoveMarkStep(from.pos, to.pos, this.mark);
562
+ return new RemoveMarkStep(from, to, this.mark);
539
563
  }
540
564
  merge(other) {
541
565
  if (other instanceof RemoveMarkStep &&
@@ -558,6 +582,42 @@ class RemoveMarkStep extends Step {
558
582
  }
559
583
  }
560
584
  Step.jsonID("removeMark", RemoveMarkStep);
585
+ class MarkSetStep extends Step {
586
+ constructor(steps) {
587
+ super();
588
+ this.steps = steps;
589
+ }
590
+ apply(doc) {
591
+ for (let step of this.steps) {
592
+ let result = step.apply(doc);
593
+ if (!result.doc)
594
+ return result;
595
+ doc = result.doc;
596
+ }
597
+ return new StepResult(doc, null);
598
+ }
599
+ invert(doc) {
600
+ return new MarkSetStep(this.steps.map(s => s.invert(doc)));
601
+ }
602
+ map(mapping) {
603
+ let result = [];
604
+ for (let step of this.steps) {
605
+ let mapped = step.map(mapping);
606
+ if (mapped)
607
+ result.push(mapped);
608
+ }
609
+ return result.length ? new MarkSetStep(result) : null;
610
+ }
611
+ toJSON() {
612
+ return { stepType: "markSet", steps: this.steps.map(s => s.toJSON()) };
613
+ }
614
+ fromJSON(schema, json) {
615
+ if (!Array.isArray(json.steps) || !json.steps.every((s) => s.stepType == "addMark" || s.stepType == "removeMark"))
616
+ throw new RangeError("Invalid JSON for MarkSetStep");
617
+ return new MarkSetStep(json.steps.map((s) => Step.fromJSON(schema, s)));
618
+ }
619
+ }
620
+ Step.jsonID("markSet", MarkSetStep);
561
621
  /**
562
622
  Add a mark to a specific node.
563
623
  */
@@ -882,36 +942,25 @@ function contentBetween(doc, from, to) {
882
942
  }
883
943
 
884
944
  function addMark(tr, from, to, mark) {
885
- let removed = [], added = [];
886
- let removing, adding;
945
+ let added = [], adding;
887
946
  tr.doc.nodesBetween(from, to, (node, pos, parent) => {
888
947
  if (!node.isInline)
889
948
  return;
890
949
  let marks = node.marks;
891
950
  if (!mark.isInSet(marks) && parent.type.allowsMarkType(mark.type)) {
892
951
  let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to);
893
- let newSet = mark.addToSet(marks);
894
- for (let i = 0; i < marks.length; i++) {
895
- if (!marks[i].isInSet(newSet)) {
896
- if (removing && removing.to == start && removing.mark.eq(marks[i]))
897
- removing.to = end;
898
- else
899
- removed.push(removing = new RemoveMarkStep(start, end, marks[i]));
900
- }
901
- }
902
952
  if (adding && adding.to == start)
903
953
  adding.to = end;
904
954
  else
905
955
  added.push(adding = new AddMarkStep(start, end, mark));
906
956
  }
907
957
  });
908
- removed.forEach(s => tr.step(s));
909
958
  added.forEach(s => tr.step(s));
910
959
  }
911
960
  function removeMark(tr, from, to, mark) {
912
961
  let matched = [], step = 0;
913
962
  tr.doc.nodesBetween(from, to, (node, pos) => {
914
- if (!node.isInline)
963
+ if (!node.isInline || !node.isAtom)
915
964
  return;
916
965
  step++;
917
966
  let toRemove = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prosemirror-transform",
3
- "version": "1.12.2",
3
+ "version": "1.12.3",
4
4
  "description": "ProseMirror document transformations",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
package/src/mark.ts CHANGED
@@ -6,39 +6,23 @@ import {AddMarkStep, RemoveMarkStep} from "./mark_step"
6
6
  import {ReplaceStep} from "./replace_step"
7
7
 
8
8
  export function addMark(tr: Transform, from: number, to: number, mark: Mark) {
9
- let removed: Step[] = [], added: Step[] = []
10
- let removing: RemoveMarkStep | undefined, adding: AddMarkStep | undefined
9
+ let added: Step[] = [], adding: AddMarkStep | undefined
11
10
  tr.doc.nodesBetween(from, to, (node, pos, parent) => {
12
11
  if (!node.isInline) return
13
12
  let marks = node.marks
14
13
  if (!mark.isInSet(marks) && parent!.type.allowsMarkType(mark.type)) {
15
14
  let start = Math.max(pos, from), end = Math.min(pos + node.nodeSize, to)
16
- let newSet = mark.addToSet(marks)
17
-
18
- for (let i = 0; i < marks.length; i++) {
19
- if (!marks[i].isInSet(newSet)) {
20
- if (removing && removing.to == start && removing.mark.eq(marks[i]))
21
- (removing as any).to = end
22
- else
23
- removed.push(removing = new RemoveMarkStep(start, end, marks[i]))
24
- }
25
- }
26
-
27
- if (adding && adding.to == start)
28
- (adding as any).to = end
29
- else
30
- added.push(adding = new AddMarkStep(start, end, mark))
15
+ if (adding && adding.to == start) (adding as any).to = end
16
+ else added.push(adding = new AddMarkStep(start, end, mark))
31
17
  }
32
18
  })
33
-
34
- removed.forEach(s => tr.step(s))
35
19
  added.forEach(s => tr.step(s))
36
20
  }
37
21
 
38
22
  export function removeMark(tr: Transform, from: number, to: number, mark?: Mark | MarkType | null) {
39
23
  let matched: {style: Mark, from: number, to: number, step: number}[] = [], step = 0
40
24
  tr.doc.nodesBetween(from, to, (node, pos) => {
41
- if (!node.isInline) return
25
+ if (!node.isInline || !node.isAtom) return
42
26
  step++
43
27
  let toRemove = null
44
28
  if (mark instanceof MarkType) {
package/src/mark_step.ts CHANGED
@@ -28,6 +28,7 @@ export class AddMarkStep extends Step {
28
28
  }
29
29
 
30
30
  apply(doc: Node) {
31
+ if (this.from == this.to) return new StepResult(doc, null)
31
32
  let oldSlice = doc.slice(this.from, this.to), $from = doc.resolve(this.from)
32
33
  let parent = $from.node($from.sharedDepth(this.to))
33
34
  let slice = new Slice(mapFragment(oldSlice.content, (node, parent) => {
@@ -37,14 +38,27 @@ export class AddMarkStep extends Step {
37
38
  return StepResult.fromReplace(doc, this.from, this.to, slice)
38
39
  }
39
40
 
40
- invert(): Step {
41
- return new RemoveMarkStep(this.from, this.to, this.mark)
41
+ invert(doc: Node): Step {
42
+ let steps: (RemoveMarkStep | AddMarkStep)[] = []
43
+ doc.nodesBetween(this.from, this.to, (node, pos) => {
44
+ if (node.isInline && node.isAtom) {
45
+ let added = this.mark.addToSet(node.marks)
46
+ if (!Mark.sameSet(added, node.marks)) {
47
+ let from = Math.max(this.from, pos), to = Math.min(this.to, pos + node.nodeSize)
48
+ steps.push(new RemoveMarkStep(from, to, this.mark))
49
+ for (let mark of node.marks) if (!mark.isInSet(added))
50
+ steps.push(new AddMarkStep(from, to, mark))
51
+ }
52
+ }
53
+ })
54
+ return steps.length == 0 ? new RemoveMarkStep(this.from, this.from, this.mark)
55
+ : steps.length == 1 ? steps[0] : new MarkSetStep(steps)
42
56
  }
43
57
 
44
58
  map(mapping: Mappable): Step | null {
45
- let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)
46
- if (from.deleted && to.deleted || from.pos >= to.pos) return null
47
- return new AddMarkStep(from.pos, to.pos, this.mark)
59
+ let from = mapping.map(this.from, 1), to = mapping.map(this.to, -1)
60
+ if (from >= to) return null
61
+ return new AddMarkStep(from, to, this.mark)
48
62
  }
49
63
 
50
64
  merge(other: Step): Step | null {
@@ -86,6 +100,7 @@ export class RemoveMarkStep extends Step {
86
100
  }
87
101
 
88
102
  apply(doc: Node) {
103
+ if (this.from == this.to) return new StepResult(doc, null)
89
104
  let oldSlice = doc.slice(this.from, this.to)
90
105
  let slice = new Slice(mapFragment(oldSlice.content, node => {
91
106
  return node.mark(this.mark.removeFromSet(node.marks))
@@ -93,14 +108,20 @@ export class RemoveMarkStep extends Step {
93
108
  return StepResult.fromReplace(doc, this.from, this.to, slice)
94
109
  }
95
110
 
96
- invert(): Step {
97
- return new AddMarkStep(this.from, this.to, this.mark)
111
+ invert(doc: Node): Step {
112
+ let steps: AddMarkStep[] = []
113
+ doc.nodesBetween(this.from, this.to, (node, pos) => {
114
+ if (node.isInline && node.isAtom && this.mark.isInSet(node.marks))
115
+ steps.push(new AddMarkStep(Math.max(this.from, pos), Math.min(this.to, pos + node.nodeSize), this.mark))
116
+ })
117
+ return steps.length == 0 ? new AddMarkStep(this.from, this.from, this.mark)
118
+ : steps.length == 1 ? steps[0] : new MarkSetStep(steps)
98
119
  }
99
120
 
100
121
  map(mapping: Mappable): Step | null {
101
- let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1)
102
- if (from.deleted && to.deleted || from.pos >= to.pos) return null
103
- return new RemoveMarkStep(from.pos, to.pos, this.mark)
122
+ let from = mapping.map(this.from, 1), to = mapping.map(this.to, -1)
123
+ if (from >= to) return null
124
+ return new RemoveMarkStep(from, to, this.mark)
104
125
  }
105
126
 
106
127
  merge(other: Step): Step | null {
@@ -127,6 +148,48 @@ export class RemoveMarkStep extends Step {
127
148
 
128
149
  Step.jsonID("removeMark", RemoveMarkStep)
129
150
 
151
+ class MarkSetStep extends Step {
152
+ constructor(
153
+ readonly steps: readonly (AddMarkStep | RemoveMarkStep)[]
154
+ ) {
155
+ super()
156
+ }
157
+
158
+ apply(doc: Node) {
159
+ for (let step of this.steps) {
160
+ let result = step.apply(doc)
161
+ if (!result.doc) return result
162
+ doc = result.doc
163
+ }
164
+ return new StepResult(doc, null)
165
+ }
166
+
167
+ invert(doc: Node): Step {
168
+ return new MarkSetStep(this.steps.map(s => s.invert(doc) as AddMarkStep | RemoveMarkStep))
169
+ }
170
+
171
+ map(mapping: Mappable) {
172
+ let result: (AddMarkStep | RemoveMarkStep)[] = []
173
+ for (let step of this.steps) {
174
+ let mapped = step.map(mapping)
175
+ if (mapped) result.push(mapped as AddMarkStep | RemoveMarkStep)
176
+ }
177
+ return result.length ? new MarkSetStep(result) : null
178
+ }
179
+
180
+ toJSON() {
181
+ return {stepType: "markSet", steps: this.steps.map(s => s.toJSON())}
182
+ }
183
+
184
+ fromJSON(schema: Schema, json: any) {
185
+ if (!Array.isArray(json.steps) || !json.steps.every((s: any) => s.stepType == "addMark" || s.stepType == "removeMark"))
186
+ throw new RangeError("Invalid JSON for MarkSetStep")
187
+ return new MarkSetStep(json.steps.map((s: any) => Step.fromJSON(schema, s)))
188
+ }
189
+ }
190
+
191
+ Step.jsonID("markSet", MarkSetStep)
192
+
130
193
  /// Add a mark to a specific node.
131
194
  export class AddNodeMarkStep extends Step {
132
195
  /// Create a node mark step.