@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.
Files changed (31) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/pm-plugins/areDocsEqualByBlockStructureAndText.js +29 -0
  3. package/dist/cjs/pm-plugins/calculateDiffDecorations.js +29 -10
  4. package/dist/cjs/pm-plugins/decorations/colorSchemes/standard.js +1 -1
  5. package/dist/cjs/pm-plugins/decorations/colorSchemes/traditional.js +39 -2
  6. package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +37 -27
  7. package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +10 -4
  8. package/dist/cjs/pm-plugins/main.js +19 -3
  9. package/dist/es2019/pm-plugins/areDocsEqualByBlockStructureAndText.js +23 -0
  10. package/dist/es2019/pm-plugins/calculateDiffDecorations.js +28 -10
  11. package/dist/es2019/pm-plugins/decorations/colorSchemes/standard.js +1 -1
  12. package/dist/es2019/pm-plugins/decorations/colorSchemes/traditional.js +38 -1
  13. package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +36 -28
  14. package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +13 -6
  15. package/dist/es2019/pm-plugins/main.js +17 -1
  16. package/dist/esm/pm-plugins/areDocsEqualByBlockStructureAndText.js +23 -0
  17. package/dist/esm/pm-plugins/calculateDiffDecorations.js +29 -10
  18. package/dist/esm/pm-plugins/decorations/colorSchemes/standard.js +1 -1
  19. package/dist/esm/pm-plugins/decorations/colorSchemes/traditional.js +38 -1
  20. package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +38 -28
  21. package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +11 -5
  22. package/dist/esm/pm-plugins/main.js +19 -3
  23. package/dist/types/pm-plugins/areDocsEqualByBlockStructureAndText.d.ts +7 -0
  24. package/dist/types/pm-plugins/decorations/colorSchemes/traditional.d.ts +9 -0
  25. package/dist/types/pm-plugins/decorations/createBlockChangedDecoration.d.ts +8 -5
  26. package/dist/types/pm-plugins/decorations/createNodeChangedDecorationWidget.d.ts +1 -1
  27. package/dist/types-ts4.5/pm-plugins/areDocsEqualByBlockStructureAndText.d.ts +7 -0
  28. package/dist/types-ts4.5/pm-plugins/decorations/colorSchemes/traditional.d.ts +9 -0
  29. package/dist/types-ts4.5/pm-plugins/decorations/createBlockChangedDecoration.d.ts +8 -5
  30. package/dist/types-ts4.5/pm-plugins/decorations/createNodeChangedDecorationWidget.d.ts +1 -1
  31. 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, #BAF3DB)",
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
- * Inline decoration used for insertions as the content already exists in the document
80
+ * Node decoration used for block-level insertions. When isActive, uses emphasised (pressed) styling.
80
81
  *
81
- * @param change Changeset "change" containing information about the change content + range
82
- * @returns Prosemirror inline decoration
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 => colorScheme === 'traditional' ? deletedTraditionalContentStyleUnbounded : deletedContentStyleUnbounded;
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
- return [Decoration.widget(safeInsertPos, dom, {
233
- key: 'diff-widget'
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
- return (_set$find = set === null || set === void 0 ? void 0 : set.find(undefined, undefined, spec => spec.key === 'diff-inline' || spec.key === 'diff-widget' || spec.key === 'diff-block')) !== null && _set$find !== void 0 ? _set$find : [];
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: pos + node.nodeSize,
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
- return DecorationSet.empty;
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 >= activeIndexPos.from && change.toB <= activeIndexPos.to;
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 >= activeIndexPos.from && change.toB <= activeIndexPos.to;
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 >= activeIndexPos.from && change.toB <= activeIndexPos.to;
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, #EED7FC)",
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, #BAF3DB)",
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,