@atlaskit/editor-plugin-show-diff 6.1.2 → 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 +15 -0
- package/dist/cjs/pm-plugins/areDocsEqualByBlockStructureAndText.js +29 -0
- package/dist/cjs/pm-plugins/calculateDiffDecorations.js +29 -10
- package/dist/cjs/pm-plugins/decorations/colorSchemes/standard.js +1 -1
- package/dist/cjs/pm-plugins/decorations/colorSchemes/traditional.js +39 -2
- package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +37 -27
- package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +10 -4
- package/dist/cjs/pm-plugins/main.js +19 -3
- package/dist/es2019/pm-plugins/areDocsEqualByBlockStructureAndText.js +23 -0
- package/dist/es2019/pm-plugins/calculateDiffDecorations.js +28 -10
- package/dist/es2019/pm-plugins/decorations/colorSchemes/standard.js +1 -1
- package/dist/es2019/pm-plugins/decorations/colorSchemes/traditional.js +38 -1
- package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +36 -28
- package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +13 -6
- package/dist/es2019/pm-plugins/main.js +17 -1
- package/dist/esm/pm-plugins/areDocsEqualByBlockStructureAndText.js +23 -0
- package/dist/esm/pm-plugins/calculateDiffDecorations.js +29 -10
- package/dist/esm/pm-plugins/decorations/colorSchemes/standard.js +1 -1
- package/dist/esm/pm-plugins/decorations/colorSchemes/traditional.js +38 -1
- package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +38 -28
- package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +11 -5
- package/dist/esm/pm-plugins/main.js +19 -3
- package/dist/types/pm-plugins/areDocsEqualByBlockStructureAndText.d.ts +7 -0
- package/dist/types/pm-plugins/decorations/colorSchemes/traditional.d.ts +9 -0
- package/dist/types/pm-plugins/decorations/createBlockChangedDecoration.d.ts +8 -5
- package/dist/types/pm-plugins/decorations/createNodeChangedDecorationWidget.d.ts +1 -1
- package/dist/types-ts4.5/pm-plugins/areDocsEqualByBlockStructureAndText.d.ts +7 -0
- package/dist/types-ts4.5/pm-plugins/decorations/colorSchemes/traditional.d.ts +9 -0
- package/dist/types-ts4.5/pm-plugins/decorations/createBlockChangedDecoration.d.ts +8 -5
- package/dist/types-ts4.5/pm-plugins/decorations/createNodeChangedDecorationWidget.d.ts +1 -1
- package/package.json +5 -2
|
@@ -7,7 +7,7 @@ export const traditionalInsertStyle = convertToInlineCss({
|
|
|
7
7
|
textDecorationColor: "var(--ds-border-accent-green, #22A06B)"
|
|
8
8
|
});
|
|
9
9
|
export const traditionalInsertStyleActive = convertToInlineCss({
|
|
10
|
-
background: "var(--ds-background-accent-green-subtler, #
|
|
10
|
+
background: "var(--ds-background-accent-green-subtler-pressed, #7EE2B8)",
|
|
11
11
|
textDecoration: 'underline',
|
|
12
12
|
textDecorationStyle: 'solid',
|
|
13
13
|
textDecorationThickness: "var(--ds-space-025, 2px)",
|
|
@@ -19,6 +19,15 @@ export const deletedTraditionalContentStyle = convertToInlineCss({
|
|
|
19
19
|
position: 'relative',
|
|
20
20
|
opacity: 1
|
|
21
21
|
});
|
|
22
|
+
|
|
23
|
+
/** Emphasised (pressed) strikethrough for traditional removed text when active */
|
|
24
|
+
export const deletedTraditionalContentStyleActive = convertToInlineCss({
|
|
25
|
+
textDecorationColor: "var(--ds-text-accent-red, #AE2E24)",
|
|
26
|
+
textDecoration: 'line-through',
|
|
27
|
+
backgroundColor: "var(--ds-background-accent-red-subtlest-pressed, #FFB8B2)",
|
|
28
|
+
position: 'relative',
|
|
29
|
+
opacity: 1
|
|
30
|
+
});
|
|
22
31
|
export const deletedTraditionalContentStyleUnbounded = convertToInlineCss({
|
|
23
32
|
position: 'absolute',
|
|
24
33
|
top: '50%',
|
|
@@ -28,6 +37,17 @@ export const deletedTraditionalContentStyleUnbounded = convertToInlineCss({
|
|
|
28
37
|
pointerEvents: 'none',
|
|
29
38
|
zIndex: 1
|
|
30
39
|
});
|
|
40
|
+
|
|
41
|
+
/** Emphasised (pressed) strikethrough line for traditional when active */
|
|
42
|
+
export const deletedTraditionalContentStyleUnboundedActive = convertToInlineCss({
|
|
43
|
+
position: 'absolute',
|
|
44
|
+
top: '50%',
|
|
45
|
+
width: '100%',
|
|
46
|
+
display: 'inline-block',
|
|
47
|
+
borderTop: `1px solid ${"var(--ds-text-accent-red-bolder, #5D1F1A)"}`,
|
|
48
|
+
pointerEvents: 'none',
|
|
49
|
+
zIndex: 1
|
|
50
|
+
});
|
|
31
51
|
export const deletedTraditionalStyleQuoteNode = convertToInlineCss({
|
|
32
52
|
marginTop: "var(--ds-space-150, 12px)",
|
|
33
53
|
paddingTop: "var(--ds-space-025, 2px)",
|
|
@@ -53,20 +73,37 @@ export const deletedTraditionalRowStyle = convertToInlineCss({
|
|
|
53
73
|
export const traditionalStyleQuoteNode = convertToInlineCss({
|
|
54
74
|
borderLeft: `2px solid ${"var(--ds-border-accent-green, #22A06B)"}`
|
|
55
75
|
});
|
|
76
|
+
export const traditionalStyleQuoteNodeActive = convertToInlineCss({
|
|
77
|
+
borderLeft: `2px solid ${"var(--ds-background-accent-green-subtler-pressed, #7EE2B8)"}`
|
|
78
|
+
});
|
|
56
79
|
export const traditionalStyleRuleNode = convertToInlineCss({
|
|
57
80
|
backgroundColor: "var(--ds-border-accent-green, #22A06B)"
|
|
58
81
|
});
|
|
82
|
+
export const traditionalStyleRuleNodeActive = convertToInlineCss({
|
|
83
|
+
backgroundColor: "var(--ds-background-accent-green-subtler-pressed, #7EE2B8)"
|
|
84
|
+
});
|
|
59
85
|
export const traditionalStyleNode = convertToInlineCss({
|
|
60
86
|
boxShadow: `0 0 0 1px ${"var(--ds-border-accent-green, #22A06B)"}`,
|
|
61
87
|
borderRadius: "var(--ds-radius-small, 4px)"
|
|
62
88
|
});
|
|
89
|
+
export const traditionalStyleNodeActive = convertToInlineCss({
|
|
90
|
+
boxShadow: `0 0 0 2px ${"var(--ds-background-accent-green-subtler-pressed, #7EE2B8)"}`,
|
|
91
|
+
borderRadius: "var(--ds-radius-small, 4px)"
|
|
92
|
+
});
|
|
63
93
|
export const traditionalStyleCardBlockNode = convertToInlineCss({
|
|
64
94
|
boxShadow: `0 0 0 1px ${"var(--ds-border-accent-green, #22A06B)"}`,
|
|
65
95
|
borderRadius: "var(--ds-radius-medium, 6px)"
|
|
66
96
|
});
|
|
97
|
+
export const traditionalStyleCardBlockNodeActive = convertToInlineCss({
|
|
98
|
+
boxShadow: `0 0 0 1px ${"var(--ds-background-accent-green-subtler-pressed, #7EE2B8)"}`,
|
|
99
|
+
borderRadius: "var(--ds-radius-medium, 6px)"
|
|
100
|
+
});
|
|
67
101
|
export const traditionalDecorationMarkerVariable = convertToInlineCss({
|
|
68
102
|
'--diff-decoration-marker-color': "var(--ds-border-accent-green, #22A06B)"
|
|
69
103
|
});
|
|
104
|
+
export const traditionalDecorationMarkerVariableActive = convertToInlineCss({
|
|
105
|
+
'--diff-decoration-marker-color': "var(--ds-text-accent-green, #216E4E)"
|
|
106
|
+
});
|
|
70
107
|
export const traditionalAddedCellOverlayStyle = convertToInlineCss({
|
|
71
108
|
position: 'absolute',
|
|
72
109
|
top: 0,
|
|
@@ -2,7 +2,7 @@ import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
|
2
2
|
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
3
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
4
4
|
import { standardDecorationMarkerVariable, editingStyleQuoteNode, editingStyleRuleNode, editingStyleCardBlockNode, editingStyleNode, deletedContentStyleNew, deletedStyleQuoteNode } from './colorSchemes/standard';
|
|
5
|
-
import { traditionalDecorationMarkerVariable, traditionalStyleQuoteNode, traditionalStyleRuleNode, traditionalStyleCardBlockNode, traditionalStyleNode, deletedTraditionalContentStyle, deletedTraditionalStyleQuoteNode } from './colorSchemes/traditional';
|
|
5
|
+
import { traditionalDecorationMarkerVariable, traditionalDecorationMarkerVariableActive, traditionalStyleQuoteNode, traditionalStyleQuoteNodeActive, traditionalStyleRuleNode, traditionalStyleRuleNodeActive, traditionalStyleCardBlockNode, traditionalStyleCardBlockNodeActive, traditionalStyleNode, traditionalStyleNodeActive, deletedTraditionalContentStyle, deletedTraditionalStyleQuoteNode } from './colorSchemes/traditional';
|
|
6
6
|
const getNodeClass = name => {
|
|
7
7
|
switch (name) {
|
|
8
8
|
case 'extension':
|
|
@@ -14,7 +14,8 @@ const getNodeClass = name => {
|
|
|
14
14
|
const getBlockNodeStyle = ({
|
|
15
15
|
nodeName,
|
|
16
16
|
colorScheme,
|
|
17
|
-
isInserted = true
|
|
17
|
+
isInserted = true,
|
|
18
|
+
isActive = false
|
|
18
19
|
}) => {
|
|
19
20
|
const isTraditional = colorScheme === 'traditional';
|
|
20
21
|
if (['mediaSingle', 'mediaGroup', 'table',
|
|
@@ -28,73 +29,78 @@ const getBlockNodeStyle = ({
|
|
|
28
29
|
if (['extension', 'embedCard', 'listItem'].includes(nodeName)) {
|
|
29
30
|
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
30
31
|
if (isInserted) {
|
|
31
|
-
return isTraditional ? traditionalDecorationMarkerVariable : standardDecorationMarkerVariable;
|
|
32
|
+
return isTraditional && isActive ? traditionalDecorationMarkerVariableActive : isTraditional ? traditionalDecorationMarkerVariable : standardDecorationMarkerVariable;
|
|
32
33
|
} else {
|
|
33
34
|
return isTraditional ? deletedTraditionalContentStyle : deletedContentStyleNew;
|
|
34
35
|
}
|
|
35
36
|
}
|
|
36
|
-
return isTraditional ? traditionalDecorationMarkerVariable : standardDecorationMarkerVariable;
|
|
37
|
+
return isTraditional && isActive ? traditionalDecorationMarkerVariableActive : isTraditional ? traditionalDecorationMarkerVariable : standardDecorationMarkerVariable;
|
|
37
38
|
}
|
|
38
39
|
if (nodeName === 'blockquote') {
|
|
39
40
|
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
40
41
|
if (isInserted) {
|
|
41
|
-
return isTraditional ? traditionalStyleQuoteNode : editingStyleQuoteNode;
|
|
42
|
+
return isTraditional ? isActive ? traditionalStyleQuoteNodeActive : traditionalStyleQuoteNode : editingStyleQuoteNode;
|
|
42
43
|
} else {
|
|
43
44
|
return isTraditional ? deletedTraditionalStyleQuoteNode : deletedStyleQuoteNode;
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
|
-
return isTraditional ? traditionalStyleQuoteNode : editingStyleQuoteNode;
|
|
47
|
+
return isTraditional ? isActive ? traditionalStyleQuoteNodeActive : traditionalStyleQuoteNode : editingStyleQuoteNode;
|
|
47
48
|
}
|
|
48
49
|
if (nodeName === 'rule') {
|
|
49
50
|
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
50
51
|
if (isInserted) {
|
|
51
|
-
return isTraditional ? traditionalStyleRuleNode : editingStyleRuleNode;
|
|
52
|
+
return isTraditional ? isActive ? traditionalStyleRuleNodeActive : traditionalStyleRuleNode : editingStyleRuleNode;
|
|
52
53
|
} else {
|
|
53
54
|
return isTraditional ? deletedTraditionalContentStyle : deletedContentStyleNew;
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
|
-
return isTraditional ? traditionalStyleRuleNode : editingStyleRuleNode;
|
|
57
|
+
return isTraditional ? isActive ? traditionalStyleRuleNodeActive : traditionalStyleRuleNode : editingStyleRuleNode;
|
|
57
58
|
}
|
|
58
59
|
if (nodeName === 'blockCard') {
|
|
59
60
|
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
60
61
|
if (isInserted) {
|
|
61
|
-
return isTraditional ? traditionalStyleCardBlockNode : editingStyleCardBlockNode;
|
|
62
|
+
return isTraditional ? isActive ? traditionalStyleCardBlockNodeActive : traditionalStyleCardBlockNode : editingStyleCardBlockNode;
|
|
62
63
|
} else {
|
|
63
64
|
return isTraditional ? deletedTraditionalContentStyle : deletedContentStyleNew;
|
|
64
65
|
}
|
|
65
66
|
}
|
|
66
|
-
return isTraditional ? traditionalStyleCardBlockNode : editingStyleCardBlockNode;
|
|
67
|
+
return isTraditional ? isActive ? traditionalStyleCardBlockNodeActive : traditionalStyleCardBlockNode : editingStyleCardBlockNode;
|
|
67
68
|
}
|
|
68
69
|
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
69
70
|
if (isInserted) {
|
|
70
|
-
return isTraditional ? traditionalStyleNode : editingStyleNode;
|
|
71
|
+
return isTraditional ? isActive ? traditionalStyleNodeActive : traditionalStyleNode : editingStyleNode;
|
|
71
72
|
} else {
|
|
72
73
|
return isTraditional ? deletedTraditionalContentStyle : deletedContentStyleNew;
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
|
-
return isTraditional ? traditionalStyleNode : editingStyleNode;
|
|
76
|
+
return isTraditional ? isActive ? traditionalStyleNodeActive : traditionalStyleNode : editingStyleNode;
|
|
76
77
|
};
|
|
77
78
|
|
|
78
79
|
/**
|
|
79
|
-
*
|
|
80
|
+
* Node decoration used for block-level insertions. When isActive, uses emphasised (pressed) styling.
|
|
80
81
|
*
|
|
81
|
-
* @param change
|
|
82
|
-
* @
|
|
82
|
+
* @param change Node range and name
|
|
83
|
+
* @param colorScheme Optional color scheme
|
|
84
|
+
* @param isActive Whether this node is part of the currently active/focused change
|
|
85
|
+
* @returns Prosemirror node decoration or undefined
|
|
83
86
|
*/
|
|
84
87
|
export const createBlockChangedDecoration = ({
|
|
85
88
|
change,
|
|
86
89
|
colorScheme,
|
|
87
|
-
isInserted = true
|
|
90
|
+
isInserted = true,
|
|
91
|
+
isActive = false
|
|
88
92
|
}) => {
|
|
89
93
|
let style = getBlockNodeStyle({
|
|
90
94
|
nodeName: change.name,
|
|
91
|
-
colorScheme
|
|
95
|
+
colorScheme,
|
|
96
|
+
isActive
|
|
92
97
|
});
|
|
93
98
|
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
94
99
|
style = getBlockNodeStyle({
|
|
95
100
|
nodeName: change.name,
|
|
96
101
|
colorScheme,
|
|
97
|
-
isInserted
|
|
102
|
+
isInserted,
|
|
103
|
+
isActive
|
|
98
104
|
});
|
|
99
105
|
}
|
|
100
106
|
const className = getNodeClass(change.name);
|
|
@@ -105,17 +111,19 @@ export const createBlockChangedDecoration = ({
|
|
|
105
111
|
'data-testid': 'show-diff-changed-decoration-node',
|
|
106
112
|
class: className
|
|
107
113
|
}, {
|
|
108
|
-
key: 'diff-block'
|
|
114
|
+
key: 'diff-block',
|
|
115
|
+
nodeName: change.name
|
|
109
116
|
});
|
|
117
|
+
} else {
|
|
118
|
+
return undefined;
|
|
110
119
|
}
|
|
111
|
-
return undefined;
|
|
112
|
-
} else {
|
|
113
|
-
return Decoration.node(change.from, change.to, {
|
|
114
|
-
style,
|
|
115
|
-
'data-testid': 'show-diff-changed-decoration-node',
|
|
116
|
-
class: className
|
|
117
|
-
}, {
|
|
118
|
-
key: 'diff-block'
|
|
119
|
-
});
|
|
120
120
|
}
|
|
121
|
+
return Decoration.node(change.from, change.to, {
|
|
122
|
+
style,
|
|
123
|
+
'data-testid': 'show-diff-changed-decoration-node',
|
|
124
|
+
class: className
|
|
125
|
+
}, {
|
|
126
|
+
key: 'diff-block',
|
|
127
|
+
nodeName: change.name
|
|
128
|
+
});
|
|
121
129
|
};
|
|
@@ -2,11 +2,16 @@ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
|
2
2
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
3
3
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
4
4
|
import { editingStyle, editingStyleActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleNewActive, deletedContentStyleUnbounded } from './colorSchemes/standard';
|
|
5
|
-
import { traditionalInsertStyle, traditionalInsertStyleActive, deletedTraditionalContentStyle, deletedTraditionalContentStyleUnbounded } from './colorSchemes/traditional';
|
|
5
|
+
import { traditionalInsertStyle, traditionalInsertStyleActive, deletedTraditionalContentStyle, deletedTraditionalContentStyleActive, deletedTraditionalContentStyleUnbounded, deletedTraditionalContentStyleUnboundedActive } from './colorSchemes/traditional';
|
|
6
6
|
import { createChangedRowDecorationWidgets } from './createChangedRowDecorationWidgets';
|
|
7
7
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
8
8
|
import { wrapBlockNodeView } from './utils/wrapBlockNodeView';
|
|
9
|
-
const getDeletedContentStyleUnbounded = colorScheme
|
|
9
|
+
const getDeletedContentStyleUnbounded = (colorScheme, isActive = false) => {
|
|
10
|
+
if (colorScheme === 'traditional' && isActive) {
|
|
11
|
+
return deletedTraditionalContentStyleUnboundedActive;
|
|
12
|
+
}
|
|
13
|
+
return colorScheme === 'traditional' ? deletedTraditionalContentStyleUnbounded : deletedContentStyleUnbounded;
|
|
14
|
+
};
|
|
10
15
|
const getInsertedContentStyle = (colorScheme, isActive = false) => {
|
|
11
16
|
if (colorScheme === 'traditional') {
|
|
12
17
|
if (isActive) {
|
|
@@ -21,7 +26,7 @@ const getInsertedContentStyle = (colorScheme, isActive = false) => {
|
|
|
21
26
|
};
|
|
22
27
|
const getDeletedContentStyle = (colorScheme, isActive = false) => {
|
|
23
28
|
if (colorScheme === 'traditional') {
|
|
24
|
-
return deletedTraditionalContentStyle;
|
|
29
|
+
return isActive ? deletedTraditionalContentStyleActive : deletedTraditionalContentStyle;
|
|
25
30
|
}
|
|
26
31
|
if (isActive) {
|
|
27
32
|
return expValEquals('platform_editor_enghealth_a11y_jan_fixes', 'isEnabled', true) ? deletedContentStyleNewActive : deletedContentStyleActive;
|
|
@@ -229,7 +234,9 @@ export const createNodeChangedDecorationWidget = ({
|
|
|
229
234
|
// Widget decoration used for deletions as the content is not in the document
|
|
230
235
|
// and we want to display the deleted content with a style.
|
|
231
236
|
const safeInsertPos = findSafeInsertPos(newDoc, change.fromB, slice);
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
237
|
+
const decorations = [];
|
|
238
|
+
decorations.push(Decoration.widget(safeInsertPos, dom, {
|
|
239
|
+
key: `diff-widget-${isActive ? 'active' : 'inactive'}`
|
|
240
|
+
}));
|
|
241
|
+
return decorations;
|
|
235
242
|
};
|
|
@@ -11,7 +11,23 @@ import { scrollToActiveDecoration } from './scrollToActiveDecoration';
|
|
|
11
11
|
export const showDiffPluginKey = new PluginKey('showDiffPlugin');
|
|
12
12
|
export const getScrollableDecorations = set => {
|
|
13
13
|
var _set$find;
|
|
14
|
-
|
|
14
|
+
const seenBlockKeys = new Set();
|
|
15
|
+
return ((_set$find = set === null || set === void 0 ? void 0 : set.find(undefined, undefined, spec => {
|
|
16
|
+
var _spec$key;
|
|
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';
|
|
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);
|
|
15
31
|
};
|
|
16
32
|
export const createPlugin = (config, getIntl, api) => {
|
|
17
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';
|
|
@@ -25,19 +27,23 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
|
|
|
25
27
|
to = _ref.to,
|
|
26
28
|
colorScheme = _ref.colorScheme,
|
|
27
29
|
_ref$isInserted = _ref.isInserted,
|
|
28
|
-
isInserted = _ref$isInserted === void 0 ? true : _ref$isInserted
|
|
30
|
+
isInserted = _ref$isInserted === void 0 ? true : _ref$isInserted,
|
|
31
|
+
activeIndexPos = _ref.activeIndexPos;
|
|
29
32
|
var decorations = [];
|
|
30
33
|
// Iterate over the document nodes within the range
|
|
31
34
|
doc.nodesBetween(from, to, function (node, pos) {
|
|
32
35
|
if (node.isBlock && (!expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) || pos + node.nodeSize <= to)) {
|
|
36
|
+
var nodeEnd = pos + node.nodeSize;
|
|
37
|
+
var isActive = activeIndexPos && pos === activeIndexPos.from && nodeEnd === activeIndexPos.to;
|
|
33
38
|
var decoration = createBlockChangedDecoration({
|
|
34
39
|
change: {
|
|
35
40
|
from: pos,
|
|
36
|
-
to:
|
|
41
|
+
to: nodeEnd,
|
|
37
42
|
name: node.type.name
|
|
38
43
|
},
|
|
39
44
|
colorScheme: colorScheme,
|
|
40
|
-
isInserted: isInserted
|
|
45
|
+
isInserted: isInserted,
|
|
46
|
+
isActive: isActive
|
|
41
47
|
});
|
|
42
48
|
if (decoration) {
|
|
43
49
|
decorations.push(decoration);
|
|
@@ -122,6 +128,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
122
128
|
_iterator.f();
|
|
123
129
|
}
|
|
124
130
|
if (!areNodesEqualIgnoreAttrs(steppedDoc, tr.doc)) {
|
|
131
|
+
var recoveredViaContentEquality = fg('platform_editor_show_diff_equality_fallback') ? areDocsEqualByBlockStructureAndText(steppedDoc, tr.doc) : undefined;
|
|
125
132
|
if (expValEquals('platform_editor_are_nodes_equal_ignore_mark_order', 'isEnabled', true)) {
|
|
126
133
|
var _api$analytics;
|
|
127
134
|
api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 || _api$analytics.actions.fireAnalyticsEvent({
|
|
@@ -130,18 +137,25 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
130
137
|
actionSubject: 'showDiff',
|
|
131
138
|
attributes: {
|
|
132
139
|
docSizeEqual: steppedDoc.nodeSize === tr.doc.nodeSize,
|
|
133
|
-
colorScheme: colorScheme
|
|
140
|
+
colorScheme: colorScheme,
|
|
141
|
+
recoveredViaContentEquality: recoveredViaContentEquality
|
|
134
142
|
}
|
|
135
143
|
});
|
|
136
144
|
}
|
|
137
|
-
|
|
145
|
+
if (fg('platform_editor_show_diff_equality_fallback')) {
|
|
146
|
+
if (!recoveredViaContentEquality) {
|
|
147
|
+
return DecorationSet.empty;
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
return DecorationSet.empty;
|
|
151
|
+
}
|
|
138
152
|
}
|
|
139
153
|
var changeset = ChangeSet.create(originalDoc).addSteps(steppedDoc, stepMaps, tr.doc);
|
|
140
154
|
var changes = simplifyChanges(changeset.changes, tr.doc);
|
|
141
155
|
var optimizedChanges = optimizeChanges(changes);
|
|
142
156
|
var decorations = [];
|
|
143
157
|
optimizedChanges.forEach(function (change) {
|
|
144
|
-
var isActive = activeIndexPos && change.fromB
|
|
158
|
+
var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
|
|
145
159
|
// Our default operations are insertions, so it should match the opposite of isInverted.
|
|
146
160
|
var isInserted = !isInverted;
|
|
147
161
|
if (change.inserted.length > 0) {
|
|
@@ -152,17 +166,20 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
152
166
|
}, expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) && {
|
|
153
167
|
isInserted: isInserted
|
|
154
168
|
})));
|
|
155
|
-
decorations.push.apply(decorations, _toConsumableArray(calculateNodesForBlockDecoration(_objectSpread({
|
|
169
|
+
decorations.push.apply(decorations, _toConsumableArray(calculateNodesForBlockDecoration(_objectSpread(_objectSpread({
|
|
156
170
|
doc: tr.doc,
|
|
157
171
|
from: change.fromB,
|
|
158
172
|
to: change.toB,
|
|
159
173
|
colorScheme: colorScheme
|
|
160
174
|
}, expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) && {
|
|
161
175
|
isInserted: isInserted
|
|
176
|
+
}), {}, {
|
|
177
|
+
activeIndexPos: activeIndexPos,
|
|
178
|
+
intl: intl
|
|
162
179
|
}))));
|
|
163
180
|
}
|
|
164
181
|
if (change.deleted.length > 0) {
|
|
165
|
-
var _isActive = activeIndexPos && change.fromB
|
|
182
|
+
var _isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.fromB === activeIndexPos.to;
|
|
166
183
|
var decoration = createNodeChangedDecorationWidget(_objectSpread({
|
|
167
184
|
change: change,
|
|
168
185
|
doc: originalDoc,
|
|
@@ -180,7 +197,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
180
197
|
}
|
|
181
198
|
});
|
|
182
199
|
getMarkChangeRanges(steps).forEach(function (change) {
|
|
183
|
-
var isActive = activeIndexPos && change.fromB
|
|
200
|
+
var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
|
|
184
201
|
decorations.push(createInlineChangedDecoration({
|
|
185
202
|
change: change,
|
|
186
203
|
colorScheme: colorScheme,
|
|
@@ -194,7 +211,9 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref2
|
|
|
194
211
|
from: change.fromB,
|
|
195
212
|
to: change.toB,
|
|
196
213
|
colorScheme: colorScheme,
|
|
197
|
-
isInserted: true
|
|
214
|
+
isInserted: true,
|
|
215
|
+
activeIndexPos: activeIndexPos,
|
|
216
|
+
intl: intl
|
|
198
217
|
})));
|
|
199
218
|
});
|
|
200
219
|
return DecorationSet.empty.add(tr.doc, decorations);
|
|
@@ -7,7 +7,7 @@ export var editingStyle = convertToInlineCss({
|
|
|
7
7
|
textDecorationColor: "var(--ds-border-accent-purple, #AF59E1)"
|
|
8
8
|
});
|
|
9
9
|
export var editingStyleActive = convertToInlineCss({
|
|
10
|
-
background: "var(--ds-background-accent-purple-subtler, #
|
|
10
|
+
background: "var(--ds-background-accent-purple-subtler-pressed, #D8A0F7)",
|
|
11
11
|
textDecoration: 'underline',
|
|
12
12
|
textDecorationStyle: 'dotted',
|
|
13
13
|
textDecorationThickness: "var(--ds-space-025, 2px)",
|
|
@@ -7,7 +7,7 @@ export var traditionalInsertStyle = convertToInlineCss({
|
|
|
7
7
|
textDecorationColor: "var(--ds-border-accent-green, #22A06B)"
|
|
8
8
|
});
|
|
9
9
|
export var traditionalInsertStyleActive = convertToInlineCss({
|
|
10
|
-
background: "var(--ds-background-accent-green-subtler, #
|
|
10
|
+
background: "var(--ds-background-accent-green-subtler-pressed, #7EE2B8)",
|
|
11
11
|
textDecoration: 'underline',
|
|
12
12
|
textDecorationStyle: 'solid',
|
|
13
13
|
textDecorationThickness: "var(--ds-space-025, 2px)",
|
|
@@ -19,6 +19,15 @@ export var deletedTraditionalContentStyle = convertToInlineCss({
|
|
|
19
19
|
position: 'relative',
|
|
20
20
|
opacity: 1
|
|
21
21
|
});
|
|
22
|
+
|
|
23
|
+
/** Emphasised (pressed) strikethrough for traditional removed text when active */
|
|
24
|
+
export var deletedTraditionalContentStyleActive = convertToInlineCss({
|
|
25
|
+
textDecorationColor: "var(--ds-text-accent-red, #AE2E24)",
|
|
26
|
+
textDecoration: 'line-through',
|
|
27
|
+
backgroundColor: "var(--ds-background-accent-red-subtlest-pressed, #FFB8B2)",
|
|
28
|
+
position: 'relative',
|
|
29
|
+
opacity: 1
|
|
30
|
+
});
|
|
22
31
|
export var deletedTraditionalContentStyleUnbounded = convertToInlineCss({
|
|
23
32
|
position: 'absolute',
|
|
24
33
|
top: '50%',
|
|
@@ -28,6 +37,17 @@ export var deletedTraditionalContentStyleUnbounded = convertToInlineCss({
|
|
|
28
37
|
pointerEvents: 'none',
|
|
29
38
|
zIndex: 1
|
|
30
39
|
});
|
|
40
|
+
|
|
41
|
+
/** Emphasised (pressed) strikethrough line for traditional when active */
|
|
42
|
+
export var deletedTraditionalContentStyleUnboundedActive = convertToInlineCss({
|
|
43
|
+
position: 'absolute',
|
|
44
|
+
top: '50%',
|
|
45
|
+
width: '100%',
|
|
46
|
+
display: 'inline-block',
|
|
47
|
+
borderTop: "1px solid ".concat("var(--ds-text-accent-red-bolder, #5D1F1A)"),
|
|
48
|
+
pointerEvents: 'none',
|
|
49
|
+
zIndex: 1
|
|
50
|
+
});
|
|
31
51
|
export var deletedTraditionalStyleQuoteNode = convertToInlineCss({
|
|
32
52
|
marginTop: "var(--ds-space-150, 12px)",
|
|
33
53
|
paddingTop: "var(--ds-space-025, 2px)",
|
|
@@ -53,20 +73,37 @@ export var deletedTraditionalRowStyle = convertToInlineCss({
|
|
|
53
73
|
export var traditionalStyleQuoteNode = convertToInlineCss({
|
|
54
74
|
borderLeft: "2px solid ".concat("var(--ds-border-accent-green, #22A06B)")
|
|
55
75
|
});
|
|
76
|
+
export var traditionalStyleQuoteNodeActive = convertToInlineCss({
|
|
77
|
+
borderLeft: "2px solid ".concat("var(--ds-background-accent-green-subtler-pressed, #7EE2B8)")
|
|
78
|
+
});
|
|
56
79
|
export var traditionalStyleRuleNode = convertToInlineCss({
|
|
57
80
|
backgroundColor: "var(--ds-border-accent-green, #22A06B)"
|
|
58
81
|
});
|
|
82
|
+
export var traditionalStyleRuleNodeActive = convertToInlineCss({
|
|
83
|
+
backgroundColor: "var(--ds-background-accent-green-subtler-pressed, #7EE2B8)"
|
|
84
|
+
});
|
|
59
85
|
export var traditionalStyleNode = convertToInlineCss({
|
|
60
86
|
boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-green, #22A06B)"),
|
|
61
87
|
borderRadius: "var(--ds-radius-small, 4px)"
|
|
62
88
|
});
|
|
89
|
+
export var traditionalStyleNodeActive = convertToInlineCss({
|
|
90
|
+
boxShadow: "0 0 0 2px ".concat("var(--ds-background-accent-green-subtler-pressed, #7EE2B8)"),
|
|
91
|
+
borderRadius: "var(--ds-radius-small, 4px)"
|
|
92
|
+
});
|
|
63
93
|
export var traditionalStyleCardBlockNode = convertToInlineCss({
|
|
64
94
|
boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-green, #22A06B)"),
|
|
65
95
|
borderRadius: "var(--ds-radius-medium, 6px)"
|
|
66
96
|
});
|
|
97
|
+
export var traditionalStyleCardBlockNodeActive = convertToInlineCss({
|
|
98
|
+
boxShadow: "0 0 0 1px ".concat("var(--ds-background-accent-green-subtler-pressed, #7EE2B8)"),
|
|
99
|
+
borderRadius: "var(--ds-radius-medium, 6px)"
|
|
100
|
+
});
|
|
67
101
|
export var traditionalDecorationMarkerVariable = convertToInlineCss({
|
|
68
102
|
'--diff-decoration-marker-color': "var(--ds-border-accent-green, #22A06B)"
|
|
69
103
|
});
|
|
104
|
+
export var traditionalDecorationMarkerVariableActive = convertToInlineCss({
|
|
105
|
+
'--diff-decoration-marker-color': "var(--ds-text-accent-green, #216E4E)"
|
|
106
|
+
});
|
|
70
107
|
export var traditionalAddedCellOverlayStyle = convertToInlineCss({
|
|
71
108
|
position: 'absolute',
|
|
72
109
|
top: 0,
|