@atlaskit/editor-plugin-show-diff 8.4.1 → 8.4.2
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,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 8.4.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`5789b1638025b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5789b1638025b) -
|
|
8
|
+
EDITOR-6631: If only marks has changed, don't use granular diffing as that won't show any diffs.
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
3
11
|
## 8.4.1
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -8,6 +8,7 @@ exports.diffBySteps = void 0;
|
|
|
8
8
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
9
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
10
10
|
var _prosemirrorChangeset = require("prosemirror-changeset");
|
|
11
|
+
var _model = require("@atlaskit/editor-prosemirror/model");
|
|
11
12
|
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
12
13
|
var _optimizeChanges = require("./optimizeChanges");
|
|
13
14
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -18,6 +19,22 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
18
19
|
var mapPosition = function mapPosition(mapping, pos) {
|
|
19
20
|
return mapping.map(pos);
|
|
20
21
|
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Compare marks between two nodes
|
|
25
|
+
* We have to check each child because adding a mark splits text into multiple nodes
|
|
26
|
+
*/
|
|
27
|
+
var hasSameChildMarks = function hasSameChildMarks(left, right) {
|
|
28
|
+
if (left.childCount !== right.childCount) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
for (var index = 0; index < left.childCount; index++) {
|
|
32
|
+
if (!_model.Mark.sameSet(left.child(index).marks, right.child(index).marks)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return true;
|
|
37
|
+
};
|
|
21
38
|
var createMapping = function createMapping(maps) {
|
|
22
39
|
var mapping = new _transform.Mapping();
|
|
23
40
|
var _iterator = _createForOfIteratorHelper(maps),
|
|
@@ -69,8 +86,20 @@ var mergeOverlappingByNewDocRange = function mergeOverlappingByNewDocRange(chang
|
|
|
69
86
|
merged.push(current);
|
|
70
87
|
return merged;
|
|
71
88
|
};
|
|
72
|
-
|
|
73
|
-
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* This function checks whether to do granular diffing.
|
|
92
|
+
* We should do granular diffing if:
|
|
93
|
+
* - The step is a replace step
|
|
94
|
+
* - The step is not open
|
|
95
|
+
* - The replaced slice is not open
|
|
96
|
+
* - The replaced slice has only one child
|
|
97
|
+
* - The replacing slice has only one child
|
|
98
|
+
* - The replaced slice and replacing slice have the same text content
|
|
99
|
+
* - The replaced slice and replacing slice have the same child marks (if text content is equal)
|
|
100
|
+
*/
|
|
101
|
+
var shouldCheckGranularDiff = function shouldCheckGranularDiff(step, before, from, to) {
|
|
102
|
+
var _replacedNode$marks, _replacingNode$marks;
|
|
74
103
|
if (!(step instanceof _transform.ReplaceStep)) {
|
|
75
104
|
return false;
|
|
76
105
|
}
|
|
@@ -79,7 +108,19 @@ var isReplaceStepForTextBlockNode = function isReplaceStepForTextBlockNode(step,
|
|
|
79
108
|
}
|
|
80
109
|
var replacedSlice = before.slice(from, to);
|
|
81
110
|
var replacingSlice = step.slice;
|
|
82
|
-
|
|
111
|
+
if (replacedSlice.openStart !== 0 || replacedSlice.openEnd !== 0 || replacedSlice.content.childCount !== 1 || replacingSlice.content.childCount !== 1) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
var replacedNode = replacedSlice.content.firstChild;
|
|
115
|
+
var replacingNode = replacingSlice.content.firstChild;
|
|
116
|
+
if ((replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.type.name) !== (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.type.name) || !(replacedNode !== null && replacedNode !== void 0 && replacedNode.type.isTextblock)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
if (!_model.Mark.sameSet((_replacedNode$marks = replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.marks) !== null && _replacedNode$marks !== void 0 ? _replacedNode$marks : [], (_replacingNode$marks = replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.marks) !== null && _replacingNode$marks !== void 0 ? _replacingNode$marks : [])) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
var isTextContentEqual = (replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.textContent) === (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.textContent);
|
|
123
|
+
return !isTextContentEqual || isTextContentEqual && hasSameChildMarks(replacedNode, replacingNode);
|
|
83
124
|
};
|
|
84
125
|
var diffBySteps = exports.diffBySteps = function diffBySteps(originalDoc, steps) {
|
|
85
126
|
var changes = [];
|
|
@@ -131,7 +172,7 @@ var diffBySteps = exports.diffBySteps = function diffBySteps(originalDoc, steps)
|
|
|
131
172
|
var afterStepToFinal = createMapping(successfulStepMaps.slice(rangedStep.mapIndex + 1));
|
|
132
173
|
var fromB = mapPosition(afterStepToFinal, fromAfterStep);
|
|
133
174
|
var toB = mapPosition(afterStepToFinal, toAfterStep);
|
|
134
|
-
if (
|
|
175
|
+
if (shouldCheckGranularDiff(rangedStep.step, rangedStep.before, rangedStep.from, rangedStep.to)) {
|
|
135
176
|
var granularStepChanges = _prosemirrorChangeset.ChangeSet.create(rangedStep.before).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
|
|
136
177
|
|
|
137
178
|
// `simplifyChanges` reads text using `Change.fromB`/`toB`, which are
|
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
import { simplifyChanges, ChangeSet } from 'prosemirror-changeset';
|
|
2
|
+
import { Mark } from '@atlaskit/editor-prosemirror/model';
|
|
2
3
|
import { Mapping, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
3
4
|
import { optimizeChanges } from './optimizeChanges';
|
|
4
5
|
const mapPosition = (mapping, pos) => mapping.map(pos);
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Compare marks between two nodes
|
|
9
|
+
* We have to check each child because adding a mark splits text into multiple nodes
|
|
10
|
+
*/
|
|
11
|
+
const hasSameChildMarks = (left, right) => {
|
|
12
|
+
if (left.childCount !== right.childCount) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
for (let index = 0; index < left.childCount; index++) {
|
|
16
|
+
if (!Mark.sameSet(left.child(index).marks, right.child(index).marks)) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return true;
|
|
21
|
+
};
|
|
5
22
|
const createMapping = maps => {
|
|
6
23
|
const mapping = new Mapping();
|
|
7
24
|
for (const map of maps) {
|
|
@@ -44,8 +61,20 @@ const mergeOverlappingByNewDocRange = changes => {
|
|
|
44
61
|
merged.push(current);
|
|
45
62
|
return merged;
|
|
46
63
|
};
|
|
47
|
-
|
|
48
|
-
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* This function checks whether to do granular diffing.
|
|
67
|
+
* We should do granular diffing if:
|
|
68
|
+
* - The step is a replace step
|
|
69
|
+
* - The step is not open
|
|
70
|
+
* - The replaced slice is not open
|
|
71
|
+
* - The replaced slice has only one child
|
|
72
|
+
* - The replacing slice has only one child
|
|
73
|
+
* - The replaced slice and replacing slice have the same text content
|
|
74
|
+
* - The replaced slice and replacing slice have the same child marks (if text content is equal)
|
|
75
|
+
*/
|
|
76
|
+
const shouldCheckGranularDiff = (step, before, from, to) => {
|
|
77
|
+
var _replacedNode$marks, _replacingNode$marks;
|
|
49
78
|
if (!(step instanceof ReplaceStep)) {
|
|
50
79
|
return false;
|
|
51
80
|
}
|
|
@@ -54,7 +83,19 @@ const isReplaceStepForTextBlockNode = (step, before, from, to) => {
|
|
|
54
83
|
}
|
|
55
84
|
const replacedSlice = before.slice(from, to);
|
|
56
85
|
const replacingSlice = step.slice;
|
|
57
|
-
|
|
86
|
+
if (replacedSlice.openStart !== 0 || replacedSlice.openEnd !== 0 || replacedSlice.content.childCount !== 1 || replacingSlice.content.childCount !== 1) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
const replacedNode = replacedSlice.content.firstChild;
|
|
90
|
+
const replacingNode = replacingSlice.content.firstChild;
|
|
91
|
+
if ((replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.type.name) !== (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.type.name) || !(replacedNode !== null && replacedNode !== void 0 && replacedNode.type.isTextblock)) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
if (!Mark.sameSet((_replacedNode$marks = replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.marks) !== null && _replacedNode$marks !== void 0 ? _replacedNode$marks : [], (_replacingNode$marks = replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.marks) !== null && _replacingNode$marks !== void 0 ? _replacingNode$marks : [])) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
const isTextContentEqual = (replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.textContent) === (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.textContent);
|
|
98
|
+
return !isTextContentEqual || isTextContentEqual && hasSameChildMarks(replacedNode, replacingNode);
|
|
58
99
|
};
|
|
59
100
|
export const diffBySteps = (originalDoc, steps) => {
|
|
60
101
|
const changes = [];
|
|
@@ -96,7 +137,7 @@ export const diffBySteps = (originalDoc, steps) => {
|
|
|
96
137
|
const afterStepToFinal = createMapping(successfulStepMaps.slice(rangedStep.mapIndex + 1));
|
|
97
138
|
const fromB = mapPosition(afterStepToFinal, fromAfterStep);
|
|
98
139
|
const toB = mapPosition(afterStepToFinal, toAfterStep);
|
|
99
|
-
if (
|
|
140
|
+
if (shouldCheckGranularDiff(rangedStep.step, rangedStep.before, rangedStep.from, rangedStep.to)) {
|
|
100
141
|
const granularStepChanges = ChangeSet.create(rangedStep.before).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
|
|
101
142
|
|
|
102
143
|
// `simplifyChanges` reads text using `Change.fromB`/`toB`, which are
|
|
@@ -6,11 +6,28 @@ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol
|
|
|
6
6
|
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
7
7
|
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
8
8
|
import { simplifyChanges, ChangeSet } from 'prosemirror-changeset';
|
|
9
|
+
import { Mark } from '@atlaskit/editor-prosemirror/model';
|
|
9
10
|
import { Mapping, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
10
11
|
import { optimizeChanges } from './optimizeChanges';
|
|
11
12
|
var mapPosition = function mapPosition(mapping, pos) {
|
|
12
13
|
return mapping.map(pos);
|
|
13
14
|
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Compare marks between two nodes
|
|
18
|
+
* We have to check each child because adding a mark splits text into multiple nodes
|
|
19
|
+
*/
|
|
20
|
+
var hasSameChildMarks = function hasSameChildMarks(left, right) {
|
|
21
|
+
if (left.childCount !== right.childCount) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
for (var index = 0; index < left.childCount; index++) {
|
|
25
|
+
if (!Mark.sameSet(left.child(index).marks, right.child(index).marks)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
};
|
|
14
31
|
var createMapping = function createMapping(maps) {
|
|
15
32
|
var mapping = new Mapping();
|
|
16
33
|
var _iterator = _createForOfIteratorHelper(maps),
|
|
@@ -62,8 +79,20 @@ var mergeOverlappingByNewDocRange = function mergeOverlappingByNewDocRange(chang
|
|
|
62
79
|
merged.push(current);
|
|
63
80
|
return merged;
|
|
64
81
|
};
|
|
65
|
-
|
|
66
|
-
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* This function checks whether to do granular diffing.
|
|
85
|
+
* We should do granular diffing if:
|
|
86
|
+
* - The step is a replace step
|
|
87
|
+
* - The step is not open
|
|
88
|
+
* - The replaced slice is not open
|
|
89
|
+
* - The replaced slice has only one child
|
|
90
|
+
* - The replacing slice has only one child
|
|
91
|
+
* - The replaced slice and replacing slice have the same text content
|
|
92
|
+
* - The replaced slice and replacing slice have the same child marks (if text content is equal)
|
|
93
|
+
*/
|
|
94
|
+
var shouldCheckGranularDiff = function shouldCheckGranularDiff(step, before, from, to) {
|
|
95
|
+
var _replacedNode$marks, _replacingNode$marks;
|
|
67
96
|
if (!(step instanceof ReplaceStep)) {
|
|
68
97
|
return false;
|
|
69
98
|
}
|
|
@@ -72,7 +101,19 @@ var isReplaceStepForTextBlockNode = function isReplaceStepForTextBlockNode(step,
|
|
|
72
101
|
}
|
|
73
102
|
var replacedSlice = before.slice(from, to);
|
|
74
103
|
var replacingSlice = step.slice;
|
|
75
|
-
|
|
104
|
+
if (replacedSlice.openStart !== 0 || replacedSlice.openEnd !== 0 || replacedSlice.content.childCount !== 1 || replacingSlice.content.childCount !== 1) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
var replacedNode = replacedSlice.content.firstChild;
|
|
108
|
+
var replacingNode = replacingSlice.content.firstChild;
|
|
109
|
+
if ((replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.type.name) !== (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.type.name) || !(replacedNode !== null && replacedNode !== void 0 && replacedNode.type.isTextblock)) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
if (!Mark.sameSet((_replacedNode$marks = replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.marks) !== null && _replacedNode$marks !== void 0 ? _replacedNode$marks : [], (_replacingNode$marks = replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.marks) !== null && _replacingNode$marks !== void 0 ? _replacingNode$marks : [])) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
var isTextContentEqual = (replacedNode === null || replacedNode === void 0 ? void 0 : replacedNode.textContent) === (replacingNode === null || replacingNode === void 0 ? void 0 : replacingNode.textContent);
|
|
116
|
+
return !isTextContentEqual || isTextContentEqual && hasSameChildMarks(replacedNode, replacingNode);
|
|
76
117
|
};
|
|
77
118
|
export var diffBySteps = function diffBySteps(originalDoc, steps) {
|
|
78
119
|
var changes = [];
|
|
@@ -124,7 +165,7 @@ export var diffBySteps = function diffBySteps(originalDoc, steps) {
|
|
|
124
165
|
var afterStepToFinal = createMapping(successfulStepMaps.slice(rangedStep.mapIndex + 1));
|
|
125
166
|
var fromB = mapPosition(afterStepToFinal, fromAfterStep);
|
|
126
167
|
var toB = mapPosition(afterStepToFinal, toAfterStep);
|
|
127
|
-
if (
|
|
168
|
+
if (shouldCheckGranularDiff(rangedStep.step, rangedStep.before, rangedStep.from, rangedStep.to)) {
|
|
128
169
|
var granularStepChanges = ChangeSet.create(rangedStep.before).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
|
|
129
170
|
|
|
130
171
|
// `simplifyChanges` reads text using `Change.fromB`/`toB`, which are
|