@atlaskit/editor-plugin-show-diff 6.1.9 → 6.2.0
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 +17 -0
- package/dist/cjs/pm-plugins/{calculateDiffDecorations.js → calculateDiff/calculateDiffDecorations.js} +74 -84
- package/dist/cjs/pm-plugins/calculateDiff/groupChangesByBlock.js +77 -0
- package/dist/cjs/pm-plugins/calculateDiff/optimizeChanges.js +43 -0
- package/dist/cjs/pm-plugins/main.js +8 -5
- package/dist/es2019/pm-plugins/{calculateDiffDecorations.js → calculateDiff/calculateDiffDecorations.js} +37 -51
- package/dist/es2019/pm-plugins/calculateDiff/groupChangesByBlock.js +54 -0
- package/dist/es2019/pm-plugins/calculateDiff/optimizeChanges.js +36 -0
- package/dist/es2019/pm-plugins/main.js +9 -6
- package/dist/esm/pm-plugins/{calculateDiffDecorations.js → calculateDiff/calculateDiffDecorations.js} +72 -82
- package/dist/esm/pm-plugins/calculateDiff/groupChangesByBlock.js +70 -0
- package/dist/esm/pm-plugins/calculateDiff/optimizeChanges.js +36 -0
- package/dist/esm/pm-plugins/main.js +8 -5
- package/dist/types/pm-plugins/{calculateDiffDecorations.d.ts → calculateDiff/calculateDiffDecorations.d.ts} +4 -4
- package/dist/types/pm-plugins/calculateDiff/groupChangesByBlock.d.ts +7 -0
- package/dist/types/pm-plugins/calculateDiff/optimizeChanges.d.ts +6 -0
- package/dist/types/pm-plugins/main.d.ts +2 -1
- package/dist/types/showDiffPluginType.d.ts +2 -0
- package/dist/types-ts4.5/pm-plugins/{calculateDiffDecorations.d.ts → calculateDiff/calculateDiffDecorations.d.ts} +4 -4
- package/dist/types-ts4.5/pm-plugins/calculateDiff/groupChangesByBlock.d.ts +7 -0
- package/dist/types-ts4.5/pm-plugins/calculateDiff/optimizeChanges.d.ts +6 -0
- package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -1
- package/dist/types-ts4.5/showDiffPluginType.d.ts +2 -0
- package/package.json +4 -4
- /package/dist/cjs/pm-plugins/{simplifyChanges.js → calculateDiff/simplifySteps.js} +0 -0
- /package/dist/es2019/pm-plugins/{simplifyChanges.js → calculateDiff/simplifySteps.js} +0 -0
- /package/dist/esm/pm-plugins/{simplifyChanges.js → calculateDiff/simplifySteps.js} +0 -0
- /package/dist/types/pm-plugins/{simplifyChanges.d.ts → calculateDiff/simplifySteps.d.ts} +0 -0
- /package/dist/types-ts4.5/pm-plugins/{simplifyChanges.d.ts → calculateDiff/simplifySteps.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 6.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`255e764f80182`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/255e764f80182) -
|
|
8
|
+
EDITOR-5830: Add support for showing inline vs. block diff types.
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- Updated dependencies
|
|
13
|
+
|
|
14
|
+
## 6.1.10
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
|
|
3
20
|
## 6.1.9
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -15,26 +15,40 @@ var _document = require("@atlaskit/editor-common/utils/document");
|
|
|
15
15
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
16
16
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
17
17
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
18
|
-
var _areDocsEqualByBlockStructureAndText = require("
|
|
19
|
-
var _createBlockChangedDecoration = require("
|
|
20
|
-
var _createInlineChangedDecoration = require("
|
|
21
|
-
var _createNodeChangedDecorationWidget = require("
|
|
22
|
-
var _getAttrChangeRanges = require("
|
|
23
|
-
var _getMarkChangeRanges = require("
|
|
24
|
-
var
|
|
18
|
+
var _areDocsEqualByBlockStructureAndText = require("../areDocsEqualByBlockStructureAndText");
|
|
19
|
+
var _createBlockChangedDecoration = require("../decorations/createBlockChangedDecoration");
|
|
20
|
+
var _createInlineChangedDecoration = require("../decorations/createInlineChangedDecoration");
|
|
21
|
+
var _createNodeChangedDecorationWidget = require("../decorations/createNodeChangedDecorationWidget");
|
|
22
|
+
var _getAttrChangeRanges = require("../decorations/utils/getAttrChangeRanges");
|
|
23
|
+
var _getMarkChangeRanges = require("../decorations/utils/getMarkChangeRanges");
|
|
24
|
+
var _groupChangesByBlock = require("./groupChangesByBlock");
|
|
25
|
+
var _optimizeChanges = require("./optimizeChanges");
|
|
26
|
+
var _simplifySteps = require("./simplifySteps");
|
|
27
|
+
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; }
|
|
28
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
25
29
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
26
30
|
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; } }
|
|
27
|
-
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; }
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
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; } // eslint-disable-next-line @atlassian/tangerine/import/entry-points
|
|
32
|
+
var getChanges = function getChanges(_ref) {
|
|
33
|
+
var changeset = _ref.changeset,
|
|
34
|
+
originalDoc = _ref.originalDoc,
|
|
35
|
+
steppedDoc = _ref.steppedDoc,
|
|
36
|
+
diffType = _ref.diffType,
|
|
37
|
+
tr = _ref.tr;
|
|
38
|
+
if (diffType === 'block' && (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
39
|
+
return (0, _groupChangesByBlock.groupChangesByBlock)(changeset.changes, originalDoc, steppedDoc);
|
|
40
|
+
}
|
|
41
|
+
var changes = (0, _prosemirrorChangeset.simplifyChanges)(changeset.changes, tr.doc);
|
|
42
|
+
return (0, _optimizeChanges.optimizeChanges)(changes);
|
|
43
|
+
};
|
|
44
|
+
var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration(_ref2) {
|
|
45
|
+
var doc = _ref2.doc,
|
|
46
|
+
from = _ref2.from,
|
|
47
|
+
to = _ref2.to,
|
|
48
|
+
colorScheme = _ref2.colorScheme,
|
|
49
|
+
_ref2$isInserted = _ref2.isInserted,
|
|
50
|
+
isInserted = _ref2$isInserted === void 0 ? true : _ref2$isInserted,
|
|
51
|
+
activeIndexPos = _ref2.activeIndexPos;
|
|
38
52
|
var decorations = [];
|
|
39
53
|
// Iterate over the document nodes within the range
|
|
40
54
|
doc.nodesBetween(from, to, function (node, pos) {
|
|
@@ -58,49 +72,18 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
|
|
|
58
72
|
});
|
|
59
73
|
return decorations;
|
|
60
74
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
var next = changes[i];
|
|
74
|
-
|
|
75
|
-
// Check if changes are adjacent or very close (within 2 positions)
|
|
76
|
-
var isAdjacent = next.fromB <= current.toB + 2;
|
|
77
|
-
if (isAdjacent) {
|
|
78
|
-
current = {
|
|
79
|
-
fromA: current.fromA,
|
|
80
|
-
toA: Math.max(current.toA, next.toA),
|
|
81
|
-
fromB: current.fromB,
|
|
82
|
-
toB: Math.max(current.toB, next.toB),
|
|
83
|
-
deleted: [].concat((0, _toConsumableArray2.default)(current.deleted), (0, _toConsumableArray2.default)(next.deleted)),
|
|
84
|
-
inserted: [].concat((0, _toConsumableArray2.default)(current.inserted), (0, _toConsumableArray2.default)(next.inserted))
|
|
85
|
-
};
|
|
86
|
-
} else {
|
|
87
|
-
optimized.push(current);
|
|
88
|
-
current = _objectSpread({}, next);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
optimized.push(current);
|
|
92
|
-
return optimized;
|
|
93
|
-
}
|
|
94
|
-
var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2) {
|
|
95
|
-
var state = _ref2.state,
|
|
96
|
-
pluginState = _ref2.pluginState,
|
|
97
|
-
nodeViewSerializer = _ref2.nodeViewSerializer,
|
|
98
|
-
colorScheme = _ref2.colorScheme,
|
|
99
|
-
intl = _ref2.intl,
|
|
100
|
-
activeIndexPos = _ref2.activeIndexPos,
|
|
101
|
-
api = _ref2.api,
|
|
102
|
-
_ref2$isInverted = _ref2.isInverted,
|
|
103
|
-
isInverted = _ref2$isInverted === void 0 ? false : _ref2$isInverted;
|
|
75
|
+
var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3) {
|
|
76
|
+
var state = _ref3.state,
|
|
77
|
+
pluginState = _ref3.pluginState,
|
|
78
|
+
nodeViewSerializer = _ref3.nodeViewSerializer,
|
|
79
|
+
colorScheme = _ref3.colorScheme,
|
|
80
|
+
intl = _ref3.intl,
|
|
81
|
+
activeIndexPos = _ref3.activeIndexPos,
|
|
82
|
+
api = _ref3.api,
|
|
83
|
+
_ref3$isInverted = _ref3.isInverted,
|
|
84
|
+
isInverted = _ref3$isInverted === void 0 ? false : _ref3$isInverted,
|
|
85
|
+
_ref3$diffType = _ref3.diffType,
|
|
86
|
+
diffType = _ref3$diffType === void 0 ? 'inline' : _ref3$diffType;
|
|
104
87
|
var originalDoc = pluginState.originalDoc,
|
|
105
88
|
steps = pluginState.steps;
|
|
106
89
|
if (!originalDoc || !pluginState.isDisplayingChanges) {
|
|
@@ -109,7 +92,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
109
92
|
var tr = state.tr;
|
|
110
93
|
var steppedDoc = originalDoc;
|
|
111
94
|
var attrSteps = [];
|
|
112
|
-
var simplifiedSteps = (0,
|
|
95
|
+
var simplifiedSteps = (0, _simplifySteps.simplifySteps)(steps, originalDoc);
|
|
113
96
|
var stepMaps = [];
|
|
114
97
|
var _iterator = _createForOfIteratorHelper(simplifiedSteps),
|
|
115
98
|
_step;
|
|
@@ -157,10 +140,15 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
157
140
|
}
|
|
158
141
|
}
|
|
159
142
|
var changeset = _prosemirrorChangeset.ChangeSet.create(originalDoc).addSteps(steppedDoc, stepMaps, tr.doc);
|
|
160
|
-
var changes = (
|
|
161
|
-
|
|
143
|
+
var changes = getChanges({
|
|
144
|
+
changeset: changeset,
|
|
145
|
+
originalDoc: originalDoc,
|
|
146
|
+
steppedDoc: steppedDoc,
|
|
147
|
+
diffType: diffType,
|
|
148
|
+
tr: tr
|
|
149
|
+
});
|
|
162
150
|
var decorations = [];
|
|
163
|
-
|
|
151
|
+
changes.forEach(function (change) {
|
|
164
152
|
var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
|
|
165
153
|
// Our default operations are insertions, so it should match the opposite of isInverted.
|
|
166
154
|
var isInserted = !isInverted;
|
|
@@ -226,28 +214,30 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
226
214
|
};
|
|
227
215
|
var calculateDiffDecorations = exports.calculateDiffDecorations = (0, _memoizeOne.default)(calculateDiffDecorationsInner,
|
|
228
216
|
// Cache results unless relevant inputs change
|
|
229
|
-
function (
|
|
230
|
-
var
|
|
231
|
-
var _ref5 = (0, _slicedToArray2.default)(_ref3, 1),
|
|
232
|
-
_ref5$ = _ref5[0],
|
|
233
|
-
pluginState = _ref5$.pluginState,
|
|
234
|
-
state = _ref5$.state,
|
|
235
|
-
colorScheme = _ref5$.colorScheme,
|
|
236
|
-
intl = _ref5$.intl,
|
|
237
|
-
activeIndexPos = _ref5$.activeIndexPos,
|
|
238
|
-
isInverted = _ref5$.isInverted;
|
|
217
|
+
function (_ref4, _ref5) {
|
|
218
|
+
var _ref9;
|
|
239
219
|
var _ref6 = (0, _slicedToArray2.default)(_ref4, 1),
|
|
240
220
|
_ref6$ = _ref6[0],
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
221
|
+
pluginState = _ref6$.pluginState,
|
|
222
|
+
state = _ref6$.state,
|
|
223
|
+
colorScheme = _ref6$.colorScheme,
|
|
224
|
+
intl = _ref6$.intl,
|
|
225
|
+
activeIndexPos = _ref6$.activeIndexPos,
|
|
226
|
+
isInverted = _ref6$.isInverted,
|
|
227
|
+
diffType = _ref6$.diffType;
|
|
228
|
+
var _ref7 = (0, _slicedToArray2.default)(_ref5, 1),
|
|
229
|
+
_ref7$ = _ref7[0],
|
|
230
|
+
lastPluginState = _ref7$.pluginState,
|
|
231
|
+
lastState = _ref7$.state,
|
|
232
|
+
lastColorScheme = _ref7$.colorScheme,
|
|
233
|
+
lastIntl = _ref7$.intl,
|
|
234
|
+
lastActiveIndexPos = _ref7$.activeIndexPos,
|
|
235
|
+
lastIsInverted = _ref7$.isInverted,
|
|
236
|
+
lastDiffType = _ref7$.diffType;
|
|
247
237
|
var originalDocIsSame = lastPluginState.originalDoc && pluginState.originalDoc && pluginState.originalDoc.eq(lastPluginState.originalDoc);
|
|
248
238
|
if ((0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
249
|
-
var
|
|
250
|
-
return (
|
|
239
|
+
var _ref8;
|
|
240
|
+
return (_ref8 = colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isInverted === lastIsInverted && diffType === lastDiffType && (0, _isEqual.default)(activeIndexPos, lastActiveIndexPos) && originalDocIsSame && (0, _isEqual.default)(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc)) !== null && _ref8 !== void 0 ? _ref8 : false;
|
|
251
241
|
}
|
|
252
|
-
return (
|
|
242
|
+
return (_ref9 = originalDocIsSame && (0, _isEqual.default)(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && colorScheme === lastColorScheme && intl.locale === lastIntl.locale && (0, _isEqual.default)(activeIndexPos, lastActiveIndexPos)) !== null && _ref9 !== void 0 ? _ref9 : false;
|
|
253
243
|
});
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.groupChangesByBlock = groupChangesByBlock;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
10
|
+
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; } }
|
|
11
|
+
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; }
|
|
12
|
+
/**
|
|
13
|
+
* Finds the position range of the top-level block (direct child of doc) that contains `pos`.
|
|
14
|
+
* Returns null if `pos` is at the doc boundary or outside the doc content.
|
|
15
|
+
*/
|
|
16
|
+
function getTopLevelBlockAt(doc, from, to) {
|
|
17
|
+
return {
|
|
18
|
+
from: doc.resolve(from).before(1),
|
|
19
|
+
to: doc.resolve(to).after(1)
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Groups all changes that fall within the same top-level block (direct child of doc)
|
|
25
|
+
* and merges them into a single change spanning the full block in both old and new doc.
|
|
26
|
+
*/
|
|
27
|
+
function groupChangesByBlock(changes, docA, docB) {
|
|
28
|
+
var groups = new Map();
|
|
29
|
+
var _iterator = _createForOfIteratorHelper(changes),
|
|
30
|
+
_step;
|
|
31
|
+
try {
|
|
32
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
33
|
+
var change = _step.value;
|
|
34
|
+
var blockA = getTopLevelBlockAt(docA, change.fromA, change.toA);
|
|
35
|
+
var blockB = getTopLevelBlockAt(docB, change.fromB, change.toB);
|
|
36
|
+
if (!groups.has(blockB.from)) {
|
|
37
|
+
groups.set(blockB.from, {
|
|
38
|
+
fromB: blockB.from,
|
|
39
|
+
toB: blockB.to,
|
|
40
|
+
fromA: blockA ? blockA.from : change.fromA,
|
|
41
|
+
toA: blockA ? blockA.to : change.toA,
|
|
42
|
+
changed: []
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
var group = groups.get(blockB.from);
|
|
46
|
+
if (group) {
|
|
47
|
+
group.changed = [].concat((0, _toConsumableArray2.default)(group.changed), (0, _toConsumableArray2.default)(change.inserted), (0, _toConsumableArray2.default)(change.deleted));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} catch (err) {
|
|
51
|
+
_iterator.e(err);
|
|
52
|
+
} finally {
|
|
53
|
+
_iterator.f();
|
|
54
|
+
}
|
|
55
|
+
return Array.from(groups.values()).sort(function (a, b) {
|
|
56
|
+
return a.fromB - b.fromB;
|
|
57
|
+
}).map(function (_ref) {
|
|
58
|
+
var fromA = _ref.fromA,
|
|
59
|
+
toA = _ref.toA,
|
|
60
|
+
fromB = _ref.fromB,
|
|
61
|
+
toB = _ref.toB,
|
|
62
|
+
changed = _ref.changed;
|
|
63
|
+
return {
|
|
64
|
+
fromA: fromA,
|
|
65
|
+
toA: toA,
|
|
66
|
+
fromB: fromB,
|
|
67
|
+
toB: toB,
|
|
68
|
+
/**
|
|
69
|
+
* We add all changes (both deleted and inserted) as that will
|
|
70
|
+
* inform the calculateDiffDecorations function that changes should be rendered
|
|
71
|
+
* (even if the change is only one of the two).
|
|
72
|
+
*/
|
|
73
|
+
deleted: changed,
|
|
74
|
+
inserted: changed
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.optimizeChanges = optimizeChanges;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
10
|
+
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; }
|
|
11
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
12
|
+
/**
|
|
13
|
+
* Groups adjacent changes to reduce visual fragmentation in diffs.
|
|
14
|
+
* Merges consecutive insertions and deletions that are close together.
|
|
15
|
+
*/
|
|
16
|
+
function optimizeChanges(changes) {
|
|
17
|
+
if (changes.length <= 1) {
|
|
18
|
+
return changes;
|
|
19
|
+
}
|
|
20
|
+
var optimized = [];
|
|
21
|
+
var current = _objectSpread({}, changes[0]);
|
|
22
|
+
for (var i = 1; i < changes.length; i++) {
|
|
23
|
+
var next = changes[i];
|
|
24
|
+
|
|
25
|
+
// Check if changes are adjacent or very close (within 2 positions)
|
|
26
|
+
var isAdjacent = next.fromB <= current.toB + 2;
|
|
27
|
+
if (isAdjacent) {
|
|
28
|
+
current = {
|
|
29
|
+
fromA: current.fromA,
|
|
30
|
+
toA: Math.max(current.toA, next.toA),
|
|
31
|
+
fromB: current.fromB,
|
|
32
|
+
toB: Math.max(current.toB, next.toB),
|
|
33
|
+
deleted: [].concat((0, _toConsumableArray2.default)(current.deleted), (0, _toConsumableArray2.default)(next.deleted)),
|
|
34
|
+
inserted: [].concat((0, _toConsumableArray2.default)(current.inserted), (0, _toConsumableArray2.default)(next.inserted))
|
|
35
|
+
};
|
|
36
|
+
} else {
|
|
37
|
+
optimized.push(current);
|
|
38
|
+
current = _objectSpread({}, next);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
optimized.push(current);
|
|
42
|
+
return optimized;
|
|
43
|
+
}
|
|
@@ -13,7 +13,7 @@ var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
|
13
13
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
14
14
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
15
15
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
16
|
-
var _calculateDiffDecorations = require("./calculateDiffDecorations");
|
|
16
|
+
var _calculateDiffDecorations = require("./calculateDiff/calculateDiffDecorations");
|
|
17
17
|
var _NodeViewSerializer = require("./NodeViewSerializer");
|
|
18
18
|
var _scrollToActiveDecoration = require("./scrollToActiveDecoration");
|
|
19
19
|
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; }
|
|
@@ -59,7 +59,8 @@ var createPlugin = exports.createPlugin = function createPlugin(config, getIntl,
|
|
|
59
59
|
decorations: _view.DecorationSet.empty,
|
|
60
60
|
isDisplayingChanges: false
|
|
61
61
|
}, (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? {
|
|
62
|
-
isInverted: false
|
|
62
|
+
isInverted: false,
|
|
63
|
+
diffType: 'inline'
|
|
63
64
|
} : {});
|
|
64
65
|
},
|
|
65
66
|
apply: function apply(tr, currentPluginState, oldState, newState) {
|
|
@@ -67,7 +68,7 @@ var createPlugin = exports.createPlugin = function createPlugin(config, getIntl,
|
|
|
67
68
|
var newPluginState = currentPluginState;
|
|
68
69
|
if (meta) {
|
|
69
70
|
if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SHOW_DIFF') {
|
|
70
|
-
var _newPluginState;
|
|
71
|
+
var _newPluginState, _newPluginState2;
|
|
71
72
|
// Update the plugin state with the new metadata
|
|
72
73
|
newPluginState = _objectSpread(_objectSpread(_objectSpread({}, currentPluginState), meta), {}, {
|
|
73
74
|
isDisplayingChanges: true,
|
|
@@ -83,7 +84,8 @@ var createPlugin = exports.createPlugin = function createPlugin(config, getIntl,
|
|
|
83
84
|
activeIndexPos: (0, _platformFeatureFlags.fg)('platform_editor_show_diff_scroll_navigation') ? newPluginState.activeIndexPos : undefined,
|
|
84
85
|
api: api
|
|
85
86
|
}, (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? {
|
|
86
|
-
isInverted: (_newPluginState = newPluginState) === null || _newPluginState === void 0 ? void 0 : _newPluginState.isInverted
|
|
87
|
+
isInverted: (_newPluginState = newPluginState) === null || _newPluginState === void 0 ? void 0 : _newPluginState.isInverted,
|
|
88
|
+
diffType: (_newPluginState2 = newPluginState) === null || _newPluginState2 === void 0 ? void 0 : _newPluginState2.diffType
|
|
87
89
|
} : {}));
|
|
88
90
|
// Update the decorations
|
|
89
91
|
newPluginState.decorations = decorations;
|
|
@@ -93,7 +95,8 @@ var createPlugin = exports.createPlugin = function createPlugin(config, getIntl,
|
|
|
93
95
|
isDisplayingChanges: false,
|
|
94
96
|
activeIndex: undefined
|
|
95
97
|
}, (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? {
|
|
96
|
-
isInverted: false
|
|
98
|
+
isInverted: false,
|
|
99
|
+
diffType: 'inline'
|
|
97
100
|
} : {});
|
|
98
101
|
} else if (((meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_NEXT' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_PREVIOUS') && (0, _platformFeatureFlags.fg)('platform_editor_show_diff_scroll_navigation')) {
|
|
99
102
|
// Update the active index in plugin state and recalculate decorations
|
|
@@ -6,13 +6,28 @@ import { areNodesEqualIgnoreAttrs } from '@atlaskit/editor-common/utils/document
|
|
|
6
6
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
7
7
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
8
8
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
9
|
-
import { areDocsEqualByBlockStructureAndText } from '
|
|
10
|
-
import { createBlockChangedDecoration } from '
|
|
11
|
-
import { createInlineChangedDecoration } from '
|
|
12
|
-
import { createNodeChangedDecorationWidget } from '
|
|
13
|
-
import { getAttrChangeRanges, stepIsValidAttrChange } from '
|
|
14
|
-
import { getMarkChangeRanges } from '
|
|
15
|
-
import {
|
|
9
|
+
import { areDocsEqualByBlockStructureAndText } from '../areDocsEqualByBlockStructureAndText';
|
|
10
|
+
import { createBlockChangedDecoration } from '../decorations/createBlockChangedDecoration';
|
|
11
|
+
import { createInlineChangedDecoration } from '../decorations/createInlineChangedDecoration';
|
|
12
|
+
import { createNodeChangedDecorationWidget } from '../decorations/createNodeChangedDecorationWidget';
|
|
13
|
+
import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
|
|
14
|
+
import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
|
|
15
|
+
import { groupChangesByBlock } from './groupChangesByBlock';
|
|
16
|
+
import { optimizeChanges } from './optimizeChanges';
|
|
17
|
+
import { simplifySteps } from './simplifySteps';
|
|
18
|
+
const getChanges = ({
|
|
19
|
+
changeset,
|
|
20
|
+
originalDoc,
|
|
21
|
+
steppedDoc,
|
|
22
|
+
diffType,
|
|
23
|
+
tr
|
|
24
|
+
}) => {
|
|
25
|
+
if (diffType === 'block' && expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
26
|
+
return groupChangesByBlock(changeset.changes, originalDoc, steppedDoc);
|
|
27
|
+
}
|
|
28
|
+
const changes = simplifyChanges(changeset.changes, tr.doc);
|
|
29
|
+
return optimizeChanges(changes);
|
|
30
|
+
};
|
|
16
31
|
const calculateNodesForBlockDecoration = ({
|
|
17
32
|
doc,
|
|
18
33
|
from,
|
|
@@ -44,43 +59,6 @@ const calculateNodesForBlockDecoration = ({
|
|
|
44
59
|
});
|
|
45
60
|
return decorations;
|
|
46
61
|
};
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Groups adjacent changes to reduce visual fragmentation in diffs.
|
|
50
|
-
* Merges consecutive insertions and deletions that are close together.
|
|
51
|
-
*/
|
|
52
|
-
function optimizeChanges(changes) {
|
|
53
|
-
if (changes.length <= 1) {
|
|
54
|
-
return changes;
|
|
55
|
-
}
|
|
56
|
-
const optimized = [];
|
|
57
|
-
let current = {
|
|
58
|
-
...changes[0]
|
|
59
|
-
};
|
|
60
|
-
for (let i = 1; i < changes.length; i++) {
|
|
61
|
-
const next = changes[i];
|
|
62
|
-
|
|
63
|
-
// Check if changes are adjacent or very close (within 2 positions)
|
|
64
|
-
const isAdjacent = next.fromB <= current.toB + 2;
|
|
65
|
-
if (isAdjacent) {
|
|
66
|
-
current = {
|
|
67
|
-
fromA: current.fromA,
|
|
68
|
-
toA: Math.max(current.toA, next.toA),
|
|
69
|
-
fromB: current.fromB,
|
|
70
|
-
toB: Math.max(current.toB, next.toB),
|
|
71
|
-
deleted: [...current.deleted, ...next.deleted],
|
|
72
|
-
inserted: [...current.inserted, ...next.inserted]
|
|
73
|
-
};
|
|
74
|
-
} else {
|
|
75
|
-
optimized.push(current);
|
|
76
|
-
current = {
|
|
77
|
-
...next
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
optimized.push(current);
|
|
82
|
-
return optimized;
|
|
83
|
-
}
|
|
84
62
|
const calculateDiffDecorationsInner = ({
|
|
85
63
|
state,
|
|
86
64
|
pluginState,
|
|
@@ -89,7 +67,8 @@ const calculateDiffDecorationsInner = ({
|
|
|
89
67
|
intl,
|
|
90
68
|
activeIndexPos,
|
|
91
69
|
api,
|
|
92
|
-
isInverted = false
|
|
70
|
+
isInverted = false,
|
|
71
|
+
diffType = 'inline'
|
|
93
72
|
}) => {
|
|
94
73
|
const {
|
|
95
74
|
originalDoc,
|
|
@@ -142,10 +121,15 @@ const calculateDiffDecorationsInner = ({
|
|
|
142
121
|
}
|
|
143
122
|
}
|
|
144
123
|
const changeset = ChangeSet.create(originalDoc).addSteps(steppedDoc, stepMaps, tr.doc);
|
|
145
|
-
const changes =
|
|
146
|
-
|
|
124
|
+
const changes = getChanges({
|
|
125
|
+
changeset,
|
|
126
|
+
originalDoc,
|
|
127
|
+
steppedDoc,
|
|
128
|
+
diffType,
|
|
129
|
+
tr
|
|
130
|
+
});
|
|
147
131
|
const decorations = [];
|
|
148
|
-
|
|
132
|
+
changes.forEach(change => {
|
|
149
133
|
const isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
|
|
150
134
|
// Our default operations are insertions, so it should match the opposite of isInverted.
|
|
151
135
|
const isInserted = !isInverted;
|
|
@@ -219,20 +203,22 @@ export const calculateDiffDecorations = memoizeOne(calculateDiffDecorationsInner
|
|
|
219
203
|
colorScheme,
|
|
220
204
|
intl,
|
|
221
205
|
activeIndexPos,
|
|
222
|
-
isInverted
|
|
206
|
+
isInverted,
|
|
207
|
+
diffType
|
|
223
208
|
}], [{
|
|
224
209
|
pluginState: lastPluginState,
|
|
225
210
|
state: lastState,
|
|
226
211
|
colorScheme: lastColorScheme,
|
|
227
212
|
intl: lastIntl,
|
|
228
213
|
activeIndexPos: lastActiveIndexPos,
|
|
229
|
-
isInverted: lastIsInverted
|
|
214
|
+
isInverted: lastIsInverted,
|
|
215
|
+
diffType: lastDiffType
|
|
230
216
|
}]) => {
|
|
231
217
|
var _ref2;
|
|
232
218
|
const originalDocIsSame = lastPluginState.originalDoc && pluginState.originalDoc && pluginState.originalDoc.eq(lastPluginState.originalDoc);
|
|
233
219
|
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
234
220
|
var _ref;
|
|
235
|
-
return (_ref = colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isInverted === lastIsInverted && isEqual(activeIndexPos, lastActiveIndexPos) && originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc)) !== null && _ref !== void 0 ? _ref : false;
|
|
221
|
+
return (_ref = colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isInverted === lastIsInverted && diffType === lastDiffType && isEqual(activeIndexPos, lastActiveIndexPos) && originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc)) !== null && _ref !== void 0 ? _ref : false;
|
|
236
222
|
}
|
|
237
223
|
return (_ref2 = originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isEqual(activeIndexPos, lastActiveIndexPos)) !== null && _ref2 !== void 0 ? _ref2 : false;
|
|
238
224
|
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds the position range of the top-level block (direct child of doc) that contains `pos`.
|
|
3
|
+
* Returns null if `pos` is at the doc boundary or outside the doc content.
|
|
4
|
+
*/
|
|
5
|
+
function getTopLevelBlockAt(doc, from, to) {
|
|
6
|
+
return {
|
|
7
|
+
from: doc.resolve(from).before(1),
|
|
8
|
+
to: doc.resolve(to).after(1)
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Groups all changes that fall within the same top-level block (direct child of doc)
|
|
14
|
+
* and merges them into a single change spanning the full block in both old and new doc.
|
|
15
|
+
*/
|
|
16
|
+
export function groupChangesByBlock(changes, docA, docB) {
|
|
17
|
+
const groups = new Map();
|
|
18
|
+
for (const change of changes) {
|
|
19
|
+
const blockA = getTopLevelBlockAt(docA, change.fromA, change.toA);
|
|
20
|
+
const blockB = getTopLevelBlockAt(docB, change.fromB, change.toB);
|
|
21
|
+
if (!groups.has(blockB.from)) {
|
|
22
|
+
groups.set(blockB.from, {
|
|
23
|
+
fromB: blockB.from,
|
|
24
|
+
toB: blockB.to,
|
|
25
|
+
fromA: blockA ? blockA.from : change.fromA,
|
|
26
|
+
toA: blockA ? blockA.to : change.toA,
|
|
27
|
+
changed: []
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
const group = groups.get(blockB.from);
|
|
31
|
+
if (group) {
|
|
32
|
+
group.changed = [...group.changed, ...change.inserted, ...change.deleted];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return Array.from(groups.values()).sort((a, b) => a.fromB - b.fromB).map(({
|
|
36
|
+
fromA,
|
|
37
|
+
toA,
|
|
38
|
+
fromB,
|
|
39
|
+
toB,
|
|
40
|
+
changed
|
|
41
|
+
}) => ({
|
|
42
|
+
fromA,
|
|
43
|
+
toA,
|
|
44
|
+
fromB,
|
|
45
|
+
toB,
|
|
46
|
+
/**
|
|
47
|
+
* We add all changes (both deleted and inserted) as that will
|
|
48
|
+
* inform the calculateDiffDecorations function that changes should be rendered
|
|
49
|
+
* (even if the change is only one of the two).
|
|
50
|
+
*/
|
|
51
|
+
deleted: changed,
|
|
52
|
+
inserted: changed
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Groups adjacent changes to reduce visual fragmentation in diffs.
|
|
3
|
+
* Merges consecutive insertions and deletions that are close together.
|
|
4
|
+
*/
|
|
5
|
+
export function optimizeChanges(changes) {
|
|
6
|
+
if (changes.length <= 1) {
|
|
7
|
+
return changes;
|
|
8
|
+
}
|
|
9
|
+
const optimized = [];
|
|
10
|
+
let current = {
|
|
11
|
+
...changes[0]
|
|
12
|
+
};
|
|
13
|
+
for (let i = 1; i < changes.length; i++) {
|
|
14
|
+
const next = changes[i];
|
|
15
|
+
|
|
16
|
+
// Check if changes are adjacent or very close (within 2 positions)
|
|
17
|
+
const isAdjacent = next.fromB <= current.toB + 2;
|
|
18
|
+
if (isAdjacent) {
|
|
19
|
+
current = {
|
|
20
|
+
fromA: current.fromA,
|
|
21
|
+
toA: Math.max(current.toA, next.toA),
|
|
22
|
+
fromB: current.fromB,
|
|
23
|
+
toB: Math.max(current.toB, next.toB),
|
|
24
|
+
deleted: [...current.deleted, ...next.deleted],
|
|
25
|
+
inserted: [...current.inserted, ...next.inserted]
|
|
26
|
+
};
|
|
27
|
+
} else {
|
|
28
|
+
optimized.push(current);
|
|
29
|
+
current = {
|
|
30
|
+
...next
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
optimized.push(current);
|
|
35
|
+
return optimized;
|
|
36
|
+
}
|
|
@@ -5,7 +5,7 @@ import { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform'
|
|
|
5
5
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
6
6
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
7
7
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
8
|
-
import { calculateDiffDecorations } from './calculateDiffDecorations';
|
|
8
|
+
import { calculateDiffDecorations } from './calculateDiff/calculateDiffDecorations';
|
|
9
9
|
import { NodeViewSerializer } from './NodeViewSerializer';
|
|
10
10
|
import { scrollToActiveDecoration } from './scrollToActiveDecoration';
|
|
11
11
|
export const showDiffPluginKey = new PluginKey('showDiffPlugin');
|
|
@@ -47,7 +47,8 @@ export const createPlugin = (config, getIntl, api) => {
|
|
|
47
47
|
decorations: DecorationSet.empty,
|
|
48
48
|
isDisplayingChanges: false,
|
|
49
49
|
...(expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? {
|
|
50
|
-
isInverted: false
|
|
50
|
+
isInverted: false,
|
|
51
|
+
diffType: 'inline'
|
|
51
52
|
} : {})
|
|
52
53
|
};
|
|
53
54
|
},
|
|
@@ -56,7 +57,7 @@ export const createPlugin = (config, getIntl, api) => {
|
|
|
56
57
|
let newPluginState = currentPluginState;
|
|
57
58
|
if (meta) {
|
|
58
59
|
if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SHOW_DIFF') {
|
|
59
|
-
var _newPluginState;
|
|
60
|
+
var _newPluginState, _newPluginState2;
|
|
60
61
|
// Update the plugin state with the new metadata
|
|
61
62
|
newPluginState = {
|
|
62
63
|
...currentPluginState,
|
|
@@ -74,7 +75,8 @@ export const createPlugin = (config, getIntl, api) => {
|
|
|
74
75
|
activeIndexPos: fg('platform_editor_show_diff_scroll_navigation') ? newPluginState.activeIndexPos : undefined,
|
|
75
76
|
api,
|
|
76
77
|
...(expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? {
|
|
77
|
-
isInverted: (_newPluginState = newPluginState) === null || _newPluginState === void 0 ? void 0 : _newPluginState.isInverted
|
|
78
|
+
isInverted: (_newPluginState = newPluginState) === null || _newPluginState === void 0 ? void 0 : _newPluginState.isInverted,
|
|
79
|
+
diffType: (_newPluginState2 = newPluginState) === null || _newPluginState2 === void 0 ? void 0 : _newPluginState2.diffType
|
|
78
80
|
} : {})
|
|
79
81
|
});
|
|
80
82
|
// Update the decorations
|
|
@@ -87,11 +89,12 @@ export const createPlugin = (config, getIntl, api) => {
|
|
|
87
89
|
isDisplayingChanges: false,
|
|
88
90
|
activeIndex: undefined,
|
|
89
91
|
/**
|
|
90
|
-
* Reset isInverted state when hiding diffs
|
|
92
|
+
* Reset isInverted & diffType state when hiding diffs
|
|
91
93
|
* Otherwise this should persist for the diff-showing session
|
|
92
94
|
*/
|
|
93
95
|
...(expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? {
|
|
94
|
-
isInverted: false
|
|
96
|
+
isInverted: false,
|
|
97
|
+
diffType: 'inline'
|
|
95
98
|
} : {})
|
|
96
99
|
};
|
|
97
100
|
} else if (((meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_NEXT' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_PREVIOUS') && fg('platform_editor_show_diff_scroll_navigation')) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
2
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
3
3
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
4
|
+
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; }
|
|
5
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
4
6
|
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
5
7
|
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; } }
|
|
6
8
|
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; }
|
|
7
|
-
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; }
|
|
8
|
-
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
9
9
|
// eslint-disable-next-line @atlassian/tangerine/import/entry-points
|
|
10
10
|
import isEqual from 'lodash/isEqual';
|
|
11
11
|
import memoizeOne from 'memoize-one';
|
|
@@ -14,21 +14,35 @@ import { areNodesEqualIgnoreAttrs } from '@atlaskit/editor-common/utils/document
|
|
|
14
14
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
15
15
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
16
16
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
17
|
-
import { areDocsEqualByBlockStructureAndText } from '
|
|
18
|
-
import { createBlockChangedDecoration } from '
|
|
19
|
-
import { createInlineChangedDecoration } from '
|
|
20
|
-
import { createNodeChangedDecorationWidget } from '
|
|
21
|
-
import { getAttrChangeRanges, stepIsValidAttrChange } from '
|
|
22
|
-
import { getMarkChangeRanges } from '
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
import { areDocsEqualByBlockStructureAndText } from '../areDocsEqualByBlockStructureAndText';
|
|
18
|
+
import { createBlockChangedDecoration } from '../decorations/createBlockChangedDecoration';
|
|
19
|
+
import { createInlineChangedDecoration } from '../decorations/createInlineChangedDecoration';
|
|
20
|
+
import { createNodeChangedDecorationWidget } from '../decorations/createNodeChangedDecorationWidget';
|
|
21
|
+
import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
|
|
22
|
+
import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
|
|
23
|
+
import { groupChangesByBlock } from './groupChangesByBlock';
|
|
24
|
+
import { optimizeChanges } from './optimizeChanges';
|
|
25
|
+
import { simplifySteps } from './simplifySteps';
|
|
26
|
+
var getChanges = function getChanges(_ref) {
|
|
27
|
+
var changeset = _ref.changeset,
|
|
28
|
+
originalDoc = _ref.originalDoc,
|
|
29
|
+
steppedDoc = _ref.steppedDoc,
|
|
30
|
+
diffType = _ref.diffType,
|
|
31
|
+
tr = _ref.tr;
|
|
32
|
+
if (diffType === 'block' && expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
33
|
+
return groupChangesByBlock(changeset.changes, originalDoc, steppedDoc);
|
|
34
|
+
}
|
|
35
|
+
var changes = simplifyChanges(changeset.changes, tr.doc);
|
|
36
|
+
return optimizeChanges(changes);
|
|
37
|
+
};
|
|
38
|
+
var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration(_ref2) {
|
|
39
|
+
var doc = _ref2.doc,
|
|
40
|
+
from = _ref2.from,
|
|
41
|
+
to = _ref2.to,
|
|
42
|
+
colorScheme = _ref2.colorScheme,
|
|
43
|
+
_ref2$isInserted = _ref2.isInserted,
|
|
44
|
+
isInserted = _ref2$isInserted === void 0 ? true : _ref2$isInserted,
|
|
45
|
+
activeIndexPos = _ref2.activeIndexPos;
|
|
32
46
|
var decorations = [];
|
|
33
47
|
// Iterate over the document nodes within the range
|
|
34
48
|
doc.nodesBetween(from, to, function (node, pos) {
|
|
@@ -52,49 +66,18 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
|
|
|
52
66
|
});
|
|
53
67
|
return decorations;
|
|
54
68
|
};
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
var next = changes[i];
|
|
68
|
-
|
|
69
|
-
// Check if changes are adjacent or very close (within 2 positions)
|
|
70
|
-
var isAdjacent = next.fromB <= current.toB + 2;
|
|
71
|
-
if (isAdjacent) {
|
|
72
|
-
current = {
|
|
73
|
-
fromA: current.fromA,
|
|
74
|
-
toA: Math.max(current.toA, next.toA),
|
|
75
|
-
fromB: current.fromB,
|
|
76
|
-
toB: Math.max(current.toB, next.toB),
|
|
77
|
-
deleted: [].concat(_toConsumableArray(current.deleted), _toConsumableArray(next.deleted)),
|
|
78
|
-
inserted: [].concat(_toConsumableArray(current.inserted), _toConsumableArray(next.inserted))
|
|
79
|
-
};
|
|
80
|
-
} else {
|
|
81
|
-
optimized.push(current);
|
|
82
|
-
current = _objectSpread({}, next);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
optimized.push(current);
|
|
86
|
-
return optimized;
|
|
87
|
-
}
|
|
88
|
-
var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2) {
|
|
89
|
-
var state = _ref2.state,
|
|
90
|
-
pluginState = _ref2.pluginState,
|
|
91
|
-
nodeViewSerializer = _ref2.nodeViewSerializer,
|
|
92
|
-
colorScheme = _ref2.colorScheme,
|
|
93
|
-
intl = _ref2.intl,
|
|
94
|
-
activeIndexPos = _ref2.activeIndexPos,
|
|
95
|
-
api = _ref2.api,
|
|
96
|
-
_ref2$isInverted = _ref2.isInverted,
|
|
97
|
-
isInverted = _ref2$isInverted === void 0 ? false : _ref2$isInverted;
|
|
69
|
+
var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3) {
|
|
70
|
+
var state = _ref3.state,
|
|
71
|
+
pluginState = _ref3.pluginState,
|
|
72
|
+
nodeViewSerializer = _ref3.nodeViewSerializer,
|
|
73
|
+
colorScheme = _ref3.colorScheme,
|
|
74
|
+
intl = _ref3.intl,
|
|
75
|
+
activeIndexPos = _ref3.activeIndexPos,
|
|
76
|
+
api = _ref3.api,
|
|
77
|
+
_ref3$isInverted = _ref3.isInverted,
|
|
78
|
+
isInverted = _ref3$isInverted === void 0 ? false : _ref3$isInverted,
|
|
79
|
+
_ref3$diffType = _ref3.diffType,
|
|
80
|
+
diffType = _ref3$diffType === void 0 ? 'inline' : _ref3$diffType;
|
|
98
81
|
var originalDoc = pluginState.originalDoc,
|
|
99
82
|
steps = pluginState.steps;
|
|
100
83
|
if (!originalDoc || !pluginState.isDisplayingChanges) {
|
|
@@ -151,10 +134,15 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
151
134
|
}
|
|
152
135
|
}
|
|
153
136
|
var changeset = ChangeSet.create(originalDoc).addSteps(steppedDoc, stepMaps, tr.doc);
|
|
154
|
-
var changes =
|
|
155
|
-
|
|
137
|
+
var changes = getChanges({
|
|
138
|
+
changeset: changeset,
|
|
139
|
+
originalDoc: originalDoc,
|
|
140
|
+
steppedDoc: steppedDoc,
|
|
141
|
+
diffType: diffType,
|
|
142
|
+
tr: tr
|
|
143
|
+
});
|
|
156
144
|
var decorations = [];
|
|
157
|
-
|
|
145
|
+
changes.forEach(function (change) {
|
|
158
146
|
var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
|
|
159
147
|
// Our default operations are insertions, so it should match the opposite of isInverted.
|
|
160
148
|
var isInserted = !isInverted;
|
|
@@ -220,28 +208,30 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
220
208
|
};
|
|
221
209
|
export var calculateDiffDecorations = memoizeOne(calculateDiffDecorationsInner,
|
|
222
210
|
// Cache results unless relevant inputs change
|
|
223
|
-
function (
|
|
224
|
-
var
|
|
225
|
-
var _ref5 = _slicedToArray(_ref3, 1),
|
|
226
|
-
_ref5$ = _ref5[0],
|
|
227
|
-
pluginState = _ref5$.pluginState,
|
|
228
|
-
state = _ref5$.state,
|
|
229
|
-
colorScheme = _ref5$.colorScheme,
|
|
230
|
-
intl = _ref5$.intl,
|
|
231
|
-
activeIndexPos = _ref5$.activeIndexPos,
|
|
232
|
-
isInverted = _ref5$.isInverted;
|
|
211
|
+
function (_ref4, _ref5) {
|
|
212
|
+
var _ref9;
|
|
233
213
|
var _ref6 = _slicedToArray(_ref4, 1),
|
|
234
214
|
_ref6$ = _ref6[0],
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
215
|
+
pluginState = _ref6$.pluginState,
|
|
216
|
+
state = _ref6$.state,
|
|
217
|
+
colorScheme = _ref6$.colorScheme,
|
|
218
|
+
intl = _ref6$.intl,
|
|
219
|
+
activeIndexPos = _ref6$.activeIndexPos,
|
|
220
|
+
isInverted = _ref6$.isInverted,
|
|
221
|
+
diffType = _ref6$.diffType;
|
|
222
|
+
var _ref7 = _slicedToArray(_ref5, 1),
|
|
223
|
+
_ref7$ = _ref7[0],
|
|
224
|
+
lastPluginState = _ref7$.pluginState,
|
|
225
|
+
lastState = _ref7$.state,
|
|
226
|
+
lastColorScheme = _ref7$.colorScheme,
|
|
227
|
+
lastIntl = _ref7$.intl,
|
|
228
|
+
lastActiveIndexPos = _ref7$.activeIndexPos,
|
|
229
|
+
lastIsInverted = _ref7$.isInverted,
|
|
230
|
+
lastDiffType = _ref7$.diffType;
|
|
241
231
|
var originalDocIsSame = lastPluginState.originalDoc && pluginState.originalDoc && pluginState.originalDoc.eq(lastPluginState.originalDoc);
|
|
242
232
|
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
243
|
-
var
|
|
244
|
-
return (
|
|
233
|
+
var _ref8;
|
|
234
|
+
return (_ref8 = colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isInverted === lastIsInverted && diffType === lastDiffType && isEqual(activeIndexPos, lastActiveIndexPos) && originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc)) !== null && _ref8 !== void 0 ? _ref8 : false;
|
|
245
235
|
}
|
|
246
|
-
return (
|
|
236
|
+
return (_ref9 = originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isEqual(activeIndexPos, lastActiveIndexPos)) !== null && _ref9 !== void 0 ? _ref9 : false;
|
|
247
237
|
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, 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 o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
3
|
+
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; } }
|
|
4
|
+
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; }
|
|
5
|
+
/**
|
|
6
|
+
* Finds the position range of the top-level block (direct child of doc) that contains `pos`.
|
|
7
|
+
* Returns null if `pos` is at the doc boundary or outside the doc content.
|
|
8
|
+
*/
|
|
9
|
+
function getTopLevelBlockAt(doc, from, to) {
|
|
10
|
+
return {
|
|
11
|
+
from: doc.resolve(from).before(1),
|
|
12
|
+
to: doc.resolve(to).after(1)
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Groups all changes that fall within the same top-level block (direct child of doc)
|
|
18
|
+
* and merges them into a single change spanning the full block in both old and new doc.
|
|
19
|
+
*/
|
|
20
|
+
export function groupChangesByBlock(changes, docA, docB) {
|
|
21
|
+
var groups = new Map();
|
|
22
|
+
var _iterator = _createForOfIteratorHelper(changes),
|
|
23
|
+
_step;
|
|
24
|
+
try {
|
|
25
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
26
|
+
var change = _step.value;
|
|
27
|
+
var blockA = getTopLevelBlockAt(docA, change.fromA, change.toA);
|
|
28
|
+
var blockB = getTopLevelBlockAt(docB, change.fromB, change.toB);
|
|
29
|
+
if (!groups.has(blockB.from)) {
|
|
30
|
+
groups.set(blockB.from, {
|
|
31
|
+
fromB: blockB.from,
|
|
32
|
+
toB: blockB.to,
|
|
33
|
+
fromA: blockA ? blockA.from : change.fromA,
|
|
34
|
+
toA: blockA ? blockA.to : change.toA,
|
|
35
|
+
changed: []
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
var group = groups.get(blockB.from);
|
|
39
|
+
if (group) {
|
|
40
|
+
group.changed = [].concat(_toConsumableArray(group.changed), _toConsumableArray(change.inserted), _toConsumableArray(change.deleted));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
} catch (err) {
|
|
44
|
+
_iterator.e(err);
|
|
45
|
+
} finally {
|
|
46
|
+
_iterator.f();
|
|
47
|
+
}
|
|
48
|
+
return Array.from(groups.values()).sort(function (a, b) {
|
|
49
|
+
return a.fromB - b.fromB;
|
|
50
|
+
}).map(function (_ref) {
|
|
51
|
+
var fromA = _ref.fromA,
|
|
52
|
+
toA = _ref.toA,
|
|
53
|
+
fromB = _ref.fromB,
|
|
54
|
+
toB = _ref.toB,
|
|
55
|
+
changed = _ref.changed;
|
|
56
|
+
return {
|
|
57
|
+
fromA: fromA,
|
|
58
|
+
toA: toA,
|
|
59
|
+
fromB: fromB,
|
|
60
|
+
toB: toB,
|
|
61
|
+
/**
|
|
62
|
+
* We add all changes (both deleted and inserted) as that will
|
|
63
|
+
* inform the calculateDiffDecorations function that changes should be rendered
|
|
64
|
+
* (even if the change is only one of the two).
|
|
65
|
+
*/
|
|
66
|
+
deleted: changed,
|
|
67
|
+
inserted: changed
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
2
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
3
|
+
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; }
|
|
4
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
|
+
/**
|
|
6
|
+
* Groups adjacent changes to reduce visual fragmentation in diffs.
|
|
7
|
+
* Merges consecutive insertions and deletions that are close together.
|
|
8
|
+
*/
|
|
9
|
+
export function optimizeChanges(changes) {
|
|
10
|
+
if (changes.length <= 1) {
|
|
11
|
+
return changes;
|
|
12
|
+
}
|
|
13
|
+
var optimized = [];
|
|
14
|
+
var current = _objectSpread({}, changes[0]);
|
|
15
|
+
for (var i = 1; i < changes.length; i++) {
|
|
16
|
+
var next = changes[i];
|
|
17
|
+
|
|
18
|
+
// Check if changes are adjacent or very close (within 2 positions)
|
|
19
|
+
var isAdjacent = next.fromB <= current.toB + 2;
|
|
20
|
+
if (isAdjacent) {
|
|
21
|
+
current = {
|
|
22
|
+
fromA: current.fromA,
|
|
23
|
+
toA: Math.max(current.toA, next.toA),
|
|
24
|
+
fromB: current.fromB,
|
|
25
|
+
toB: Math.max(current.toB, next.toB),
|
|
26
|
+
deleted: [].concat(_toConsumableArray(current.deleted), _toConsumableArray(next.deleted)),
|
|
27
|
+
inserted: [].concat(_toConsumableArray(current.inserted), _toConsumableArray(next.inserted))
|
|
28
|
+
};
|
|
29
|
+
} else {
|
|
30
|
+
optimized.push(current);
|
|
31
|
+
current = _objectSpread({}, next);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
optimized.push(current);
|
|
35
|
+
return optimized;
|
|
36
|
+
}
|
|
@@ -8,7 +8,7 @@ import { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform'
|
|
|
8
8
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
9
9
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
10
10
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
11
|
-
import { calculateDiffDecorations } from './calculateDiffDecorations';
|
|
11
|
+
import { calculateDiffDecorations } from './calculateDiff/calculateDiffDecorations';
|
|
12
12
|
import { NodeViewSerializer } from './NodeViewSerializer';
|
|
13
13
|
import { scrollToActiveDecoration } from './scrollToActiveDecoration';
|
|
14
14
|
export var showDiffPluginKey = new PluginKey('showDiffPlugin');
|
|
@@ -52,7 +52,8 @@ export var createPlugin = function createPlugin(config, getIntl, api) {
|
|
|
52
52
|
decorations: DecorationSet.empty,
|
|
53
53
|
isDisplayingChanges: false
|
|
54
54
|
}, expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? {
|
|
55
|
-
isInverted: false
|
|
55
|
+
isInverted: false,
|
|
56
|
+
diffType: 'inline'
|
|
56
57
|
} : {});
|
|
57
58
|
},
|
|
58
59
|
apply: function apply(tr, currentPluginState, oldState, newState) {
|
|
@@ -60,7 +61,7 @@ export var createPlugin = function createPlugin(config, getIntl, api) {
|
|
|
60
61
|
var newPluginState = currentPluginState;
|
|
61
62
|
if (meta) {
|
|
62
63
|
if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SHOW_DIFF') {
|
|
63
|
-
var _newPluginState;
|
|
64
|
+
var _newPluginState, _newPluginState2;
|
|
64
65
|
// Update the plugin state with the new metadata
|
|
65
66
|
newPluginState = _objectSpread(_objectSpread(_objectSpread({}, currentPluginState), meta), {}, {
|
|
66
67
|
isDisplayingChanges: true,
|
|
@@ -76,7 +77,8 @@ export var createPlugin = function createPlugin(config, getIntl, api) {
|
|
|
76
77
|
activeIndexPos: fg('platform_editor_show_diff_scroll_navigation') ? newPluginState.activeIndexPos : undefined,
|
|
77
78
|
api: api
|
|
78
79
|
}, expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? {
|
|
79
|
-
isInverted: (_newPluginState = newPluginState) === null || _newPluginState === void 0 ? void 0 : _newPluginState.isInverted
|
|
80
|
+
isInverted: (_newPluginState = newPluginState) === null || _newPluginState === void 0 ? void 0 : _newPluginState.isInverted,
|
|
81
|
+
diffType: (_newPluginState2 = newPluginState) === null || _newPluginState2 === void 0 ? void 0 : _newPluginState2.diffType
|
|
80
82
|
} : {}));
|
|
81
83
|
// Update the decorations
|
|
82
84
|
newPluginState.decorations = decorations;
|
|
@@ -86,7 +88,8 @@ export var createPlugin = function createPlugin(config, getIntl, api) {
|
|
|
86
88
|
isDisplayingChanges: false,
|
|
87
89
|
activeIndex: undefined
|
|
88
90
|
}, expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? {
|
|
89
|
-
isInverted: false
|
|
91
|
+
isInverted: false,
|
|
92
|
+
diffType: 'inline'
|
|
90
93
|
} : {});
|
|
91
94
|
} else if (((meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_NEXT' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_PREVIOUS') && fg('platform_editor_show_diff_scroll_navigation')) {
|
|
92
95
|
// Update the active index in plugin state and recalculate decorations
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type MemoizedFn } from 'memoize-one';
|
|
2
2
|
import type { IntlShape } from 'react-intl-next';
|
|
3
3
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
4
|
-
import {
|
|
4
|
+
import type { EditorState } from '@atlaskit/editor-prosemirror/state';
|
|
5
5
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
6
|
-
import type { ColorScheme, ShowDiffPlugin } from '
|
|
7
|
-
import type { ShowDiffPluginState } from '
|
|
8
|
-
import type { NodeViewSerializer } from '
|
|
6
|
+
import type { ColorScheme, ShowDiffPlugin } from '../../showDiffPluginType';
|
|
7
|
+
import type { ShowDiffPluginState } from '../main';
|
|
8
|
+
import type { NodeViewSerializer } from '../NodeViewSerializer';
|
|
9
9
|
export declare const calculateDiffDecorations: MemoizedFn<({ state, pluginState, nodeViewSerializer, colorScheme, intl, activeIndexPos, api, }: {
|
|
10
10
|
activeIndexPos?: {
|
|
11
11
|
from: number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Change } from 'prosemirror-changeset';
|
|
2
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
/**
|
|
4
|
+
* Groups all changes that fall within the same top-level block (direct child of doc)
|
|
5
|
+
* and merges them into a single change spanning the full block in both old and new doc.
|
|
6
|
+
*/
|
|
7
|
+
export declare function groupChangesByBlock(changes: readonly Change[], docA: PMNode, docB: PMNode): Change[];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Change } from 'prosemirror-changeset';
|
|
2
|
+
/**
|
|
3
|
+
* Groups adjacent changes to reduce visual fragmentation in diffs.
|
|
4
|
+
* Merges consecutive insertions and deletions that are close together.
|
|
5
|
+
*/
|
|
6
|
+
export declare function optimizeChanges(changes: Change[]): Change[];
|
|
@@ -6,7 +6,7 @@ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
|
6
6
|
import { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
|
|
7
7
|
import type { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
8
8
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
9
|
-
import { type DiffParams, type ShowDiffPlugin } from '../showDiffPluginType';
|
|
9
|
+
import { type DiffParams, type DiffType, type ShowDiffPlugin } from '../showDiffPluginType';
|
|
10
10
|
export declare const showDiffPluginKey: PluginKey<ShowDiffPluginState>;
|
|
11
11
|
export type ShowDiffPluginState = {
|
|
12
12
|
activeIndex?: number;
|
|
@@ -15,6 +15,7 @@ export type ShowDiffPluginState = {
|
|
|
15
15
|
to: number;
|
|
16
16
|
};
|
|
17
17
|
decorations: DecorationSet;
|
|
18
|
+
diffType?: DiffType;
|
|
18
19
|
isDisplayingChanges: boolean;
|
|
19
20
|
isInverted?: boolean;
|
|
20
21
|
originalDoc: PMNode | undefined;
|
|
@@ -5,6 +5,7 @@ import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
|
5
5
|
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
6
6
|
import type { Step } from '@atlaskit/editor-prosemirror/transform';
|
|
7
7
|
export type ColorScheme = 'standard' | 'traditional';
|
|
8
|
+
export type DiffType = 'inline' | 'block';
|
|
8
9
|
export type DiffParams = {
|
|
9
10
|
/**
|
|
10
11
|
* Color scheme to use for displaying diffs.
|
|
@@ -19,6 +20,7 @@ export type DiffParams = {
|
|
|
19
20
|
steps: StepJson[];
|
|
20
21
|
};
|
|
21
22
|
export type PMDiffParams = {
|
|
23
|
+
diffType?: DiffType;
|
|
22
24
|
isInverted?: boolean;
|
|
23
25
|
originalDoc: Node;
|
|
24
26
|
/**
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type MemoizedFn } from 'memoize-one';
|
|
2
2
|
import type { IntlShape } from 'react-intl-next';
|
|
3
3
|
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
4
|
-
import {
|
|
4
|
+
import type { EditorState } from '@atlaskit/editor-prosemirror/state';
|
|
5
5
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
6
|
-
import type { ColorScheme, ShowDiffPlugin } from '
|
|
7
|
-
import type { ShowDiffPluginState } from '
|
|
8
|
-
import type { NodeViewSerializer } from '
|
|
6
|
+
import type { ColorScheme, ShowDiffPlugin } from '../../showDiffPluginType';
|
|
7
|
+
import type { ShowDiffPluginState } from '../main';
|
|
8
|
+
import type { NodeViewSerializer } from '../NodeViewSerializer';
|
|
9
9
|
export declare const calculateDiffDecorations: MemoizedFn<({ state, pluginState, nodeViewSerializer, colorScheme, intl, activeIndexPos, api, }: {
|
|
10
10
|
activeIndexPos?: {
|
|
11
11
|
from: number;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type Change } from 'prosemirror-changeset';
|
|
2
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
|
+
/**
|
|
4
|
+
* Groups all changes that fall within the same top-level block (direct child of doc)
|
|
5
|
+
* and merges them into a single change spanning the full block in both old and new doc.
|
|
6
|
+
*/
|
|
7
|
+
export declare function groupChangesByBlock(changes: readonly Change[], docA: PMNode, docB: PMNode): Change[];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Change } from 'prosemirror-changeset';
|
|
2
|
+
/**
|
|
3
|
+
* Groups adjacent changes to reduce visual fragmentation in diffs.
|
|
4
|
+
* Merges consecutive insertions and deletions that are close together.
|
|
5
|
+
*/
|
|
6
|
+
export declare function optimizeChanges(changes: Change[]): Change[];
|
|
@@ -6,7 +6,7 @@ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
|
|
|
6
6
|
import { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
|
|
7
7
|
import type { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
8
8
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
9
|
-
import { type DiffParams, type ShowDiffPlugin } from '../showDiffPluginType';
|
|
9
|
+
import { type DiffParams, type DiffType, type ShowDiffPlugin } from '../showDiffPluginType';
|
|
10
10
|
export declare const showDiffPluginKey: PluginKey<ShowDiffPluginState>;
|
|
11
11
|
export type ShowDiffPluginState = {
|
|
12
12
|
activeIndex?: number;
|
|
@@ -15,6 +15,7 @@ export type ShowDiffPluginState = {
|
|
|
15
15
|
to: number;
|
|
16
16
|
};
|
|
17
17
|
decorations: DecorationSet;
|
|
18
|
+
diffType?: DiffType;
|
|
18
19
|
isDisplayingChanges: boolean;
|
|
19
20
|
isInverted?: boolean;
|
|
20
21
|
originalDoc: PMNode | undefined;
|
|
@@ -5,6 +5,7 @@ import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
|
5
5
|
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
6
6
|
import type { Step } from '@atlaskit/editor-prosemirror/transform';
|
|
7
7
|
export type ColorScheme = 'standard' | 'traditional';
|
|
8
|
+
export type DiffType = 'inline' | 'block';
|
|
8
9
|
export type DiffParams = {
|
|
9
10
|
/**
|
|
10
11
|
* Color scheme to use for displaying diffs.
|
|
@@ -19,6 +20,7 @@ export type DiffParams = {
|
|
|
19
20
|
steps: StepJson[];
|
|
20
21
|
};
|
|
21
22
|
export type PMDiffParams = {
|
|
23
|
+
diffType?: DiffType;
|
|
22
24
|
isInverted?: boolean;
|
|
23
25
|
originalDoc: Node;
|
|
24
26
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"@atlaskit/editor-prosemirror": "^7.3.0",
|
|
34
34
|
"@atlaskit/editor-tables": "^2.9.0",
|
|
35
35
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
36
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
37
|
-
"@atlaskit/tokens": "^11.
|
|
36
|
+
"@atlaskit/tmp-editor-statsig": "^45.1.0",
|
|
37
|
+
"@atlaskit/tokens": "^11.2.0",
|
|
38
38
|
"@babel/runtime": "^7.0.0",
|
|
39
39
|
"lodash": "^4.17.21",
|
|
40
40
|
"memoize-one": "^6.0.0",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@atlassian/content-reconciliation": "^0.1.3506"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@atlaskit/editor-common": "^112.
|
|
48
|
+
"@atlaskit/editor-common": "^112.9.0",
|
|
49
49
|
"react": "^18.2.0"
|
|
50
50
|
},
|
|
51
51
|
"techstack": {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/dist/types-ts4.5/pm-plugins/{simplifyChanges.d.ts → calculateDiff/simplifySteps.d.ts}
RENAMED
|
File without changes
|