@atlaskit/editor-plugin-show-diff 13.1.9 → 14.0.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 +20 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +1 -1
- package/dist/cjs/pm-plugins/calculateDiff/smart/classifySmartChanges.js +7 -0
- package/dist/cjs/pm-plugins/decorations/createAnchorDecorationWidgets.js +4 -5
- package/dist/cjs/pm-plugins/decorations/utils/diffableAttrs.js +15 -7
- package/dist/cjs/pm-plugins/isExtendedEnabled.js +4 -1
- package/dist/cjs/pm-plugins/main.js +4 -3
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +2 -2
- package/dist/es2019/pm-plugins/calculateDiff/smart/classifySmartChanges.js +7 -0
- package/dist/es2019/pm-plugins/decorations/createAnchorDecorationWidgets.js +4 -5
- package/dist/es2019/pm-plugins/decorations/utils/diffableAttrs.js +13 -7
- package/dist/es2019/pm-plugins/isExtendedEnabled.js +2 -1
- package/dist/es2019/pm-plugins/main.js +5 -4
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +2 -2
- package/dist/esm/pm-plugins/calculateDiff/smart/classifySmartChanges.js +7 -0
- package/dist/esm/pm-plugins/decorations/createAnchorDecorationWidgets.js +4 -5
- package/dist/esm/pm-plugins/decorations/utils/diffableAttrs.js +15 -7
- package/dist/esm/pm-plugins/isExtendedEnabled.js +3 -0
- package/dist/esm/pm-plugins/main.js +5 -4
- package/dist/types/pm-plugins/decorations/utils/diffableAttrs.d.ts +3 -3
- package/dist/types/pm-plugins/isExtendedEnabled.d.ts +1 -0
- package/package.json +12 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 14.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`c87074ddaa72d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c87074ddaa72d) -
|
|
8
|
+
Resolve the show-diff left anchor's document-level node once behind
|
|
9
|
+
`platform_editor_diff_plugin_extended`.
|
|
10
|
+
- [`d3bb0c15d7e40`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d3bb0c15d7e40) -
|
|
11
|
+
Recognise generic node attribute changes in Smart diff behind platform_editor_ai_smart_diff.
|
|
12
|
+
- [`92f6f5d3380be`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/92f6f5d3380be) -
|
|
13
|
+
Use the smart diff strategy by default for Confluence version history behind the
|
|
14
|
+
`confluence_ncs_step_diffing_version_history` feature gate.
|
|
15
|
+
- Updated dependencies
|
|
16
|
+
|
|
17
|
+
## 13.1.10
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
|
|
3
23
|
## 13.1.9
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
|
@@ -196,7 +196,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
196
196
|
_ref4$isInverted = _ref4.isInverted,
|
|
197
197
|
isInverted = _ref4$isInverted === void 0 ? false : _ref4$isInverted,
|
|
198
198
|
_ref4$diffType = _ref4.diffType,
|
|
199
|
-
diffType = _ref4$diffType === void 0 ?
|
|
199
|
+
diffType = _ref4$diffType === void 0 ? (0, _isExtendedEnabled.getDefaultDiffType)() : _ref4$diffType,
|
|
200
200
|
_ref4$hideDeletedDiff = _ref4.hideDeletedDiffs,
|
|
201
201
|
hideDeletedDiffs = _ref4$hideDeletedDiff === void 0 ? false : _ref4$hideDeletedDiff,
|
|
202
202
|
_ref4$hideAddedDiffsU = _ref4.hideAddedDiffsUnderline,
|
|
@@ -266,6 +266,13 @@ var classifyBlockGroup = function classifyBlockGroup(group, originalDoc, newDoc,
|
|
|
266
266
|
return [wholeBlockChange(blockA, blockB, changes)];
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
// A meaningful attribute-only change is represented by a node-boundary token. Text analysis
|
|
270
|
+
// starts inside the block, so it cannot associate that token with a sentence and would otherwise
|
|
271
|
+
// drop the change. Promote the block before choosing text or container granularity.
|
|
272
|
+
if (!blockA.node.sameMarkup(blockB.node)) {
|
|
273
|
+
return [wholeBlockChange(blockA, blockB, changes)];
|
|
274
|
+
}
|
|
275
|
+
|
|
269
276
|
// Text-bearing block → sentence / paragraph / inline.
|
|
270
277
|
if (TEXT_BLOCK_TYPES.has(blockB.node.type.name)) {
|
|
271
278
|
return classifyTextblock(blockA, blockB, changes, locale, thresholds);
|
|
@@ -61,6 +61,7 @@ var edgeCases = function edgeCases(doc, from) {
|
|
|
61
61
|
* Layouts and Expands have extra padding around the container
|
|
62
62
|
*/
|
|
63
63
|
return {
|
|
64
|
+
beforePos: beforePos,
|
|
64
65
|
measurePos: beforePos
|
|
65
66
|
};
|
|
66
67
|
}
|
|
@@ -80,6 +81,7 @@ var edgeCases = function edgeCases(doc, from) {
|
|
|
80
81
|
// Measure the first row (`nodeStart` is just inside the table, i.e. the
|
|
81
82
|
// position of the first row): its width matches the table's.
|
|
82
83
|
return {
|
|
84
|
+
beforePos: beforePos,
|
|
83
85
|
measurePos: nodeStart
|
|
84
86
|
};
|
|
85
87
|
}
|
|
@@ -87,6 +89,7 @@ var edgeCases = function edgeCases(doc, from) {
|
|
|
87
89
|
case 'expand':
|
|
88
90
|
// Measure the block itself (the widget is rendered outside the block).
|
|
89
91
|
return {
|
|
92
|
+
beforePos: beforePos,
|
|
90
93
|
leftOffset: 12
|
|
91
94
|
};
|
|
92
95
|
default:
|
|
@@ -133,11 +136,7 @@ var createLeftAnchorWidget = exports.createLeftAnchorWidget = function createLef
|
|
|
133
136
|
|
|
134
137
|
// Render the widget right before the doc-level node so it lives outside the
|
|
135
138
|
// resizable block container.
|
|
136
|
-
var
|
|
137
|
-
if (!resolved) {
|
|
138
|
-
return undefined;
|
|
139
|
-
}
|
|
140
|
-
var beforePos = resolved.beforePos;
|
|
139
|
+
var beforePos = edgeCase.beforePos;
|
|
141
140
|
var leftAnchorKey = (0, _decorationKeys.buildAnchorDecorationKey)({
|
|
142
141
|
diffId: diffId,
|
|
143
142
|
anchorType: _decorationKeys.AnchorTypeKey.left
|
|
@@ -10,7 +10,12 @@ exports.isDiffableAttr = exports.getRequiredIncludedDiffableAttrs = exports.getI
|
|
|
10
10
|
* and `getAttrChangeRanges` (decoration rendering) so the two stages agree.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
//
|
|
13
|
+
// `localId` is editor bookkeeping rather than user-visible content. Suggestions can regenerate it,
|
|
14
|
+
// so treating it as a diff would create phantom changes.
|
|
15
|
+
var DEFAULT_EXCLUDED_ATTRS = ['localId'];
|
|
16
|
+
|
|
17
|
+
// Specialised rules keep existing node-specific behaviour. Node types absent from this map use the
|
|
18
|
+
// generic fallback and diff every attribute except editor bookkeeping attributes.
|
|
14
19
|
var DIFFABLE_ATTRS_BY_NODE_TYPE = exports.DIFFABLE_ATTRS_BY_NODE_TYPE = {
|
|
15
20
|
tableCell: {
|
|
16
21
|
include: ['background', 'colspan', 'rowspan']
|
|
@@ -55,11 +60,12 @@ var DIFFABLE_ATTRS_BY_NODE_TYPE = exports.DIFFABLE_ATTRS_BY_NODE_TYPE = {
|
|
|
55
60
|
}
|
|
56
61
|
};
|
|
57
62
|
|
|
58
|
-
// Whether `attrName` is a meaningful change for `nodeTypeName`.
|
|
63
|
+
// Whether `attrName` is a meaningful change for `nodeTypeName`. Nodes without a specialised rule
|
|
64
|
+
// diff all attributes except editor bookkeeping attributes.
|
|
59
65
|
var isDiffableAttr = exports.isDiffableAttr = function isDiffableAttr(nodeTypeName, attrName) {
|
|
60
66
|
var rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
61
67
|
if (!rule) {
|
|
62
|
-
return
|
|
68
|
+
return !DEFAULT_EXCLUDED_ATTRS.includes(attrName);
|
|
63
69
|
}
|
|
64
70
|
return 'include' in rule ? rule.include.includes(attrName) : !rule.exclude.includes(attrName);
|
|
65
71
|
};
|
|
@@ -83,14 +89,16 @@ var getRequiredIncludedDiffableAttrs = exports.getRequiredIncludedDiffableAttrs
|
|
|
83
89
|
};
|
|
84
90
|
|
|
85
91
|
/**
|
|
86
|
-
* Concrete attr names to diff for a node instance, honouring
|
|
87
|
-
*
|
|
88
|
-
*
|
|
92
|
+
* Concrete attr names to diff for a node instance, honouring specialised rules and otherwise
|
|
93
|
+
* including every attribute except editor bookkeeping. Attribute names are sorted because key
|
|
94
|
+
* order is not stable across the two diffed documents.
|
|
89
95
|
*/
|
|
90
96
|
var getDiffableAttrNames = exports.getDiffableAttrNames = function getDiffableAttrNames(nodeTypeName, attrs) {
|
|
91
97
|
var rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
92
98
|
if (!rule) {
|
|
93
|
-
return
|
|
99
|
+
return Object.keys(attrs).filter(function (name) {
|
|
100
|
+
return !DEFAULT_EXCLUDED_ATTRS.includes(name);
|
|
101
|
+
}).sort();
|
|
94
102
|
}
|
|
95
103
|
if ('include' in rule) {
|
|
96
104
|
return rule.include;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isExtendedEnabled = void 0;
|
|
6
|
+
exports.isExtendedEnabled = exports.getDefaultDiffType = void 0;
|
|
7
7
|
var _fg = require("@atlaskit/platform-feature-flags/fg");
|
|
8
8
|
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
9
9
|
/**
|
|
@@ -17,4 +17,7 @@ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
|
17
17
|
*/
|
|
18
18
|
var isExtendedEnabled = exports.isExtendedEnabled = function isExtendedEnabled(diffType) {
|
|
19
19
|
return (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) || diffType === 'smart' && (0, _fg.fg)('platform_editor_ai_smart_diff');
|
|
20
|
+
};
|
|
21
|
+
var getDefaultDiffType = exports.getDefaultDiffType = function getDefaultDiffType() {
|
|
22
|
+
return (0, _fg.fg)('confluence_ncs_step_diffing_version_history') ? 'smart' : 'inline';
|
|
20
23
|
};
|
|
@@ -34,14 +34,15 @@ var createPlugin = exports.createPlugin = function createPlugin(config, getIntl,
|
|
|
34
34
|
state: {
|
|
35
35
|
init: function init(_, _state) {
|
|
36
36
|
// We do initial setup after we setup the editor view
|
|
37
|
+
var defaultDiffType = (0, _isExtendedEnabled.getDefaultDiffType)();
|
|
37
38
|
return _objectSpread({
|
|
38
39
|
steps: [],
|
|
39
40
|
originalDoc: undefined,
|
|
40
41
|
decorations: _view.DecorationSet.empty,
|
|
41
42
|
isDisplayingChanges: false
|
|
42
|
-
}, (0, _isExtendedEnabled.isExtendedEnabled)() ? {
|
|
43
|
+
}, (0, _isExtendedEnabled.isExtendedEnabled)(defaultDiffType) ? {
|
|
43
44
|
isInverted: false,
|
|
44
|
-
diffType:
|
|
45
|
+
diffType: defaultDiffType,
|
|
45
46
|
hideDeletedDiffs: false,
|
|
46
47
|
hideAddedDiffsUnderline: false,
|
|
47
48
|
showIndicators: false,
|
|
@@ -92,7 +93,7 @@ var createPlugin = exports.createPlugin = function createPlugin(config, getIntl,
|
|
|
92
93
|
activeIndex: undefined
|
|
93
94
|
}, (0, _isExtendedEnabled.isExtendedEnabled)(currentPluginState.diffType) ? {
|
|
94
95
|
isInverted: false,
|
|
95
|
-
diffType:
|
|
96
|
+
diffType: (0, _isExtendedEnabled.getDefaultDiffType)(),
|
|
96
97
|
hideDeletedDiffs: false,
|
|
97
98
|
hideAddedDiffsUnderline: false,
|
|
98
99
|
diffDescriptors: []
|
|
@@ -14,7 +14,7 @@ import { createNodeChangedDecorationWidget } from '../decorations/createNodeChan
|
|
|
14
14
|
import { extractDiffDescriptors } from '../decorations/decorationKeys';
|
|
15
15
|
import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
|
|
16
16
|
import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
|
|
17
|
-
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
17
|
+
import { getDefaultDiffType, isExtendedEnabled } from '../isExtendedEnabled';
|
|
18
18
|
import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
|
|
19
19
|
import { diffBySteps } from './diffBySteps';
|
|
20
20
|
import { groupChangesByBlock } from './groupChangesByBlock';
|
|
@@ -178,7 +178,7 @@ const calculateDiffDecorationsInner = ({
|
|
|
178
178
|
activeIndexPos,
|
|
179
179
|
api,
|
|
180
180
|
isInverted = false,
|
|
181
|
-
diffType =
|
|
181
|
+
diffType = getDefaultDiffType(),
|
|
182
182
|
hideDeletedDiffs = false,
|
|
183
183
|
hideAddedDiffsUnderline: hideAddedDiffsUnderlineParam = false,
|
|
184
184
|
showIndicators = false,
|
|
@@ -242,6 +242,13 @@ const classifyBlockGroup = (group, originalDoc, newDoc, locale, thresholds) => {
|
|
|
242
242
|
return [wholeBlockChange(blockA, blockB, changes)];
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
// A meaningful attribute-only change is represented by a node-boundary token. Text analysis
|
|
246
|
+
// starts inside the block, so it cannot associate that token with a sentence and would otherwise
|
|
247
|
+
// drop the change. Promote the block before choosing text or container granularity.
|
|
248
|
+
if (!blockA.node.sameMarkup(blockB.node)) {
|
|
249
|
+
return [wholeBlockChange(blockA, blockB, changes)];
|
|
250
|
+
}
|
|
251
|
+
|
|
245
252
|
// Text-bearing block → sentence / paragraph / inline.
|
|
246
253
|
if (TEXT_BLOCK_TYPES.has(blockB.node.type.name)) {
|
|
247
254
|
return classifyTextblock(blockA, blockB, changes, locale, thresholds);
|
|
@@ -52,6 +52,7 @@ const edgeCases = (doc, from) => {
|
|
|
52
52
|
* Layouts and Expands have extra padding around the container
|
|
53
53
|
*/
|
|
54
54
|
return {
|
|
55
|
+
beforePos,
|
|
55
56
|
measurePos: beforePos
|
|
56
57
|
};
|
|
57
58
|
}
|
|
@@ -71,6 +72,7 @@ const edgeCases = (doc, from) => {
|
|
|
71
72
|
// Measure the first row (`nodeStart` is just inside the table, i.e. the
|
|
72
73
|
// position of the first row): its width matches the table's.
|
|
73
74
|
return {
|
|
75
|
+
beforePos,
|
|
74
76
|
measurePos: nodeStart
|
|
75
77
|
};
|
|
76
78
|
}
|
|
@@ -78,6 +80,7 @@ const edgeCases = (doc, from) => {
|
|
|
78
80
|
case 'expand':
|
|
79
81
|
// Measure the block itself (the widget is rendered outside the block).
|
|
80
82
|
return {
|
|
83
|
+
beforePos,
|
|
81
84
|
leftOffset: 12
|
|
82
85
|
};
|
|
83
86
|
default:
|
|
@@ -125,13 +128,9 @@ export const createLeftAnchorWidget = ({
|
|
|
125
128
|
|
|
126
129
|
// Render the widget right before the doc-level node so it lives outside the
|
|
127
130
|
// resizable block container.
|
|
128
|
-
const resolved = resolveDocLevelNode(doc, from);
|
|
129
|
-
if (!resolved) {
|
|
130
|
-
return undefined;
|
|
131
|
-
}
|
|
132
131
|
const {
|
|
133
132
|
beforePos
|
|
134
|
-
} =
|
|
133
|
+
} = edgeCase;
|
|
135
134
|
const leftAnchorKey = buildAnchorDecorationKey({
|
|
136
135
|
diffId,
|
|
137
136
|
anchorType: AnchorTypeKey.left
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
* and `getAttrChangeRanges` (decoration rendering) so the two stages agree.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
//
|
|
7
|
+
// `localId` is editor bookkeeping rather than user-visible content. Suggestions can regenerate it,
|
|
8
|
+
// so treating it as a diff would create phantom changes.
|
|
9
|
+
const DEFAULT_EXCLUDED_ATTRS = ['localId'];
|
|
10
|
+
|
|
11
|
+
// Specialised rules keep existing node-specific behaviour. Node types absent from this map use the
|
|
12
|
+
// generic fallback and diff every attribute except editor bookkeeping attributes.
|
|
8
13
|
export const DIFFABLE_ATTRS_BY_NODE_TYPE = {
|
|
9
14
|
tableCell: {
|
|
10
15
|
include: ['background', 'colspan', 'rowspan']
|
|
@@ -49,11 +54,12 @@ export const DIFFABLE_ATTRS_BY_NODE_TYPE = {
|
|
|
49
54
|
}
|
|
50
55
|
};
|
|
51
56
|
|
|
52
|
-
// Whether `attrName` is a meaningful change for `nodeTypeName`.
|
|
57
|
+
// Whether `attrName` is a meaningful change for `nodeTypeName`. Nodes without a specialised rule
|
|
58
|
+
// diff all attributes except editor bookkeeping attributes.
|
|
53
59
|
export const isDiffableAttr = (nodeTypeName, attrName) => {
|
|
54
60
|
const rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
55
61
|
if (!rule) {
|
|
56
|
-
return
|
|
62
|
+
return !DEFAULT_EXCLUDED_ATTRS.includes(attrName);
|
|
57
63
|
}
|
|
58
64
|
return 'include' in rule ? rule.include.includes(attrName) : !rule.exclude.includes(attrName);
|
|
59
65
|
};
|
|
@@ -77,14 +83,14 @@ export const getRequiredIncludedDiffableAttrs = nodeTypeName => {
|
|
|
77
83
|
};
|
|
78
84
|
|
|
79
85
|
/**
|
|
80
|
-
* Concrete attr names to diff for a node instance, honouring
|
|
81
|
-
*
|
|
82
|
-
*
|
|
86
|
+
* Concrete attr names to diff for a node instance, honouring specialised rules and otherwise
|
|
87
|
+
* including every attribute except editor bookkeeping. Attribute names are sorted because key
|
|
88
|
+
* order is not stable across the two diffed documents.
|
|
83
89
|
*/
|
|
84
90
|
export const getDiffableAttrNames = (nodeTypeName, attrs) => {
|
|
85
91
|
const rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
86
92
|
if (!rule) {
|
|
87
|
-
return
|
|
93
|
+
return Object.keys(attrs).filter(name => !DEFAULT_EXCLUDED_ATTRS.includes(name)).sort();
|
|
88
94
|
}
|
|
89
95
|
if ('include' in rule) {
|
|
90
96
|
return rule.include;
|
|
@@ -9,4 +9,5 @@ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
|
9
9
|
* Pass the active `diffType` so callers deep in the decoration layer render the extended shape
|
|
10
10
|
* when `smart` is active even if `platform_editor_diff_plugin_extended` is off.
|
|
11
11
|
*/
|
|
12
|
-
export const isExtendedEnabled = diffType => expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) || diffType === 'smart' && fg('platform_editor_ai_smart_diff');
|
|
12
|
+
export const isExtendedEnabled = diffType => expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) || diffType === 'smart' && fg('platform_editor_ai_smart_diff');
|
|
13
|
+
export const getDefaultDiffType = () => fg('confluence_ncs_step_diffing_version_history') ? 'smart' : 'inline';
|
|
@@ -7,7 +7,7 @@ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
|
7
7
|
import { calculateDiffDecorations } from './calculateDiff/calculateDiffDecorations';
|
|
8
8
|
import { enforceCustomStepRegisters } from './enforceCustomStepRegisters';
|
|
9
9
|
import { getScrollableDecorations } from './getScrollableDecorations';
|
|
10
|
-
import { isExtendedEnabled } from './isExtendedEnabled';
|
|
10
|
+
import { getDefaultDiffType, isExtendedEnabled } from './isExtendedEnabled';
|
|
11
11
|
import { NodeViewSerializer } from './NodeViewSerializer';
|
|
12
12
|
import { scrollToDecoration } from './scrollToDiff';
|
|
13
13
|
export const showDiffPluginKey = new PluginKey('showDiffPlugin');
|
|
@@ -24,14 +24,15 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
24
24
|
state: {
|
|
25
25
|
init(_, _state) {
|
|
26
26
|
// We do initial setup after we setup the editor view
|
|
27
|
+
const defaultDiffType = getDefaultDiffType();
|
|
27
28
|
return {
|
|
28
29
|
steps: [],
|
|
29
30
|
originalDoc: undefined,
|
|
30
31
|
decorations: DecorationSet.empty,
|
|
31
32
|
isDisplayingChanges: false,
|
|
32
|
-
...(isExtendedEnabled() ? {
|
|
33
|
+
...(isExtendedEnabled(defaultDiffType) ? {
|
|
33
34
|
isInverted: false,
|
|
34
|
-
diffType:
|
|
35
|
+
diffType: defaultDiffType,
|
|
35
36
|
hideDeletedDiffs: false,
|
|
36
37
|
hideAddedDiffsUnderline: false,
|
|
37
38
|
showIndicators: false,
|
|
@@ -93,7 +94,7 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
93
94
|
*/
|
|
94
95
|
...(isExtendedEnabled(currentPluginState.diffType) ? {
|
|
95
96
|
isInverted: false,
|
|
96
|
-
diffType:
|
|
97
|
+
diffType: getDefaultDiffType(),
|
|
97
98
|
hideDeletedDiffs: false,
|
|
98
99
|
hideAddedDiffsUnderline: false,
|
|
99
100
|
diffDescriptors: []
|
|
@@ -22,7 +22,7 @@ import { createNodeChangedDecorationWidget } from '../decorations/createNodeChan
|
|
|
22
22
|
import { extractDiffDescriptors } from '../decorations/decorationKeys';
|
|
23
23
|
import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
|
|
24
24
|
import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
|
|
25
|
-
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
25
|
+
import { getDefaultDiffType, isExtendedEnabled } from '../isExtendedEnabled';
|
|
26
26
|
import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
|
|
27
27
|
import { diffBySteps } from './diffBySteps';
|
|
28
28
|
import { groupChangesByBlock } from './groupChangesByBlock';
|
|
@@ -189,7 +189,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
189
189
|
_ref4$isInverted = _ref4.isInverted,
|
|
190
190
|
isInverted = _ref4$isInverted === void 0 ? false : _ref4$isInverted,
|
|
191
191
|
_ref4$diffType = _ref4.diffType,
|
|
192
|
-
diffType = _ref4$diffType === void 0 ?
|
|
192
|
+
diffType = _ref4$diffType === void 0 ? getDefaultDiffType() : _ref4$diffType,
|
|
193
193
|
_ref4$hideDeletedDiff = _ref4.hideDeletedDiffs,
|
|
194
194
|
hideDeletedDiffs = _ref4$hideDeletedDiff === void 0 ? false : _ref4$hideDeletedDiff,
|
|
195
195
|
_ref4$hideAddedDiffsU = _ref4.hideAddedDiffsUnderline,
|
|
@@ -259,6 +259,13 @@ var classifyBlockGroup = function classifyBlockGroup(group, originalDoc, newDoc,
|
|
|
259
259
|
return [wholeBlockChange(blockA, blockB, changes)];
|
|
260
260
|
}
|
|
261
261
|
|
|
262
|
+
// A meaningful attribute-only change is represented by a node-boundary token. Text analysis
|
|
263
|
+
// starts inside the block, so it cannot associate that token with a sentence and would otherwise
|
|
264
|
+
// drop the change. Promote the block before choosing text or container granularity.
|
|
265
|
+
if (!blockA.node.sameMarkup(blockB.node)) {
|
|
266
|
+
return [wholeBlockChange(blockA, blockB, changes)];
|
|
267
|
+
}
|
|
268
|
+
|
|
262
269
|
// Text-bearing block → sentence / paragraph / inline.
|
|
263
270
|
if (TEXT_BLOCK_TYPES.has(blockB.node.type.name)) {
|
|
264
271
|
return classifyTextblock(blockA, blockB, changes, locale, thresholds);
|
|
@@ -55,6 +55,7 @@ var edgeCases = function edgeCases(doc, from) {
|
|
|
55
55
|
* Layouts and Expands have extra padding around the container
|
|
56
56
|
*/
|
|
57
57
|
return {
|
|
58
|
+
beforePos: beforePos,
|
|
58
59
|
measurePos: beforePos
|
|
59
60
|
};
|
|
60
61
|
}
|
|
@@ -74,6 +75,7 @@ var edgeCases = function edgeCases(doc, from) {
|
|
|
74
75
|
// Measure the first row (`nodeStart` is just inside the table, i.e. the
|
|
75
76
|
// position of the first row): its width matches the table's.
|
|
76
77
|
return {
|
|
78
|
+
beforePos: beforePos,
|
|
77
79
|
measurePos: nodeStart
|
|
78
80
|
};
|
|
79
81
|
}
|
|
@@ -81,6 +83,7 @@ var edgeCases = function edgeCases(doc, from) {
|
|
|
81
83
|
case 'expand':
|
|
82
84
|
// Measure the block itself (the widget is rendered outside the block).
|
|
83
85
|
return {
|
|
86
|
+
beforePos: beforePos,
|
|
84
87
|
leftOffset: 12
|
|
85
88
|
};
|
|
86
89
|
default:
|
|
@@ -127,11 +130,7 @@ export var createLeftAnchorWidget = function createLeftAnchorWidget(_ref) {
|
|
|
127
130
|
|
|
128
131
|
// Render the widget right before the doc-level node so it lives outside the
|
|
129
132
|
// resizable block container.
|
|
130
|
-
var
|
|
131
|
-
if (!resolved) {
|
|
132
|
-
return undefined;
|
|
133
|
-
}
|
|
134
|
-
var beforePos = resolved.beforePos;
|
|
133
|
+
var beforePos = edgeCase.beforePos;
|
|
135
134
|
var leftAnchorKey = buildAnchorDecorationKey({
|
|
136
135
|
diffId: diffId,
|
|
137
136
|
anchorType: AnchorTypeKey.left
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
* and `getAttrChangeRanges` (decoration rendering) so the two stages agree.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
//
|
|
7
|
+
// `localId` is editor bookkeeping rather than user-visible content. Suggestions can regenerate it,
|
|
8
|
+
// so treating it as a diff would create phantom changes.
|
|
9
|
+
var DEFAULT_EXCLUDED_ATTRS = ['localId'];
|
|
10
|
+
|
|
11
|
+
// Specialised rules keep existing node-specific behaviour. Node types absent from this map use the
|
|
12
|
+
// generic fallback and diff every attribute except editor bookkeeping attributes.
|
|
8
13
|
export var DIFFABLE_ATTRS_BY_NODE_TYPE = {
|
|
9
14
|
tableCell: {
|
|
10
15
|
include: ['background', 'colspan', 'rowspan']
|
|
@@ -49,11 +54,12 @@ export var DIFFABLE_ATTRS_BY_NODE_TYPE = {
|
|
|
49
54
|
}
|
|
50
55
|
};
|
|
51
56
|
|
|
52
|
-
// Whether `attrName` is a meaningful change for `nodeTypeName`.
|
|
57
|
+
// Whether `attrName` is a meaningful change for `nodeTypeName`. Nodes without a specialised rule
|
|
58
|
+
// diff all attributes except editor bookkeeping attributes.
|
|
53
59
|
export var isDiffableAttr = function isDiffableAttr(nodeTypeName, attrName) {
|
|
54
60
|
var rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
55
61
|
if (!rule) {
|
|
56
|
-
return
|
|
62
|
+
return !DEFAULT_EXCLUDED_ATTRS.includes(attrName);
|
|
57
63
|
}
|
|
58
64
|
return 'include' in rule ? rule.include.includes(attrName) : !rule.exclude.includes(attrName);
|
|
59
65
|
};
|
|
@@ -77,14 +83,16 @@ export var getRequiredIncludedDiffableAttrs = function getRequiredIncludedDiffab
|
|
|
77
83
|
};
|
|
78
84
|
|
|
79
85
|
/**
|
|
80
|
-
* Concrete attr names to diff for a node instance, honouring
|
|
81
|
-
*
|
|
82
|
-
*
|
|
86
|
+
* Concrete attr names to diff for a node instance, honouring specialised rules and otherwise
|
|
87
|
+
* including every attribute except editor bookkeeping. Attribute names are sorted because key
|
|
88
|
+
* order is not stable across the two diffed documents.
|
|
83
89
|
*/
|
|
84
90
|
export var getDiffableAttrNames = function getDiffableAttrNames(nodeTypeName, attrs) {
|
|
85
91
|
var rule = DIFFABLE_ATTRS_BY_NODE_TYPE[nodeTypeName];
|
|
86
92
|
if (!rule) {
|
|
87
|
-
return
|
|
93
|
+
return Object.keys(attrs).filter(function (name) {
|
|
94
|
+
return !DEFAULT_EXCLUDED_ATTRS.includes(name);
|
|
95
|
+
}).sort();
|
|
88
96
|
}
|
|
89
97
|
if ('include' in rule) {
|
|
90
98
|
return rule.include;
|
|
@@ -11,4 +11,7 @@ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
|
11
11
|
*/
|
|
12
12
|
export var isExtendedEnabled = function isExtendedEnabled(diffType) {
|
|
13
13
|
return expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) || diffType === 'smart' && fg('platform_editor_ai_smart_diff');
|
|
14
|
+
};
|
|
15
|
+
export var getDefaultDiffType = function getDefaultDiffType() {
|
|
16
|
+
return fg('confluence_ncs_step_diffing_version_history') ? 'smart' : 'inline';
|
|
14
17
|
};
|
|
@@ -10,7 +10,7 @@ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
|
10
10
|
import { calculateDiffDecorations } from './calculateDiff/calculateDiffDecorations';
|
|
11
11
|
import { enforceCustomStepRegisters } from './enforceCustomStepRegisters';
|
|
12
12
|
import { getScrollableDecorations } from './getScrollableDecorations';
|
|
13
|
-
import { isExtendedEnabled } from './isExtendedEnabled';
|
|
13
|
+
import { getDefaultDiffType, isExtendedEnabled } from './isExtendedEnabled';
|
|
14
14
|
import { NodeViewSerializer } from './NodeViewSerializer';
|
|
15
15
|
import { scrollToDecoration } from './scrollToDiff';
|
|
16
16
|
export var showDiffPluginKey = new PluginKey('showDiffPlugin');
|
|
@@ -27,14 +27,15 @@ export var createPlugin = function createPlugin(config, getIntl, api, onEditorVi
|
|
|
27
27
|
state: {
|
|
28
28
|
init: function init(_, _state) {
|
|
29
29
|
// We do initial setup after we setup the editor view
|
|
30
|
+
var defaultDiffType = getDefaultDiffType();
|
|
30
31
|
return _objectSpread({
|
|
31
32
|
steps: [],
|
|
32
33
|
originalDoc: undefined,
|
|
33
34
|
decorations: DecorationSet.empty,
|
|
34
35
|
isDisplayingChanges: false
|
|
35
|
-
}, isExtendedEnabled() ? {
|
|
36
|
+
}, isExtendedEnabled(defaultDiffType) ? {
|
|
36
37
|
isInverted: false,
|
|
37
|
-
diffType:
|
|
38
|
+
diffType: defaultDiffType,
|
|
38
39
|
hideDeletedDiffs: false,
|
|
39
40
|
hideAddedDiffsUnderline: false,
|
|
40
41
|
showIndicators: false,
|
|
@@ -85,7 +86,7 @@ export var createPlugin = function createPlugin(config, getIntl, api, onEditorVi
|
|
|
85
86
|
activeIndex: undefined
|
|
86
87
|
}, isExtendedEnabled(currentPluginState.diffType) ? {
|
|
87
88
|
isInverted: false,
|
|
88
|
-
diffType:
|
|
89
|
+
diffType: getDefaultDiffType(),
|
|
89
90
|
hideDeletedDiffs: false,
|
|
90
91
|
hideAddedDiffsUnderline: false,
|
|
91
92
|
diffDescriptors: []
|
|
@@ -13,8 +13,8 @@ export declare const isDiffableAttr: (nodeTypeName: string, attrName: string) =>
|
|
|
13
13
|
export declare const getIncludedDiffableAttrs: (nodeTypeName: string) => readonly string[] | undefined;
|
|
14
14
|
export declare const getRequiredIncludedDiffableAttrs: (nodeTypeName: string) => readonly string[];
|
|
15
15
|
/**
|
|
16
|
-
* Concrete attr names to diff for a node instance, honouring
|
|
17
|
-
*
|
|
18
|
-
*
|
|
16
|
+
* Concrete attr names to diff for a node instance, honouring specialised rules and otherwise
|
|
17
|
+
* including every attribute except editor bookkeeping. Attribute names are sorted because key
|
|
18
|
+
* order is not stable across the two diffed documents.
|
|
19
19
|
*/
|
|
20
20
|
export declare const getDiffableAttrNames: (nodeTypeName: string, attrs: Record<string, unknown>) => readonly string[] | undefined;
|
|
@@ -9,3 +9,4 @@ import type { DiffType } from '../showDiffPluginType';
|
|
|
9
9
|
* when `smart` is active even if `platform_editor_diff_plugin_extended` is off.
|
|
10
10
|
*/
|
|
11
11
|
export declare const isExtendedEnabled: (diffType?: DiffType) => boolean;
|
|
12
|
+
export declare const getDefaultDiffType: () => DiffType;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "14.0.0",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -20,15 +20,15 @@
|
|
|
20
20
|
"sideEffects": false,
|
|
21
21
|
"atlaskit:src": "src/index.ts",
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@atlaskit/adf-schema": "^57.
|
|
23
|
+
"@atlaskit/adf-schema": "^57.1.0",
|
|
24
24
|
"@atlaskit/custom-steps": "^1.0.0",
|
|
25
|
-
"@atlaskit/editor-plugin-analytics": "^
|
|
26
|
-
"@atlaskit/editor-plugin-user-intent": "^
|
|
25
|
+
"@atlaskit/editor-plugin-analytics": "^16.0.0",
|
|
26
|
+
"@atlaskit/editor-plugin-user-intent": "^14.0.0",
|
|
27
27
|
"@atlaskit/editor-prosemirror": "^8.0.0",
|
|
28
28
|
"@atlaskit/editor-tables": "^3.0.0",
|
|
29
29
|
"@atlaskit/platform-feature-experiments": "^0.3.0",
|
|
30
30
|
"@atlaskit/platform-feature-flags": "^2.1.0",
|
|
31
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
31
|
+
"@atlaskit/tmp-editor-statsig": "^160.0.0",
|
|
32
32
|
"@atlaskit/tokens": "^16.8.0",
|
|
33
33
|
"@babel/runtime": "^7.0.0",
|
|
34
34
|
"@compiled/react": "^1.0.2",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@atlaskit/button": "^25.2.0",
|
|
42
42
|
"@atlaskit/css": "^1.0.0",
|
|
43
43
|
"@atlaskit/dropdown-menu": "^18.2.0",
|
|
44
|
-
"@atlaskit/editor-core": "^
|
|
44
|
+
"@atlaskit/editor-core": "^225.0.0",
|
|
45
45
|
"@atlaskit/editor-json-transformer": "^9.6.0",
|
|
46
46
|
"@atlaskit/editor-plugins": "^16.1.0",
|
|
47
47
|
"@atlaskit/form": "^17.1.0",
|
|
@@ -52,14 +52,14 @@
|
|
|
52
52
|
"@atlaskit/util-data-test": "^19.1.0",
|
|
53
53
|
"@atlassian/confluence-presets": "workspace:^",
|
|
54
54
|
"@atlassian/content-reconciliation": "^0.1.3506",
|
|
55
|
-
"@atlassian/editor-ai-injected-editors": "^
|
|
56
|
-
"@atlassian/editor-plugin-ai": "^
|
|
55
|
+
"@atlassian/editor-ai-injected-editors": "^29.0.0",
|
|
56
|
+
"@atlassian/editor-plugin-ai": "^70.0.0",
|
|
57
57
|
"@atlassian/structured-docs-types": "workspace:^",
|
|
58
58
|
"react": "^19.2.0",
|
|
59
59
|
"react-intl": "^7.0.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
|
-
"@atlaskit/editor-common": "^
|
|
62
|
+
"@atlaskit/editor-common": "^120.0.0",
|
|
63
63
|
"react": "^18.2.0 || ^19.2.0"
|
|
64
64
|
},
|
|
65
65
|
"techstack": {
|
|
@@ -101,6 +101,9 @@
|
|
|
101
101
|
"platform-feature-flags": {
|
|
102
102
|
"platform_editor_ai_smart_diff": {
|
|
103
103
|
"type": "boolean"
|
|
104
|
+
},
|
|
105
|
+
"confluence_ncs_step_diffing_version_history": {
|
|
106
|
+
"type": "boolean"
|
|
104
107
|
}
|
|
105
108
|
}
|
|
106
109
|
}
|