@atlaskit/editor-plugin-show-diff 6.1.3 → 6.1.4
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 +8 -0
- package/dist/cjs/pm-plugins/areDocsEqualByBlockStructureAndText.js +29 -0
- package/dist/cjs/pm-plugins/calculateDiffDecorations.js +12 -2
- package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +4 -2
- package/dist/cjs/pm-plugins/main.js +17 -4
- package/dist/es2019/pm-plugins/areDocsEqualByBlockStructureAndText.js +23 -0
- package/dist/es2019/pm-plugins/calculateDiffDecorations.js +12 -2
- package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +4 -2
- package/dist/es2019/pm-plugins/main.js +16 -3
- package/dist/esm/pm-plugins/areDocsEqualByBlockStructureAndText.js +23 -0
- package/dist/esm/pm-plugins/calculateDiffDecorations.js +12 -2
- package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +4 -2
- package/dist/esm/pm-plugins/main.js +17 -4
- package/dist/types/pm-plugins/areDocsEqualByBlockStructureAndText.d.ts +7 -0
- package/dist/types-ts4.5/pm-plugins/areDocsEqualByBlockStructureAndText.d.ts +7 -0
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 6.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`9df4b10b5f0f8`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/9df4b10b5f0f8) -
|
|
8
|
+
Improve edge cases when showing diff by using a looser equality structure for steps.
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
3
11
|
## 6.1.3
|
|
4
12
|
|
|
5
13
|
### Patch Changes
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.areDocsEqualByBlockStructureAndText = areDocsEqualByBlockStructureAndText;
|
|
7
|
+
/**
|
|
8
|
+
* Returns true if both nodes have the same tree structure (type and child count at every level).
|
|
9
|
+
*/
|
|
10
|
+
function isBlockStructureEqual(node1, node2) {
|
|
11
|
+
if (node1.type !== node2.type || node1.childCount !== node2.childCount) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
for (var i = 0; i < node1.childCount; i++) {
|
|
15
|
+
if (!isBlockStructureEqual(node1.child(i), node2.child(i))) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Looser equality for "safe diff" cases: same full text content and same block structure
|
|
24
|
+
* (e.g. text moved across text-node boundaries). Used when strict areNodesEqualIgnoreAttrs fails.
|
|
25
|
+
* This is safe because we ensure decorations get applied to valid positions.
|
|
26
|
+
*/
|
|
27
|
+
function areDocsEqualByBlockStructureAndText(doc1, doc2) {
|
|
28
|
+
return doc1.textContent === doc2.textContent && doc1.nodeSize === doc2.nodeSize && isBlockStructureEqual(doc1, doc2);
|
|
29
|
+
}
|
|
@@ -13,7 +13,9 @@ var _memoizeOne = _interopRequireDefault(require("memoize-one"));
|
|
|
13
13
|
var _prosemirrorChangeset = require("prosemirror-changeset");
|
|
14
14
|
var _document = require("@atlaskit/editor-common/utils/document");
|
|
15
15
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
16
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
16
17
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
18
|
+
var _areDocsEqualByBlockStructureAndText = require("./areDocsEqualByBlockStructureAndText");
|
|
17
19
|
var _createBlockChangedDecoration = require("./decorations/createBlockChangedDecoration");
|
|
18
20
|
var _createInlineChangedDecoration = require("./decorations/createInlineChangedDecoration");
|
|
19
21
|
var _createNodeChangedDecorationWidget = require("./decorations/createNodeChangedDecorationWidget");
|
|
@@ -132,6 +134,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
132
134
|
_iterator.f();
|
|
133
135
|
}
|
|
134
136
|
if (!(0, _document.areNodesEqualIgnoreAttrs)(steppedDoc, tr.doc)) {
|
|
137
|
+
var recoveredViaContentEquality = (0, _platformFeatureFlags.fg)('platform_editor_show_diff_equality_fallback') ? (0, _areDocsEqualByBlockStructureAndText.areDocsEqualByBlockStructureAndText)(steppedDoc, tr.doc) : undefined;
|
|
135
138
|
if ((0, _expValEquals.expValEquals)('platform_editor_are_nodes_equal_ignore_mark_order', 'isEnabled', true)) {
|
|
136
139
|
var _api$analytics;
|
|
137
140
|
api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
|
|
@@ -140,11 +143,18 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
140
143
|
actionSubject: 'showDiff',
|
|
141
144
|
attributes: {
|
|
142
145
|
docSizeEqual: steppedDoc.nodeSize === tr.doc.nodeSize,
|
|
143
|
-
colorScheme: colorScheme
|
|
146
|
+
colorScheme: colorScheme,
|
|
147
|
+
recoveredViaContentEquality: recoveredViaContentEquality
|
|
144
148
|
}
|
|
145
149
|
});
|
|
146
150
|
}
|
|
147
|
-
|
|
151
|
+
if ((0, _platformFeatureFlags.fg)('platform_editor_show_diff_equality_fallback')) {
|
|
152
|
+
if (!recoveredViaContentEquality) {
|
|
153
|
+
return _view.DecorationSet.empty;
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
return _view.DecorationSet.empty;
|
|
157
|
+
}
|
|
148
158
|
}
|
|
149
159
|
var changeset = _prosemirrorChangeset.ChangeSet.create(originalDoc).addSteps(steppedDoc, stepMaps, tr.doc);
|
|
150
160
|
var changes = (0, _prosemirrorChangeset.simplifyChanges)(changeset.changes, tr.doc);
|
|
@@ -119,7 +119,8 @@ var createBlockChangedDecoration = exports.createBlockChangedDecoration = functi
|
|
|
119
119
|
'data-testid': 'show-diff-changed-decoration-node',
|
|
120
120
|
class: className
|
|
121
121
|
}, {
|
|
122
|
-
key: 'diff-block'
|
|
122
|
+
key: 'diff-block',
|
|
123
|
+
nodeName: change.name
|
|
123
124
|
});
|
|
124
125
|
} else {
|
|
125
126
|
return undefined;
|
|
@@ -130,6 +131,7 @@ var createBlockChangedDecoration = exports.createBlockChangedDecoration = functi
|
|
|
130
131
|
'data-testid': 'show-diff-changed-decoration-node',
|
|
131
132
|
class: className
|
|
132
133
|
}, {
|
|
133
|
-
key: 'diff-block'
|
|
134
|
+
key: 'diff-block',
|
|
135
|
+
nodeName: change.name
|
|
134
136
|
});
|
|
135
137
|
};
|
|
@@ -20,13 +20,26 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
|
|
|
20
20
|
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; }
|
|
21
21
|
var showDiffPluginKey = exports.showDiffPluginKey = new _state2.PluginKey('showDiffPlugin');
|
|
22
22
|
var getScrollableDecorations = exports.getScrollableDecorations = function getScrollableDecorations(set) {
|
|
23
|
-
var _set$find
|
|
24
|
-
|
|
23
|
+
var _set$find;
|
|
24
|
+
var seenBlockKeys = new Set();
|
|
25
|
+
return ((_set$find = set === null || set === void 0 ? void 0 : set.find(undefined, undefined, function (spec) {
|
|
25
26
|
var _spec$key;
|
|
26
27
|
return spec.key === 'diff-inline' || ((_spec$key = spec.key) === null || _spec$key === void 0 ? void 0 : _spec$key.startsWith('diff-widget')) || spec.key === 'diff-block';
|
|
28
|
+
})) !== null && _set$find !== void 0 ? _set$find : []).filter(function (dec) {
|
|
29
|
+
var _dec$spec;
|
|
30
|
+
if (((_dec$spec = dec.spec) === null || _dec$spec === void 0 ? void 0 : _dec$spec.key) === 'diff-block') {
|
|
31
|
+
var _dec$spec2, _dec$spec$nodeName, _dec$spec3;
|
|
32
|
+
// Skip listItem blocks as they are not scrollable
|
|
33
|
+
if (((_dec$spec2 = dec.spec) === null || _dec$spec2 === void 0 ? void 0 : _dec$spec2.nodeName) === 'listItem') return false;
|
|
34
|
+
var key = "".concat(dec.from, "-").concat(dec.to, "-").concat((_dec$spec$nodeName = (_dec$spec3 = dec.spec) === null || _dec$spec3 === void 0 ? void 0 : _dec$spec3.nodeName) !== null && _dec$spec$nodeName !== void 0 ? _dec$spec$nodeName : '');
|
|
35
|
+
// Skip blocks that have already been seen
|
|
36
|
+
if (seenBlockKeys.has(key)) return false;
|
|
37
|
+
seenBlockKeys.add(key);
|
|
38
|
+
}
|
|
39
|
+
return true;
|
|
27
40
|
}).sort(function (a, b) {
|
|
28
|
-
return a.from - b.from;
|
|
29
|
-
})
|
|
41
|
+
return a.from === b.from ? a.to - b.to : a.from - b.from;
|
|
42
|
+
});
|
|
30
43
|
};
|
|
31
44
|
var createPlugin = exports.createPlugin = function createPlugin(config, getIntl, api) {
|
|
32
45
|
var nodeViewSerializer = new _NodeViewSerializer.NodeViewSerializer({});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if both nodes have the same tree structure (type and child count at every level).
|
|
3
|
+
*/
|
|
4
|
+
function isBlockStructureEqual(node1, node2) {
|
|
5
|
+
if (node1.type !== node2.type || node1.childCount !== node2.childCount) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
for (let i = 0; i < node1.childCount; i++) {
|
|
9
|
+
if (!isBlockStructureEqual(node1.child(i), node2.child(i))) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Looser equality for "safe diff" cases: same full text content and same block structure
|
|
18
|
+
* (e.g. text moved across text-node boundaries). Used when strict areNodesEqualIgnoreAttrs fails.
|
|
19
|
+
* This is safe because we ensure decorations get applied to valid positions.
|
|
20
|
+
*/
|
|
21
|
+
export function areDocsEqualByBlockStructureAndText(doc1, doc2) {
|
|
22
|
+
return doc1.textContent === doc2.textContent && doc1.nodeSize === doc2.nodeSize && isBlockStructureEqual(doc1, doc2);
|
|
23
|
+
}
|
|
@@ -4,7 +4,9 @@ import memoizeOne from 'memoize-one';
|
|
|
4
4
|
import { ChangeSet, simplifyChanges } from 'prosemirror-changeset';
|
|
5
5
|
import { areNodesEqualIgnoreAttrs } from '@atlaskit/editor-common/utils/document';
|
|
6
6
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
7
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
7
8
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
9
|
+
import { areDocsEqualByBlockStructureAndText } from './areDocsEqualByBlockStructureAndText';
|
|
8
10
|
import { createBlockChangedDecoration } from './decorations/createBlockChangedDecoration';
|
|
9
11
|
import { createInlineChangedDecoration } from './decorations/createInlineChangedDecoration';
|
|
10
12
|
import { createNodeChangedDecorationWidget } from './decorations/createNodeChangedDecorationWidget';
|
|
@@ -117,6 +119,7 @@ const calculateDiffDecorationsInner = ({
|
|
|
117
119
|
// Rather than using .eq() we use a custom function that only checks for structural
|
|
118
120
|
// changes and ignores differences in attributes which don't affect decoration positions
|
|
119
121
|
if (!areNodesEqualIgnoreAttrs(steppedDoc, tr.doc)) {
|
|
122
|
+
const recoveredViaContentEquality = fg('platform_editor_show_diff_equality_fallback') ? areDocsEqualByBlockStructureAndText(steppedDoc, tr.doc) : undefined;
|
|
120
123
|
if (expValEquals('platform_editor_are_nodes_equal_ignore_mark_order', 'isEnabled', true)) {
|
|
121
124
|
var _api$analytics;
|
|
122
125
|
api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions.fireAnalyticsEvent({
|
|
@@ -125,11 +128,18 @@ const calculateDiffDecorationsInner = ({
|
|
|
125
128
|
actionSubject: 'showDiff',
|
|
126
129
|
attributes: {
|
|
127
130
|
docSizeEqual: steppedDoc.nodeSize === tr.doc.nodeSize,
|
|
128
|
-
colorScheme
|
|
131
|
+
colorScheme,
|
|
132
|
+
recoveredViaContentEquality
|
|
129
133
|
}
|
|
130
134
|
});
|
|
131
135
|
}
|
|
132
|
-
|
|
136
|
+
if (fg('platform_editor_show_diff_equality_fallback')) {
|
|
137
|
+
if (!recoveredViaContentEquality) {
|
|
138
|
+
return DecorationSet.empty;
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
return DecorationSet.empty;
|
|
142
|
+
}
|
|
133
143
|
}
|
|
134
144
|
const changeset = ChangeSet.create(originalDoc).addSteps(steppedDoc, stepMaps, tr.doc);
|
|
135
145
|
const changes = simplifyChanges(changeset.changes, tr.doc);
|
|
@@ -111,7 +111,8 @@ export const createBlockChangedDecoration = ({
|
|
|
111
111
|
'data-testid': 'show-diff-changed-decoration-node',
|
|
112
112
|
class: className
|
|
113
113
|
}, {
|
|
114
|
-
key: 'diff-block'
|
|
114
|
+
key: 'diff-block',
|
|
115
|
+
nodeName: change.name
|
|
115
116
|
});
|
|
116
117
|
} else {
|
|
117
118
|
return undefined;
|
|
@@ -122,6 +123,7 @@ export const createBlockChangedDecoration = ({
|
|
|
122
123
|
'data-testid': 'show-diff-changed-decoration-node',
|
|
123
124
|
class: className
|
|
124
125
|
}, {
|
|
125
|
-
key: 'diff-block'
|
|
126
|
+
key: 'diff-block',
|
|
127
|
+
nodeName: change.name
|
|
126
128
|
});
|
|
127
129
|
};
|
|
@@ -10,11 +10,24 @@ import { NodeViewSerializer } from './NodeViewSerializer';
|
|
|
10
10
|
import { scrollToActiveDecoration } from './scrollToActiveDecoration';
|
|
11
11
|
export const showDiffPluginKey = new PluginKey('showDiffPlugin');
|
|
12
12
|
export const getScrollableDecorations = set => {
|
|
13
|
-
var _set$find
|
|
14
|
-
|
|
13
|
+
var _set$find;
|
|
14
|
+
const seenBlockKeys = new Set();
|
|
15
|
+
return ((_set$find = set === null || set === void 0 ? void 0 : set.find(undefined, undefined, spec => {
|
|
15
16
|
var _spec$key;
|
|
16
17
|
return spec.key === 'diff-inline' || ((_spec$key = spec.key) === null || _spec$key === void 0 ? void 0 : _spec$key.startsWith('diff-widget')) || spec.key === 'diff-block';
|
|
17
|
-
})
|
|
18
|
+
})) !== null && _set$find !== void 0 ? _set$find : []).filter(dec => {
|
|
19
|
+
var _dec$spec;
|
|
20
|
+
if (((_dec$spec = dec.spec) === null || _dec$spec === void 0 ? void 0 : _dec$spec.key) === 'diff-block') {
|
|
21
|
+
var _dec$spec2, _dec$spec$nodeName, _dec$spec3;
|
|
22
|
+
// Skip listItem blocks as they are not scrollable
|
|
23
|
+
if (((_dec$spec2 = dec.spec) === null || _dec$spec2 === void 0 ? void 0 : _dec$spec2.nodeName) === 'listItem') return false;
|
|
24
|
+
const key = `${dec.from}-${dec.to}-${(_dec$spec$nodeName = (_dec$spec3 = dec.spec) === null || _dec$spec3 === void 0 ? void 0 : _dec$spec3.nodeName) !== null && _dec$spec$nodeName !== void 0 ? _dec$spec$nodeName : ''}`;
|
|
25
|
+
// Skip blocks that have already been seen
|
|
26
|
+
if (seenBlockKeys.has(key)) return false;
|
|
27
|
+
seenBlockKeys.add(key);
|
|
28
|
+
}
|
|
29
|
+
return true;
|
|
30
|
+
}).sort((a, b) => a.from === b.from ? a.to - b.to : a.from - b.from);
|
|
18
31
|
};
|
|
19
32
|
export const createPlugin = (config, getIntl, api) => {
|
|
20
33
|
const nodeViewSerializer = new NodeViewSerializer({});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if both nodes have the same tree structure (type and child count at every level).
|
|
3
|
+
*/
|
|
4
|
+
function isBlockStructureEqual(node1, node2) {
|
|
5
|
+
if (node1.type !== node2.type || node1.childCount !== node2.childCount) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
for (var i = 0; i < node1.childCount; i++) {
|
|
9
|
+
if (!isBlockStructureEqual(node1.child(i), node2.child(i))) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
return true;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Looser equality for "safe diff" cases: same full text content and same block structure
|
|
18
|
+
* (e.g. text moved across text-node boundaries). Used when strict areNodesEqualIgnoreAttrs fails.
|
|
19
|
+
* This is safe because we ensure decorations get applied to valid positions.
|
|
20
|
+
*/
|
|
21
|
+
export function areDocsEqualByBlockStructureAndText(doc1, doc2) {
|
|
22
|
+
return doc1.textContent === doc2.textContent && doc1.nodeSize === doc2.nodeSize && isBlockStructureEqual(doc1, doc2);
|
|
23
|
+
}
|
|
@@ -12,7 +12,9 @@ import memoizeOne from 'memoize-one';
|
|
|
12
12
|
import { ChangeSet, simplifyChanges } from 'prosemirror-changeset';
|
|
13
13
|
import { areNodesEqualIgnoreAttrs } from '@atlaskit/editor-common/utils/document';
|
|
14
14
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
15
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
15
16
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
17
|
+
import { areDocsEqualByBlockStructureAndText } from './areDocsEqualByBlockStructureAndText';
|
|
16
18
|
import { createBlockChangedDecoration } from './decorations/createBlockChangedDecoration';
|
|
17
19
|
import { createInlineChangedDecoration } from './decorations/createInlineChangedDecoration';
|
|
18
20
|
import { createNodeChangedDecorationWidget } from './decorations/createNodeChangedDecorationWidget';
|
|
@@ -126,6 +128,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
126
128
|
_iterator.f();
|
|
127
129
|
}
|
|
128
130
|
if (!areNodesEqualIgnoreAttrs(steppedDoc, tr.doc)) {
|
|
131
|
+
var recoveredViaContentEquality = fg('platform_editor_show_diff_equality_fallback') ? areDocsEqualByBlockStructureAndText(steppedDoc, tr.doc) : undefined;
|
|
129
132
|
if (expValEquals('platform_editor_are_nodes_equal_ignore_mark_order', 'isEnabled', true)) {
|
|
130
133
|
var _api$analytics;
|
|
131
134
|
api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
|
|
@@ -134,11 +137,18 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
134
137
|
actionSubject: 'showDiff',
|
|
135
138
|
attributes: {
|
|
136
139
|
docSizeEqual: steppedDoc.nodeSize === tr.doc.nodeSize,
|
|
137
|
-
colorScheme: colorScheme
|
|
140
|
+
colorScheme: colorScheme,
|
|
141
|
+
recoveredViaContentEquality: recoveredViaContentEquality
|
|
138
142
|
}
|
|
139
143
|
});
|
|
140
144
|
}
|
|
141
|
-
|
|
145
|
+
if (fg('platform_editor_show_diff_equality_fallback')) {
|
|
146
|
+
if (!recoveredViaContentEquality) {
|
|
147
|
+
return DecorationSet.empty;
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
return DecorationSet.empty;
|
|
151
|
+
}
|
|
142
152
|
}
|
|
143
153
|
var changeset = ChangeSet.create(originalDoc).addSteps(steppedDoc, stepMaps, tr.doc);
|
|
144
154
|
var changes = simplifyChanges(changeset.changes, tr.doc);
|
|
@@ -113,7 +113,8 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
113
113
|
'data-testid': 'show-diff-changed-decoration-node',
|
|
114
114
|
class: className
|
|
115
115
|
}, {
|
|
116
|
-
key: 'diff-block'
|
|
116
|
+
key: 'diff-block',
|
|
117
|
+
nodeName: change.name
|
|
117
118
|
});
|
|
118
119
|
} else {
|
|
119
120
|
return undefined;
|
|
@@ -124,6 +125,7 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
124
125
|
'data-testid': 'show-diff-changed-decoration-node',
|
|
125
126
|
class: className
|
|
126
127
|
}, {
|
|
127
|
-
key: 'diff-block'
|
|
128
|
+
key: 'diff-block',
|
|
129
|
+
nodeName: change.name
|
|
128
130
|
});
|
|
129
131
|
};
|
|
@@ -13,13 +13,26 @@ import { NodeViewSerializer } from './NodeViewSerializer';
|
|
|
13
13
|
import { scrollToActiveDecoration } from './scrollToActiveDecoration';
|
|
14
14
|
export var showDiffPluginKey = new PluginKey('showDiffPlugin');
|
|
15
15
|
export var getScrollableDecorations = function getScrollableDecorations(set) {
|
|
16
|
-
var _set$find
|
|
17
|
-
|
|
16
|
+
var _set$find;
|
|
17
|
+
var seenBlockKeys = new Set();
|
|
18
|
+
return ((_set$find = set === null || set === void 0 ? void 0 : set.find(undefined, undefined, function (spec) {
|
|
18
19
|
var _spec$key;
|
|
19
20
|
return spec.key === 'diff-inline' || ((_spec$key = spec.key) === null || _spec$key === void 0 ? void 0 : _spec$key.startsWith('diff-widget')) || spec.key === 'diff-block';
|
|
21
|
+
})) !== null && _set$find !== void 0 ? _set$find : []).filter(function (dec) {
|
|
22
|
+
var _dec$spec;
|
|
23
|
+
if (((_dec$spec = dec.spec) === null || _dec$spec === void 0 ? void 0 : _dec$spec.key) === 'diff-block') {
|
|
24
|
+
var _dec$spec2, _dec$spec$nodeName, _dec$spec3;
|
|
25
|
+
// Skip listItem blocks as they are not scrollable
|
|
26
|
+
if (((_dec$spec2 = dec.spec) === null || _dec$spec2 === void 0 ? void 0 : _dec$spec2.nodeName) === 'listItem') return false;
|
|
27
|
+
var key = "".concat(dec.from, "-").concat(dec.to, "-").concat((_dec$spec$nodeName = (_dec$spec3 = dec.spec) === null || _dec$spec3 === void 0 ? void 0 : _dec$spec3.nodeName) !== null && _dec$spec$nodeName !== void 0 ? _dec$spec$nodeName : '');
|
|
28
|
+
// Skip blocks that have already been seen
|
|
29
|
+
if (seenBlockKeys.has(key)) return false;
|
|
30
|
+
seenBlockKeys.add(key);
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
20
33
|
}).sort(function (a, b) {
|
|
21
|
-
return a.from - b.from;
|
|
22
|
-
})
|
|
34
|
+
return a.from === b.from ? a.to - b.to : a.from - b.from;
|
|
35
|
+
});
|
|
23
36
|
};
|
|
24
37
|
export var createPlugin = function createPlugin(config, getIntl, api) {
|
|
25
38
|
var nodeViewSerializer = new NodeViewSerializer({});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
/**
|
|
3
|
+
* Looser equality for "safe diff" cases: same full text content and same block structure
|
|
4
|
+
* (e.g. text moved across text-node boundaries). Used when strict areNodesEqualIgnoreAttrs fails.
|
|
5
|
+
* This is safe because we ensure decorations get applied to valid positions.
|
|
6
|
+
*/
|
|
7
|
+
export declare function areDocsEqualByBlockStructureAndText(doc1: PMNode, doc2: PMNode): boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
2
|
+
/**
|
|
3
|
+
* Looser equality for "safe diff" cases: same full text content and same block structure
|
|
4
|
+
* (e.g. text moved across text-node boundaries). Used when strict areNodesEqualIgnoreAttrs fails.
|
|
5
|
+
* This is safe because we ensure decorations get applied to valid positions.
|
|
6
|
+
*/
|
|
7
|
+
export declare function areDocsEqualByBlockStructureAndText(doc1: PMNode, doc2: PMNode): boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.4",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -33,7 +33,7 @@
|
|
|
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": "^40.
|
|
36
|
+
"@atlaskit/tmp-editor-statsig": "^40.3.0",
|
|
37
37
|
"@atlaskit/tokens": "^11.1.0",
|
|
38
38
|
"@babel/runtime": "^7.0.0",
|
|
39
39
|
"lodash": "^4.17.21",
|
|
@@ -85,6 +85,9 @@
|
|
|
85
85
|
}
|
|
86
86
|
},
|
|
87
87
|
"platform-feature-flags": {
|
|
88
|
+
"platform_editor_show_diff_equality_fallback": {
|
|
89
|
+
"type": "boolean"
|
|
90
|
+
},
|
|
88
91
|
"platform_editor_show_diff_scroll_navigation": {
|
|
89
92
|
"type": "boolean"
|
|
90
93
|
}
|