@atlaskit/prosemirror-collab 0.16.2 → 0.16.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,5 +1,14 @@
1
1
  # @atlaskit/prosemirror-collab
2
2
 
3
+ ## 0.16.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#144227](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/144227)
8
+ [`6da190d8e3a24`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/6da190d8e3a24) -
9
+ Add ability to rebase drag and drop content
10
+ - Updated dependencies
11
+
3
12
  ## 0.16.2
4
13
 
5
14
  ### Patch Changes
package/dist/cjs/index.js CHANGED
@@ -4,6 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
+ exports.Rebaseable = void 0;
7
8
  exports.collab = collab;
8
9
  exports.getCollabState = getCollabState;
9
10
  exports.getDocBeforeUnconfirmedSteps = getDocBeforeUnconfirmedSteps;
@@ -16,13 +17,13 @@ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/cl
16
17
  var _uuid = require("uuid");
17
18
  var _state = require("@atlaskit/editor-prosemirror/state");
18
19
  var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
19
- var Rebaseable = /*#__PURE__*/(0, _createClass2.default)(function Rebaseable(step, inverted, origin) {
20
+ var _movedContent = require("./movedContent");
21
+ var Rebaseable = exports.Rebaseable = /*#__PURE__*/(0, _createClass2.default)(function Rebaseable(step, inverted, origin) {
20
22
  (0, _classCallCheck2.default)(this, Rebaseable);
21
23
  this.step = step;
22
24
  this.inverted = inverted;
23
25
  this.origin = origin;
24
- }); /// Undo a given set of steps, apply a set of other steps, and then
25
- /// redo them @internal
26
+ });
26
27
  function rebaseSteps(steps, over, transform) {
27
28
  for (var i = steps.length - 1; i >= 0; i--) {
28
29
  transform.step(steps[i].inverted);
@@ -33,6 +34,7 @@ function rebaseSteps(steps, over, transform) {
33
34
  var result = [];
34
35
  for (var _i2 = 0, mapFrom = steps.length; _i2 < steps.length; _i2++) {
35
36
  var mapped = steps[_i2].step.map(transform.mapping.slice(mapFrom));
37
+ var movedStep = (0, _experiments.editorExperiment)('platform_editor_offline_editing_web', true) ? (0, _movedContent.mapStep)(steps, transform, _i2, mapped) : undefined;
36
38
  mapFrom--;
37
39
  if (mapped && !transform.maybeStep(mapped).failed) {
38
40
  // Open ticket for setMirror https://github.com/ProseMirror/prosemirror/issues/869
@@ -40,6 +42,13 @@ function rebaseSteps(steps, over, transform) {
40
42
  transform.mapping.setMirror(mapFrom, transform.steps.length - 1);
41
43
  result.push(new Rebaseable(mapped, mapped.invert(transform.docs[transform.docs.length - 1]), steps[_i2].origin));
42
44
  }
45
+
46
+ // If the step is a "move" step - apply the additional step
47
+ if ((0, _experiments.editorExperiment)('platform_editor_offline_editing_web', true)) {
48
+ if (movedStep && !transform.maybeStep(movedStep).failed) {
49
+ result.push(new Rebaseable(movedStep, movedStep.invert(transform.docs[transform.docs.length - 1]), transform));
50
+ }
51
+ }
43
52
  }
44
53
  return result;
45
54
  }
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.mapStep = void 0;
7
+ var _model = require("@atlaskit/editor-prosemirror/model");
8
+ var _transform = require("@atlaskit/editor-prosemirror/transform");
9
+ var mapStep = exports.mapStep = function mapStep(steps, transform, index, mapped) {
10
+ if (index < 1) {
11
+ return undefined;
12
+ }
13
+ var previousRebaseableStep = steps[index - 1];
14
+ if (
15
+ // This checks the local steps are a "move" sequence
16
+ isMoveSequence(previousRebaseableStep.step, steps[index].step,
17
+ // Used to get the document prior to step changes
18
+ previousRebaseableStep)) {
19
+ var previousStep = transform.steps[transform.steps.length - 1];
20
+ // Creates a new step based on the "current" steps (partially through the rebase)
21
+ return createMoveMapStep(mapped, previousStep, transform);
22
+ }
23
+ return undefined;
24
+ };
25
+
26
+ // Only consider ReplaceStep (ReplaceAroundStep do not occur for moves)
27
+ var isReplaceTypeStep = function isReplaceTypeStep(step) {
28
+ return step instanceof _transform.ReplaceStep;
29
+ };
30
+
31
+ /**
32
+ * Determines if a step pairing is a move sequence (ie. drag + drop or cut + paste).
33
+ *
34
+ * We determine this if we have a deletion followed by insertion and their content matches
35
+ *
36
+ * @param previousStep
37
+ * @param currentStep
38
+ * @param previousRebaseable
39
+ */
40
+ var isMoveSequence = function isMoveSequence(previousStep, currentStep, previousRebaseable) {
41
+ if (
42
+ // The both steps are replace
43
+ isReplaceTypeStep(previousStep) && isReplaceTypeStep(currentStep) &&
44
+ // The current step is a deletion
45
+ previousStep.slice.size === 0 &&
46
+ // The following step is an insertion with the same length that was deleted by the current step
47
+ Math.abs(previousStep.to - previousStep.from) === currentStep.slice.size) {
48
+ // Ensure we're getting the doc before our step changes so we can compare node contents
49
+ var originStepIndex = previousRebaseable.origin.steps.findIndex(function (s) {
50
+ return s === previousStep;
51
+ });
52
+ var originalDoc = previousRebaseable.origin.docs[originStepIndex];
53
+ var currentSlice = originalDoc.slice(previousStep.from, previousStep.to);
54
+ // The content from the deleted + inserted slice is exactly the same (cut + paste or drag + drop)
55
+ if (currentSlice.eq(currentStep.slice)) {
56
+ return true;
57
+ }
58
+ }
59
+ return false;
60
+ };
61
+
62
+ /**
63
+ * Update the replace step slice of the insert part of a move
64
+ * to contain the slice of the current document rather than what was sliced originally.
65
+ *
66
+ * @param mapped
67
+ * @param previousStep
68
+ * @param transform
69
+ * @returns Step to apply missing changes
70
+ */
71
+ var createMoveMapStep = function createMoveMapStep(mapped, previousStep, transform) {
72
+ if (!isReplaceTypeStep(previousStep) || mapped && !isReplaceTypeStep(mapped) || !mapped) {
73
+ return undefined;
74
+ }
75
+ var newSlice = transform.docs[transform.docs.length - 1].slice(previousStep === null || previousStep === void 0 ? void 0 : previousStep.from, previousStep === null || previousStep === void 0 ? void 0 : previousStep.to);
76
+ var diff = getDiffRange(mapped.slice.content, newSlice.content);
77
+ if (diff === undefined) {
78
+ return undefined;
79
+ }
80
+ var start = mapped.from + diff.start;
81
+ var offset = newSlice.content.size - mapped.slice.content.size === 0 ? diff.end - diff.start : 0;
82
+
83
+ // If the new slice is smaller then we're doing a deletion of content - this needs
84
+ // to be a replace step with empty content to delete content
85
+ if (newSlice.content.size - mapped.slice.content.size < 0) {
86
+ return new _transform.ReplaceStep(start, start + mapped.slice.content.size - newSlice.content.size, _model.Slice.empty);
87
+ }
88
+
89
+ // Replace the diff range with the latest content in the document (at the old position)
90
+ return new _transform.ReplaceStep(start, start + offset, transform.docs[transform.docs.length - 1].slice((previousStep === null || previousStep === void 0 ? void 0 : previousStep.from) + diff.start, (previousStep === null || previousStep === void 0 ? void 0 : previousStep.from) + diff.end));
91
+ };
92
+
93
+ /**
94
+ * Get start and end diff position values for two fragments (old, new).
95
+ * @param {Fragment} before - content that is planned to move
96
+ * @param {Fragment} after - content that was in paragraph being deleted (updated content)
97
+ * @returns {object} - { start, end }
98
+ */
99
+ function getDiffRange(before, after) {
100
+ // https://prosemirror.net/docs/ref/#model.Fragment.findDiffStart
101
+ var start = before.findDiffStart(after);
102
+ // Important: diffEnd value is {a,b} object since end pos will differ.
103
+ // https://prosemirror.net/docs/ref/#model.Fragment.findDiffEnd
104
+ var diffEnd = before.findDiffEnd(after);
105
+ if (start === null || diffEnd === null) {
106
+ return undefined;
107
+ }
108
+ // WARNING: diffEnd may be lower than diffStart.
109
+ // If so, add overlap to get correct range.
110
+ // https://discuss.prosemirror.net/t/overlap-handling-of-finddiffstart-and-finddiffend/2856
111
+ var overlap = start - Math.min(diffEnd.a, diffEnd.b);
112
+ var end = diffEnd.b;
113
+ if (overlap > 0) {
114
+ end += overlap;
115
+ }
116
+ return {
117
+ start: start,
118
+ end: end
119
+ };
120
+ }
@@ -1,16 +1,14 @@
1
1
  import { v4 as uuidv4 } from 'uuid';
2
2
  import { Plugin, PluginKey, TextSelection } from '@atlaskit/editor-prosemirror/state';
3
3
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
4
- class Rebaseable {
4
+ import { mapStep } from './movedContent';
5
+ export class Rebaseable {
5
6
  constructor(step, inverted, origin) {
6
7
  this.step = step;
7
8
  this.inverted = inverted;
8
9
  this.origin = origin;
9
10
  }
10
11
  }
11
-
12
- /// Undo a given set of steps, apply a set of other steps, and then
13
- /// redo them @internal
14
12
  export function rebaseSteps(steps, over, transform) {
15
13
  for (let i = steps.length - 1; i >= 0; i--) {
16
14
  transform.step(steps[i].inverted);
@@ -21,6 +19,7 @@ export function rebaseSteps(steps, over, transform) {
21
19
  const result = [];
22
20
  for (let i = 0, mapFrom = steps.length; i < steps.length; i++) {
23
21
  const mapped = steps[i].step.map(transform.mapping.slice(mapFrom));
22
+ const movedStep = editorExperiment('platform_editor_offline_editing_web', true) ? mapStep(steps, transform, i, mapped) : undefined;
24
23
  mapFrom--;
25
24
  if (mapped && !transform.maybeStep(mapped).failed) {
26
25
  // Open ticket for setMirror https://github.com/ProseMirror/prosemirror/issues/869
@@ -28,6 +27,13 @@ export function rebaseSteps(steps, over, transform) {
28
27
  transform.mapping.setMirror(mapFrom, transform.steps.length - 1);
29
28
  result.push(new Rebaseable(mapped, mapped.invert(transform.docs[transform.docs.length - 1]), steps[i].origin));
30
29
  }
30
+
31
+ // If the step is a "move" step - apply the additional step
32
+ if (editorExperiment('platform_editor_offline_editing_web', true)) {
33
+ if (movedStep && !transform.maybeStep(movedStep).failed) {
34
+ result.push(new Rebaseable(movedStep, movedStep.invert(transform.docs[transform.docs.length - 1]), transform));
35
+ }
36
+ }
31
37
  }
32
38
  return result;
33
39
  }
@@ -0,0 +1,110 @@
1
+ import { Slice } from '@atlaskit/editor-prosemirror/model';
2
+ import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
3
+ export const mapStep = (steps, transform, index, mapped) => {
4
+ if (index < 1) {
5
+ return undefined;
6
+ }
7
+ const previousRebaseableStep = steps[index - 1];
8
+ if (
9
+ // This checks the local steps are a "move" sequence
10
+ isMoveSequence(previousRebaseableStep.step, steps[index].step,
11
+ // Used to get the document prior to step changes
12
+ previousRebaseableStep)) {
13
+ const previousStep = transform.steps[transform.steps.length - 1];
14
+ // Creates a new step based on the "current" steps (partially through the rebase)
15
+ return createMoveMapStep(mapped, previousStep, transform);
16
+ }
17
+ return undefined;
18
+ };
19
+
20
+ // Only consider ReplaceStep (ReplaceAroundStep do not occur for moves)
21
+ const isReplaceTypeStep = step => step instanceof ReplaceStep;
22
+
23
+ /**
24
+ * Determines if a step pairing is a move sequence (ie. drag + drop or cut + paste).
25
+ *
26
+ * We determine this if we have a deletion followed by insertion and their content matches
27
+ *
28
+ * @param previousStep
29
+ * @param currentStep
30
+ * @param previousRebaseable
31
+ */
32
+ const isMoveSequence = (previousStep, currentStep, previousRebaseable) => {
33
+ if (
34
+ // The both steps are replace
35
+ isReplaceTypeStep(previousStep) && isReplaceTypeStep(currentStep) &&
36
+ // The current step is a deletion
37
+ previousStep.slice.size === 0 &&
38
+ // The following step is an insertion with the same length that was deleted by the current step
39
+ Math.abs(previousStep.to - previousStep.from) === currentStep.slice.size) {
40
+ // Ensure we're getting the doc before our step changes so we can compare node contents
41
+ const originStepIndex = previousRebaseable.origin.steps.findIndex(s => s === previousStep);
42
+ const originalDoc = previousRebaseable.origin.docs[originStepIndex];
43
+ const currentSlice = originalDoc.slice(previousStep.from, previousStep.to);
44
+ // The content from the deleted + inserted slice is exactly the same (cut + paste or drag + drop)
45
+ if (currentSlice.eq(currentStep.slice)) {
46
+ return true;
47
+ }
48
+ }
49
+ return false;
50
+ };
51
+
52
+ /**
53
+ * Update the replace step slice of the insert part of a move
54
+ * to contain the slice of the current document rather than what was sliced originally.
55
+ *
56
+ * @param mapped
57
+ * @param previousStep
58
+ * @param transform
59
+ * @returns Step to apply missing changes
60
+ */
61
+ const createMoveMapStep = (mapped, previousStep, transform) => {
62
+ if (!isReplaceTypeStep(previousStep) || mapped && !isReplaceTypeStep(mapped) || !mapped) {
63
+ return undefined;
64
+ }
65
+ const newSlice = transform.docs[transform.docs.length - 1].slice(previousStep === null || previousStep === void 0 ? void 0 : previousStep.from, previousStep === null || previousStep === void 0 ? void 0 : previousStep.to);
66
+ const diff = getDiffRange(mapped.slice.content, newSlice.content);
67
+ if (diff === undefined) {
68
+ return undefined;
69
+ }
70
+ const start = mapped.from + diff.start;
71
+ const offset = newSlice.content.size - mapped.slice.content.size === 0 ? diff.end - diff.start : 0;
72
+
73
+ // If the new slice is smaller then we're doing a deletion of content - this needs
74
+ // to be a replace step with empty content to delete content
75
+ if (newSlice.content.size - mapped.slice.content.size < 0) {
76
+ return new ReplaceStep(start, start + mapped.slice.content.size - newSlice.content.size, Slice.empty);
77
+ }
78
+
79
+ // Replace the diff range with the latest content in the document (at the old position)
80
+ return new ReplaceStep(start, start + offset, transform.docs[transform.docs.length - 1].slice((previousStep === null || previousStep === void 0 ? void 0 : previousStep.from) + diff.start, (previousStep === null || previousStep === void 0 ? void 0 : previousStep.from) + diff.end));
81
+ };
82
+
83
+ /**
84
+ * Get start and end diff position values for two fragments (old, new).
85
+ * @param {Fragment} before - content that is planned to move
86
+ * @param {Fragment} after - content that was in paragraph being deleted (updated content)
87
+ * @returns {object} - { start, end }
88
+ */
89
+ function getDiffRange(before, after) {
90
+ // https://prosemirror.net/docs/ref/#model.Fragment.findDiffStart
91
+ const start = before.findDiffStart(after);
92
+ // Important: diffEnd value is {a,b} object since end pos will differ.
93
+ // https://prosemirror.net/docs/ref/#model.Fragment.findDiffEnd
94
+ const diffEnd = before.findDiffEnd(after);
95
+ if (start === null || diffEnd === null) {
96
+ return undefined;
97
+ }
98
+ // WARNING: diffEnd may be lower than diffStart.
99
+ // If so, add overlap to get correct range.
100
+ // https://discuss.prosemirror.net/t/overlap-handling-of-finddiffstart-and-finddiffend/2856
101
+ const overlap = start - Math.min(diffEnd.a, diffEnd.b);
102
+ let end = diffEnd.b;
103
+ if (overlap > 0) {
104
+ end += overlap;
105
+ }
106
+ return {
107
+ start,
108
+ end
109
+ };
110
+ }
package/dist/esm/index.js CHANGED
@@ -3,13 +3,13 @@ import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
3
3
  import { v4 as uuidv4 } from 'uuid';
4
4
  import { Plugin, PluginKey, TextSelection } from '@atlaskit/editor-prosemirror/state';
5
5
  import { editorExperiment } from '@atlaskit/tmp-editor-statsig/experiments';
6
- var Rebaseable = /*#__PURE__*/_createClass(function Rebaseable(step, inverted, origin) {
6
+ import { mapStep } from './movedContent';
7
+ export var Rebaseable = /*#__PURE__*/_createClass(function Rebaseable(step, inverted, origin) {
7
8
  _classCallCheck(this, Rebaseable);
8
9
  this.step = step;
9
10
  this.inverted = inverted;
10
11
  this.origin = origin;
11
- }); /// Undo a given set of steps, apply a set of other steps, and then
12
- /// redo them @internal
12
+ });
13
13
  export function rebaseSteps(steps, over, transform) {
14
14
  for (var i = steps.length - 1; i >= 0; i--) {
15
15
  transform.step(steps[i].inverted);
@@ -20,6 +20,7 @@ export function rebaseSteps(steps, over, transform) {
20
20
  var result = [];
21
21
  for (var _i2 = 0, mapFrom = steps.length; _i2 < steps.length; _i2++) {
22
22
  var mapped = steps[_i2].step.map(transform.mapping.slice(mapFrom));
23
+ var movedStep = editorExperiment('platform_editor_offline_editing_web', true) ? mapStep(steps, transform, _i2, mapped) : undefined;
23
24
  mapFrom--;
24
25
  if (mapped && !transform.maybeStep(mapped).failed) {
25
26
  // Open ticket for setMirror https://github.com/ProseMirror/prosemirror/issues/869
@@ -27,6 +28,13 @@ export function rebaseSteps(steps, over, transform) {
27
28
  transform.mapping.setMirror(mapFrom, transform.steps.length - 1);
28
29
  result.push(new Rebaseable(mapped, mapped.invert(transform.docs[transform.docs.length - 1]), steps[_i2].origin));
29
30
  }
31
+
32
+ // If the step is a "move" step - apply the additional step
33
+ if (editorExperiment('platform_editor_offline_editing_web', true)) {
34
+ if (movedStep && !transform.maybeStep(movedStep).failed) {
35
+ result.push(new Rebaseable(movedStep, movedStep.invert(transform.docs[transform.docs.length - 1]), transform));
36
+ }
37
+ }
30
38
  }
31
39
  return result;
32
40
  }
@@ -0,0 +1,114 @@
1
+ import { Slice } from '@atlaskit/editor-prosemirror/model';
2
+ import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
3
+ export var mapStep = function mapStep(steps, transform, index, mapped) {
4
+ if (index < 1) {
5
+ return undefined;
6
+ }
7
+ var previousRebaseableStep = steps[index - 1];
8
+ if (
9
+ // This checks the local steps are a "move" sequence
10
+ isMoveSequence(previousRebaseableStep.step, steps[index].step,
11
+ // Used to get the document prior to step changes
12
+ previousRebaseableStep)) {
13
+ var previousStep = transform.steps[transform.steps.length - 1];
14
+ // Creates a new step based on the "current" steps (partially through the rebase)
15
+ return createMoveMapStep(mapped, previousStep, transform);
16
+ }
17
+ return undefined;
18
+ };
19
+
20
+ // Only consider ReplaceStep (ReplaceAroundStep do not occur for moves)
21
+ var isReplaceTypeStep = function isReplaceTypeStep(step) {
22
+ return step instanceof ReplaceStep;
23
+ };
24
+
25
+ /**
26
+ * Determines if a step pairing is a move sequence (ie. drag + drop or cut + paste).
27
+ *
28
+ * We determine this if we have a deletion followed by insertion and their content matches
29
+ *
30
+ * @param previousStep
31
+ * @param currentStep
32
+ * @param previousRebaseable
33
+ */
34
+ var isMoveSequence = function isMoveSequence(previousStep, currentStep, previousRebaseable) {
35
+ if (
36
+ // The both steps are replace
37
+ isReplaceTypeStep(previousStep) && isReplaceTypeStep(currentStep) &&
38
+ // The current step is a deletion
39
+ previousStep.slice.size === 0 &&
40
+ // The following step is an insertion with the same length that was deleted by the current step
41
+ Math.abs(previousStep.to - previousStep.from) === currentStep.slice.size) {
42
+ // Ensure we're getting the doc before our step changes so we can compare node contents
43
+ var originStepIndex = previousRebaseable.origin.steps.findIndex(function (s) {
44
+ return s === previousStep;
45
+ });
46
+ var originalDoc = previousRebaseable.origin.docs[originStepIndex];
47
+ var currentSlice = originalDoc.slice(previousStep.from, previousStep.to);
48
+ // The content from the deleted + inserted slice is exactly the same (cut + paste or drag + drop)
49
+ if (currentSlice.eq(currentStep.slice)) {
50
+ return true;
51
+ }
52
+ }
53
+ return false;
54
+ };
55
+
56
+ /**
57
+ * Update the replace step slice of the insert part of a move
58
+ * to contain the slice of the current document rather than what was sliced originally.
59
+ *
60
+ * @param mapped
61
+ * @param previousStep
62
+ * @param transform
63
+ * @returns Step to apply missing changes
64
+ */
65
+ var createMoveMapStep = function createMoveMapStep(mapped, previousStep, transform) {
66
+ if (!isReplaceTypeStep(previousStep) || mapped && !isReplaceTypeStep(mapped) || !mapped) {
67
+ return undefined;
68
+ }
69
+ var newSlice = transform.docs[transform.docs.length - 1].slice(previousStep === null || previousStep === void 0 ? void 0 : previousStep.from, previousStep === null || previousStep === void 0 ? void 0 : previousStep.to);
70
+ var diff = getDiffRange(mapped.slice.content, newSlice.content);
71
+ if (diff === undefined) {
72
+ return undefined;
73
+ }
74
+ var start = mapped.from + diff.start;
75
+ var offset = newSlice.content.size - mapped.slice.content.size === 0 ? diff.end - diff.start : 0;
76
+
77
+ // If the new slice is smaller then we're doing a deletion of content - this needs
78
+ // to be a replace step with empty content to delete content
79
+ if (newSlice.content.size - mapped.slice.content.size < 0) {
80
+ return new ReplaceStep(start, start + mapped.slice.content.size - newSlice.content.size, Slice.empty);
81
+ }
82
+
83
+ // Replace the diff range with the latest content in the document (at the old position)
84
+ return new ReplaceStep(start, start + offset, transform.docs[transform.docs.length - 1].slice((previousStep === null || previousStep === void 0 ? void 0 : previousStep.from) + diff.start, (previousStep === null || previousStep === void 0 ? void 0 : previousStep.from) + diff.end));
85
+ };
86
+
87
+ /**
88
+ * Get start and end diff position values for two fragments (old, new).
89
+ * @param {Fragment} before - content that is planned to move
90
+ * @param {Fragment} after - content that was in paragraph being deleted (updated content)
91
+ * @returns {object} - { start, end }
92
+ */
93
+ function getDiffRange(before, after) {
94
+ // https://prosemirror.net/docs/ref/#model.Fragment.findDiffStart
95
+ var start = before.findDiffStart(after);
96
+ // Important: diffEnd value is {a,b} object since end pos will differ.
97
+ // https://prosemirror.net/docs/ref/#model.Fragment.findDiffEnd
98
+ var diffEnd = before.findDiffEnd(after);
99
+ if (start === null || diffEnd === null) {
100
+ return undefined;
101
+ }
102
+ // WARNING: diffEnd may be lower than diffStart.
103
+ // If so, add overlap to get correct range.
104
+ // https://discuss.prosemirror.net/t/overlap-handling-of-finddiffstart-and-finddiffend/2856
105
+ var overlap = start - Math.min(diffEnd.a, diffEnd.b);
106
+ var end = diffEnd.b;
107
+ if (overlap > 0) {
108
+ end += overlap;
109
+ }
110
+ return {
111
+ start: start,
112
+ end: end
113
+ };
114
+ }
@@ -1,7 +1,7 @@
1
1
  import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
2
  import { Plugin } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { Step as ProseMirrorStep, Transform as ProseMirrorTransform } from '@atlaskit/editor-prosemirror/transform';
4
- declare class Rebaseable {
4
+ export declare class Rebaseable {
5
5
  readonly step: ProseMirrorStep;
6
6
  readonly inverted: ProseMirrorStep;
7
7
  readonly origin: ProseMirrorTransform;
@@ -0,0 +1,4 @@
1
+ import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
2
+ import type { Step as ProseMirrorStep, Transform as ProseMirrorTransform } from '@atlaskit/editor-prosemirror/transform';
3
+ import type { Rebaseable } from './index';
4
+ export declare const mapStep: (steps: readonly Rebaseable[], transform: ProseMirrorTransform, index: number, mapped: ProseMirrorStep | null) => ReplaceStep | undefined;
@@ -1,7 +1,7 @@
1
1
  import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
2
  import { Plugin } from '@atlaskit/editor-prosemirror/state';
3
3
  import type { Step as ProseMirrorStep, Transform as ProseMirrorTransform } from '@atlaskit/editor-prosemirror/transform';
4
- declare class Rebaseable {
4
+ export declare class Rebaseable {
5
5
  readonly step: ProseMirrorStep;
6
6
  readonly inverted: ProseMirrorStep;
7
7
  readonly origin: ProseMirrorTransform;
@@ -0,0 +1,4 @@
1
+ import { ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
2
+ import type { Step as ProseMirrorStep, Transform as ProseMirrorTransform } from '@atlaskit/editor-prosemirror/transform';
3
+ import type { Rebaseable } from './index';
4
+ export declare const mapStep: (steps: readonly Rebaseable[], transform: ProseMirrorTransform, index: number, mapped: ProseMirrorStep | null) => ReplaceStep | undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/prosemirror-collab",
3
- "version": "0.16.2",
3
+ "version": "0.16.3",
4
4
  "description": "Collaborative editing for ProseMirror - Atlassian Fork",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@atlaskit/editor-prosemirror": "7.0.0",
34
- "@atlaskit/tmp-editor-statsig": "^4.8.0",
34
+ "@atlaskit/tmp-editor-statsig": "^4.21.0",
35
35
  "@babel/runtime": "^7.0.0",
36
36
  "uuid": "^3.1.0"
37
37
  },