@atlaskit/editor-plugin-show-diff 4.1.2 → 4.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 (28) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/pm-plugins/calculateDiffDecorations.js +5 -2
  3. package/dist/cjs/pm-plugins/colorSchemes/standard.js +96 -0
  4. package/dist/cjs/pm-plugins/colorSchemes/traditional.js +76 -0
  5. package/dist/cjs/pm-plugins/decorations.js +62 -195
  6. package/dist/cjs/pm-plugins/main.js +9 -3
  7. package/dist/cjs/showDiffPlugin.js +2 -1
  8. package/dist/es2019/pm-plugins/calculateDiffDecorations.js +5 -2
  9. package/dist/es2019/pm-plugins/colorSchemes/standard.js +90 -0
  10. package/dist/es2019/pm-plugins/colorSchemes/traditional.js +70 -0
  11. package/dist/es2019/pm-plugins/decorations.js +57 -189
  12. package/dist/es2019/pm-plugins/main.js +6 -2
  13. package/dist/es2019/showDiffPlugin.js +3 -2
  14. package/dist/esm/pm-plugins/calculateDiffDecorations.js +5 -2
  15. package/dist/esm/pm-plugins/colorSchemes/standard.js +90 -0
  16. package/dist/esm/pm-plugins/colorSchemes/traditional.js +70 -0
  17. package/dist/esm/pm-plugins/decorations.js +56 -189
  18. package/dist/esm/pm-plugins/main.js +8 -2
  19. package/dist/esm/showDiffPlugin.js +3 -2
  20. package/dist/types/pm-plugins/colorSchemes/standard.d.ts +8 -0
  21. package/dist/types/pm-plugins/colorSchemes/traditional.d.ts +5 -0
  22. package/dist/types/pm-plugins/decorations.d.ts +1 -1
  23. package/dist/types/pm-plugins/main.d.ts +2 -0
  24. package/dist/types-ts4.5/pm-plugins/colorSchemes/standard.d.ts +8 -0
  25. package/dist/types-ts4.5/pm-plugins/colorSchemes/traditional.d.ts +5 -0
  26. package/dist/types-ts4.5/pm-plugins/decorations.d.ts +1 -1
  27. package/dist/types-ts4.5/pm-plugins/main.d.ts +2 -0
  28. package/package.json +4 -4
@@ -0,0 +1,90 @@
1
+ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
2
+ export const editingStyle = convertToInlineCss({
3
+ background: "var(--ds-background-accent-purple-subtlest, #F8EEFE)",
4
+ textDecoration: 'underline',
5
+ textDecorationStyle: 'dotted',
6
+ textDecorationThickness: "var(--ds-space-025, 2px)",
7
+ textDecorationColor: "var(--ds-border-accent-purple, #AF59E1)"
8
+ });
9
+ export const editingStyleActive = convertToInlineCss({
10
+ background: "var(--ds-background-accent-purple-subtler, #EED7FC)",
11
+ textDecoration: 'underline',
12
+ textDecorationStyle: 'dotted',
13
+ textDecorationThickness: "var(--ds-space-025, 2px)",
14
+ textDecorationColor: "var(--ds-text-accent-purple, #803FA5)"
15
+ });
16
+ export const deletedContentStyle = convertToInlineCss({
17
+ color: "var(--ds-text-accent-gray, #505258)",
18
+ textDecoration: 'line-through',
19
+ position: 'relative',
20
+ opacity: 0.6
21
+ });
22
+ export const deletedContentStyleActive = convertToInlineCss({
23
+ color: "var(--ds-text, #292A2E)",
24
+ textDecoration: 'line-through',
25
+ textDecorationColor: "var(--ds-text-accent-gray, #505258)",
26
+ position: 'relative',
27
+ opacity: 1
28
+ });
29
+ export const deletedContentStyleNew = convertToInlineCss({
30
+ color: "var(--ds-text-accent-gray, #505258)",
31
+ textDecoration: 'line-through',
32
+ position: 'relative',
33
+ opacity: 0.8
34
+ });
35
+ export const deletedContentStyleNewActive = convertToInlineCss({
36
+ color: "var(--ds-text, #292A2E)",
37
+ textDecoration: 'line-through',
38
+ textDecorationColor: "var(--ds-text-accent-gray, #505258)",
39
+ position: 'relative',
40
+ opacity: 1
41
+ });
42
+ export const deletedContentStyleUnbounded = convertToInlineCss({
43
+ position: 'absolute',
44
+ top: '50%',
45
+ width: '100%',
46
+ display: 'inline-block',
47
+ borderTop: `1px solid ${"var(--ds-text-accent-gray, #505258)"}`,
48
+ pointerEvents: 'none',
49
+ zIndex: 1
50
+ });
51
+ const editingStyleQuoteNode = convertToInlineCss({
52
+ borderLeft: `2px solid ${"var(--ds-border-accent-purple, #AF59E1)"}`
53
+ });
54
+ const editingStyleRuleNode = convertToInlineCss({
55
+ backgroundColor: "var(--ds-border-accent-purple, #AF59E1)"
56
+ });
57
+ const editingStyleNode = convertToInlineCss({
58
+ boxShadow: `0 0 0 1px ${"var(--ds-border-accent-purple, #AF59E1)"}`,
59
+ borderRadius: "var(--ds-radius-small, 4px)"
60
+ });
61
+ const editingStyleCardBlockNode = convertToInlineCss({
62
+ boxShadow: `0 0 0 1px ${"var(--ds-border-accent-purple, #AF59E1)"}`,
63
+ borderRadius: "var(--ds-radius-medium, 6px)"
64
+ });
65
+ const standardDecorationMarkerVariableName = convertToInlineCss({
66
+ '--diff-decoration-marker-color': "var(--ds-border-accent-purple, #AF59E1)"
67
+ });
68
+ export const getStandardNodeStyle = nodeName => {
69
+ if (['mediaSingle', 'mediaGroup', 'table',
70
+ // Handle table separately to avoid border issues
71
+ 'tableRow', 'tableCell', 'tableHeader', 'paragraph',
72
+ // Paragraph and heading nodes do not need special styling
73
+ 'heading', 'hardBreak', 'decisionList', 'taskList', 'taskItem', 'bulletList', 'orderedList', 'layoutSection'].includes(nodeName)) {
74
+ // Layout nodes do not need special styling
75
+ return undefined;
76
+ }
77
+ if (['extension', 'embedCard', 'listItem'].includes(nodeName)) {
78
+ return standardDecorationMarkerVariableName;
79
+ }
80
+ if (nodeName === 'blockquote') {
81
+ return editingStyleQuoteNode;
82
+ }
83
+ if (nodeName === 'rule') {
84
+ return editingStyleRuleNode;
85
+ }
86
+ if (nodeName === 'blockCard') {
87
+ return editingStyleCardBlockNode;
88
+ }
89
+ return editingStyleNode;
90
+ };
@@ -0,0 +1,70 @@
1
+ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
2
+ export const traditionalInsertStyle = convertToInlineCss({
3
+ background: "var(--ds-background-accent-green-subtlest, #DCFFF1)",
4
+ textDecoration: 'underline',
5
+ textDecorationStyle: 'solid',
6
+ textDecorationThickness: "var(--ds-space-025, 2px)",
7
+ textDecorationColor: "var(--ds-border-accent-green, #22A06B)"
8
+ });
9
+ export const traditionalInsertStyleActive = convertToInlineCss({
10
+ background: "var(--ds-background-accent-green-subtler, #BAF3DB)",
11
+ textDecoration: 'underline',
12
+ textDecorationStyle: 'solid',
13
+ textDecorationThickness: "var(--ds-space-025, 2px)",
14
+ textDecorationColor: "var(--ds-text-accent-green, #216E4E)"
15
+ });
16
+ export const deletedTraditionalContentStyle = convertToInlineCss({
17
+ textDecorationColor: "var(--ds-border-accent-red, #E2483D)",
18
+ textDecoration: 'line-through',
19
+ position: 'relative',
20
+ opacity: 1
21
+ });
22
+ export const deletedTraditionalContentStyleUnbounded = convertToInlineCss({
23
+ position: 'absolute',
24
+ top: '50%',
25
+ width: '100%',
26
+ display: 'inline-block',
27
+ borderTop: `1px solid ${"var(--ds-border-accent-red, #E2483D)"}`,
28
+ pointerEvents: 'none',
29
+ zIndex: 1
30
+ });
31
+ const traditionalStyleQuoteNode = convertToInlineCss({
32
+ borderLeft: `2px solid ${"var(--ds-border-accent-green, #22A06B)"}`
33
+ });
34
+ const traditionalStyleRuleNode = convertToInlineCss({
35
+ backgroundColor: "var(--ds-border-accent-green, #22A06B)"
36
+ });
37
+ const traditionalStyleNode = convertToInlineCss({
38
+ boxShadow: `0 0 0 1px ${"var(--ds-border-accent-green, #22A06B)"}`,
39
+ borderRadius: "var(--ds-radius-small, 4px)"
40
+ });
41
+ const traditionalStyleCardBlockNode = convertToInlineCss({
42
+ boxShadow: `0 0 0 1px ${"var(--ds-border-accent-green, #22A06B)"}`,
43
+ borderRadius: "var(--ds-radius-medium, 6px)"
44
+ });
45
+ const traditionalDecorationMarkerVariable = convertToInlineCss({
46
+ '--diff-decoration-marker-color': "var(--ds-border-accent-green, #22A06B)"
47
+ });
48
+ export const getTraditionalNodeStyle = nodeName => {
49
+ if (['mediaSingle', 'mediaGroup', 'table',
50
+ // Handle table separately to avoid border issues
51
+ 'tableRow', 'tableCell', 'tableHeader', 'paragraph',
52
+ // Paragraph and heading nodes do not need special styling
53
+ 'heading', 'hardBreak', 'decisionList', 'taskList', 'taskItem', 'bulletList', 'orderedList', 'layoutSection'].includes(nodeName)) {
54
+ // Layout nodes do not need special styling
55
+ return undefined;
56
+ }
57
+ if (['extension', 'embedCard', 'listItem'].includes(nodeName)) {
58
+ return traditionalDecorationMarkerVariable;
59
+ }
60
+ if (nodeName === 'blockquote') {
61
+ return traditionalStyleQuoteNode;
62
+ }
63
+ if (nodeName === 'rule') {
64
+ return traditionalStyleRuleNode;
65
+ }
66
+ if (nodeName === 'blockCard') {
67
+ return traditionalStyleCardBlockNode;
68
+ }
69
+ return traditionalStyleNode;
70
+ };
@@ -2,38 +2,11 @@ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
2
2
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
3
3
  import { fg } from '@atlaskit/platform-feature-flags';
4
4
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
5
+ import { getStandardNodeStyle, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleNewActive, editingStyle, editingStyleActive, deletedContentStyleUnbounded } from './colorSchemes/standard';
6
+ import { getTraditionalNodeStyle, deletedTraditionalContentStyle, deletedTraditionalContentStyleUnbounded, traditionalInsertStyle, traditionalInsertStyleActive } from './colorSchemes/traditional';
5
7
  import { createDeletedStyleWrapperWithoutOpacity, handleBlockNodeView } from './deletedBlocksHandler';
6
8
  import { handleDeletedRows } from './deletedRowsHandler';
7
9
  import { findSafeInsertPos } from './findSafeInsertPos';
8
- const editingStyle = convertToInlineCss({
9
- background: "var(--ds-background-accent-purple-subtlest, #F8EEFE)",
10
- textDecoration: 'underline',
11
- textDecorationStyle: 'dotted',
12
- textDecorationThickness: "var(--ds-space-025, 2px)",
13
- textDecorationColor: "var(--ds-border-accent-purple, #AF59E1)"
14
- });
15
- const editingStyleActive = convertToInlineCss({
16
- background: "var(--ds-background-accent-purple-subtler, #EED7FC)",
17
- textDecoration: 'underline',
18
- textDecorationStyle: 'dotted',
19
- textDecorationThickness: "var(--ds-space-025, 2px)",
20
- textDecorationColor: "var(--ds-text-accent-purple, #803FA5)"
21
- });
22
- const traditionalInsertStyle = convertToInlineCss({
23
- background: "var(--ds-background-accent-green-subtlest, #DCFFF1)",
24
- textDecoration: 'underline',
25
- textDecorationStyle: 'solid',
26
- textDecorationThickness: "var(--ds-space-025, 2px)",
27
- textDecorationColor: "var(--ds-border-accent-green, #22A06B)"
28
- });
29
- const traditionalInsertStyleActive = convertToInlineCss({
30
- background: "var(--ds-background-accent-green-subtler, #BAF3DB)",
31
- textDecoration: 'underline',
32
- textDecorationStyle: 'solid',
33
- textDecorationThickness: "var(--ds-space-025, 2px)",
34
- textDecorationColor: "var(--ds-text-accent-green, #216E4E)"
35
- });
36
-
37
10
  /**
38
11
  * Inline decoration used for insertions as the content already exists in the document
39
12
  *
@@ -50,126 +23,10 @@ export const createInlineChangedDecoration = (change, colourScheme, isActive = f
50
23
  return Decoration.inline(change.fromB, change.toB, {
51
24
  style,
52
25
  'data-testid': 'show-diff-changed-decoration'
53
- }, {});
54
- };
55
- const getEditorStyleNode = (nodeName, colourScheme) => {
56
- switch (nodeName) {
57
- case 'blockquote':
58
- return colourScheme === 'traditional' ? traditionalStyleQuoteNode : editingStyleQuoteNode;
59
- case 'mediaSingle':
60
- case 'mediaGroup':
61
- case 'table':
62
- case 'tableRow':
63
- case 'tableCell':
64
- case 'tableHeader':
65
- return undefined;
66
- // Handle table separately to avoid border issues
67
- case 'paragraph':
68
- case 'heading':
69
- case 'hardBreak':
70
- return undefined;
71
- // Paragraph and heading nodes do not need special styling
72
- case 'decisionList':
73
- case 'taskList':
74
- case 'taskItem':
75
- case 'bulletList':
76
- case 'orderedList':
77
- return undefined;
78
- case 'extension':
79
- case 'embedCard':
80
- case 'listItem':
81
- return convertToInlineCss({
82
- '--diff-decoration-marker-color': colourScheme === 'traditional' ? "var(--ds-border-accent-green, #22A06B)" : "var(--ds-border-accent-purple, #AF59E1)"
83
- });
84
- case 'layoutSection':
85
- return undefined;
86
- // Layout nodes do not need special styling
87
- case 'rule':
88
- return colourScheme === 'traditional' ? traditionalStyleRuleNode : editingStyleRuleNode;
89
- case 'blockCard':
90
- return colourScheme === 'traditional' ? traditionalStyleCardBlockNode : editingStyleCardBlockNode;
91
- default:
92
- return colourScheme === 'traditional' ? traditionalStyleNode : editingStyleNode;
93
- }
26
+ }, {
27
+ key: 'diff-inline'
28
+ });
94
29
  };
95
- const editingStyleQuoteNode = convertToInlineCss({
96
- borderLeft: `2px solid ${"var(--ds-border-accent-purple, #AF59E1)"}`
97
- });
98
- const traditionalStyleQuoteNode = convertToInlineCss({
99
- borderLeft: `2px solid ${"var(--ds-border-accent-green, #22A06B)"}`
100
- });
101
- const editingStyleRuleNode = convertToInlineCss({
102
- backgroundColor: "var(--ds-border-accent-purple, #AF59E1)"
103
- });
104
- const traditionalStyleRuleNode = convertToInlineCss({
105
- backgroundColor: "var(--ds-border-accent-green, #22A06B)"
106
- });
107
- const editingStyleNode = convertToInlineCss({
108
- boxShadow: `0 0 0 1px ${"var(--ds-border-accent-purple, #AF59E1)"}`,
109
- borderRadius: "var(--ds-radius-small, 4px)"
110
- });
111
- const traditionalStyleNode = convertToInlineCss({
112
- boxShadow: `0 0 0 1px ${"var(--ds-border-accent-green, #22A06B)"}`,
113
- borderRadius: "var(--ds-radius-small, 4px)"
114
- });
115
- const editingStyleCardBlockNode = convertToInlineCss({
116
- boxShadow: `0 0 0 1px ${"var(--ds-border-accent-purple, #AF59E1)"}`,
117
- borderRadius: "var(--ds-radius-medium, 6px)"
118
- });
119
- const traditionalStyleCardBlockNode = convertToInlineCss({
120
- boxShadow: `0 0 0 1px ${"var(--ds-border-accent-green, #22A06B)"}`,
121
- borderRadius: "var(--ds-radius-medium, 6px)"
122
- });
123
- const deletedContentStyle = convertToInlineCss({
124
- color: "var(--ds-text-accent-gray, #505258)",
125
- textDecoration: 'line-through',
126
- position: 'relative',
127
- opacity: 0.6
128
- });
129
- const deletedContentStyleActive = convertToInlineCss({
130
- color: "var(--ds-text, #292A2E)",
131
- textDecoration: 'line-through',
132
- textDecorationColor: "var(--ds-text-accent-gray, #505258)",
133
- position: 'relative',
134
- opacity: 1
135
- });
136
- const deletedContentStyleNew = convertToInlineCss({
137
- color: "var(--ds-text-accent-gray, #505258)",
138
- textDecoration: 'line-through',
139
- position: 'relative',
140
- opacity: 0.8
141
- });
142
- const deletedContentStyleNewActive = convertToInlineCss({
143
- color: "var(--ds-text, #292A2E)",
144
- textDecoration: 'line-through',
145
- textDecorationColor: "var(--ds-text-accent-gray, #505258)",
146
- position: 'relative',
147
- opacity: 1
148
- });
149
- const deletedContentStyleUnbounded = convertToInlineCss({
150
- position: 'absolute',
151
- top: '50%',
152
- width: '100%',
153
- display: 'inline-block',
154
- borderTop: `1px solid ${"var(--ds-text-accent-gray, #505258)"}`,
155
- pointerEvents: 'none',
156
- zIndex: 1
157
- });
158
- const deletedTraditionalContentStyle = convertToInlineCss({
159
- textDecorationColor: "var(--ds-border-accent-red, #E2483D)",
160
- textDecoration: 'line-through',
161
- position: 'relative',
162
- opacity: 1
163
- });
164
- const deletedTraditionalContentStyleUnbounded = convertToInlineCss({
165
- position: 'absolute',
166
- top: '50%',
167
- width: '100%',
168
- display: 'inline-block',
169
- borderTop: `1px solid ${"var(--ds-border-accent-red, #E2483D)"}`,
170
- pointerEvents: 'none',
171
- zIndex: 1
172
- });
173
30
  export const getDeletedContentStyleUnbounded = colourScheme => colourScheme === 'traditional' ? deletedTraditionalContentStyleUnbounded : deletedContentStyleUnbounded;
174
31
  export const getDeletedContentStyle = (colourScheme, isActive = false) => {
175
32
  if (colourScheme === 'traditional') {
@@ -188,6 +45,9 @@ const getNodeClass = name => {
188
45
  return undefined;
189
46
  }
190
47
  };
48
+ const getBlockNodeStyle = (name, colourScheme) => {
49
+ return colourScheme === 'traditional' ? getTraditionalNodeStyle(name) : getStandardNodeStyle(name);
50
+ };
191
51
 
192
52
  /**
193
53
  * Inline decoration used for insertions as the content already exists in the document
@@ -195,11 +55,42 @@ const getNodeClass = name => {
195
55
  * @param change Changeset "change" containing information about the change content + range
196
56
  * @returns Prosemirror inline decoration
197
57
  */
198
- export const createBlockChangedDecoration = (change, colourScheme) => Decoration.node(change.from, change.to, {
199
- style: getEditorStyleNode(change.name, colourScheme),
200
- 'data-testid': 'show-diff-changed-decoration-node',
201
- class: getNodeClass(change.name)
202
- }, {});
58
+ export const createBlockChangedDecoration = (change, colourScheme) => {
59
+ if (fg('platform_editor_show_diff_scroll_navigation')) {
60
+ const style = getBlockNodeStyle(change.name, colourScheme);
61
+ const className = getNodeClass(change.name);
62
+ if (style || className) {
63
+ return Decoration.node(change.from, change.to, {
64
+ style: style,
65
+ 'data-testid': 'show-diff-changed-decoration-node',
66
+ class: className
67
+ }, {
68
+ key: 'diff-block'
69
+ });
70
+ }
71
+ return undefined;
72
+ } else {
73
+ return Decoration.node(change.from, change.to, {
74
+ style: getBlockNodeStyle(change.name, colourScheme),
75
+ 'data-testid': 'show-diff-changed-decoration-node',
76
+ class: getNodeClass(change.name)
77
+ }, {
78
+ key: 'diff-block'
79
+ });
80
+ }
81
+ };
82
+ const createContentWrapper = (colourScheme, isActive = false) => {
83
+ const wrapper = document.createElement('span');
84
+ const baseStyle = convertToInlineCss({
85
+ position: 'relative',
86
+ width: 'fit-content'
87
+ });
88
+ wrapper.setAttribute('style', `${baseStyle}${getDeletedContentStyle(colourScheme, isActive)}`);
89
+ const strikethrough = document.createElement('span');
90
+ strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colourScheme));
91
+ wrapper.append(strikethrough);
92
+ return wrapper;
93
+ };
203
94
  export const createDeletedContentDecoration = ({
204
95
  change,
205
96
  doc,
@@ -238,20 +129,6 @@ export const createDeletedContentDecoration = ({
238
129
  * or sliced End depth is and match only the entire node.
239
130
  */
240
131
  slice.content.forEach(node => {
241
- // Create a wrapper for each node with strikethrough
242
- const createWrapperWithStrikethrough = () => {
243
- const wrapper = document.createElement('span');
244
- const baseStyle = convertToInlineCss({
245
- position: 'relative',
246
- width: 'fit-content'
247
- });
248
- wrapper.setAttribute('style', `${baseStyle}${getDeletedContentStyle(colourScheme, isActive)}`);
249
- const strikethrough = document.createElement('span');
250
- strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colourScheme));
251
- wrapper.append(strikethrough);
252
- return wrapper;
253
- };
254
-
255
132
  // Helper function to handle multiple child nodes
256
133
  const handleMultipleChildNodes = node => {
257
134
  if (node.content.childCount > 1 && node.type.inlineContent) {
@@ -259,16 +136,15 @@ export const createDeletedContentDecoration = ({
259
136
  const childNodeView = serializer.tryCreateNodeView(childNode);
260
137
  if (childNodeView) {
261
138
  const lineBreak = document.createElement('br');
262
- targetNode = node;
263
139
  dom.append(lineBreak);
264
- const wrapper = createWrapperWithStrikethrough();
140
+ const wrapper = createContentWrapper(colourScheme, isActive);
265
141
  wrapper.append(childNodeView);
266
142
  dom.append(wrapper);
267
143
  } else {
268
144
  // Fallback to serializing the individual child node
269
145
  const serializedChild = serializer.serializeNode(childNode);
270
146
  if (serializedChild) {
271
- const wrapper = createWrapperWithStrikethrough();
147
+ const wrapper = createContentWrapper(colourScheme, isActive);
272
148
  wrapper.append(serializedChild);
273
149
  dom.append(wrapper);
274
150
  }
@@ -283,19 +159,13 @@ export const createDeletedContentDecoration = ({
283
159
  const isFirst = slice.content.firstChild === node;
284
160
  const isLast = slice.content.lastChild === node;
285
161
  const hasInlineContent = node.content.childCount > 0 && node.type.inlineContent === true;
286
- let targetNode;
287
162
  let fallbackSerialization;
163
+ if (handleMultipleChildNodes(node)) {
164
+ return;
165
+ }
288
166
  if ((isFirst || isLast && slice.content.childCount > 2) && hasInlineContent) {
289
- if (handleMultipleChildNodes(node)) {
290
- return;
291
- }
292
- targetNode = node;
293
167
  fallbackSerialization = () => serializer.serializeFragment(node.content);
294
168
  } else if (isLast && slice.content.childCount === 2) {
295
- if (handleMultipleChildNodes(node)) {
296
- return;
297
- }
298
- targetNode = node;
299
169
  fallbackSerialization = () => {
300
170
  if (node.type.name === 'text') {
301
171
  return document.createTextNode(node.text || '');
@@ -308,25 +178,21 @@ export const createDeletedContentDecoration = ({
308
178
  return serializer.serializeFragment(node.content);
309
179
  };
310
180
  } else {
311
- if (handleMultipleChildNodes(node)) {
312
- return;
313
- }
314
- targetNode = node;
315
181
  fallbackSerialization = () => serializer.serializeNode(node);
316
182
  }
317
183
 
318
184
  // Try to create node view, fallback to serialization
319
- const nodeView = serializer.tryCreateNodeView(targetNode);
185
+ const nodeView = serializer.tryCreateNodeView(node);
320
186
  if (nodeView) {
321
- if (targetNode.isInline) {
322
- const wrapper = createWrapperWithStrikethrough();
187
+ if (node.isInline) {
188
+ const wrapper = createContentWrapper(colourScheme, isActive);
323
189
  wrapper.append(nodeView);
324
190
  dom.append(wrapper);
325
191
  } else {
326
192
  // Handle all block nodes with unified function
327
- handleBlockNodeView(dom, nodeView, targetNode, colourScheme, intl);
193
+ handleBlockNodeView(dom, nodeView, node, colourScheme, intl);
328
194
  }
329
- } else if (nodeViewSerializer.getFilteredNodeViewBlocklist(['paragraph', 'tableRow']).has(targetNode.type.name)) {
195
+ } else if (nodeViewSerializer.getFilteredNodeViewBlocklist(['paragraph', 'tableRow']).has(node.type.name)) {
330
196
  // Skip the case where the node is a paragraph or table row that way it can still be rendered and delete the entire table
331
197
  return;
332
198
  } else {
@@ -343,5 +209,7 @@ export const createDeletedContentDecoration = ({
343
209
  // Widget decoration used for deletions as the content is not in the document
344
210
  // and we want to display the deleted content with a style.
345
211
  const safeInsertPos = findSafeInsertPos(newDoc, change.fromB, slice);
346
- return [Decoration.widget(safeInsertPos, dom)];
212
+ return [Decoration.widget(safeInsertPos, dom, {
213
+ key: 'diff-widget'
214
+ })];
347
215
  };
@@ -7,6 +7,10 @@ import { fg } from '@atlaskit/platform-feature-flags';
7
7
  import { calculateDiffDecorations } from './calculateDiffDecorations';
8
8
  import { NodeViewSerializer } from './NodeViewSerializer';
9
9
  export const showDiffPluginKey = new PluginKey('showDiffPlugin');
10
+ export const getScrollableDecorations = set => {
11
+ var _set$find;
12
+ 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 : [];
13
+ };
10
14
  export const createPlugin = (config, getIntl) => {
11
15
  const nodeViewSerializer = new NodeViewSerializer({});
12
16
  const setNodeViewSerializer = editorView => {
@@ -33,7 +37,7 @@ export const createPlugin = (config, getIntl) => {
33
37
  if (!pluginState || pluginState.decorations.find().length === 0) {
34
38
  return;
35
39
  }
36
- const decorations = pluginState.decorations.find();
40
+ const decorations = getScrollableDecorations(pluginState.decorations);
37
41
  const decoration = decorations[(_pluginState$activeIn = pluginState.activeIndex) !== null && _pluginState$activeIn !== void 0 ? _pluginState$activeIn : 0];
38
42
  if (!decoration) {
39
43
  return;
@@ -95,7 +99,7 @@ export const createPlugin = (config, getIntl) => {
95
99
  };
96
100
  } else if (((meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_NEXT' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_PREVIOUS') && fg('platform_editor_show_diff_scroll_navigation')) {
97
101
  // Update the active index in plugin state and recalculate decorations
98
- const decorations = currentPluginState.decorations.find();
102
+ const decorations = getScrollableDecorations(currentPluginState.decorations);
99
103
  if (decorations.length > 0) {
100
104
  var _currentPluginState$a;
101
105
  let nextIndex = (_currentPluginState$a = currentPluginState.activeIndex) !== null && _currentPluginState$a !== void 0 ? _currentPluginState$a : 0;
@@ -1,4 +1,5 @@
1
- import { createPlugin, showDiffPluginKey } from './pm-plugins/main';
1
+ import { fg } from '@atlaskit/platform-feature-flags';
2
+ import { createPlugin, showDiffPluginKey, getScrollableDecorations } from './pm-plugins/main';
2
3
  export const showDiffPlugin = ({
3
4
  api: _api,
4
5
  config
@@ -53,7 +54,7 @@ export const showDiffPlugin = ({
53
54
  };
54
55
  }
55
56
  const pluginState = showDiffPluginKey.getState(editorState);
56
- const decorationCount = (pluginState === null || pluginState === void 0 ? void 0 : (_pluginState$decorati = pluginState.decorations) === null || _pluginState$decorati === void 0 ? void 0 : _pluginState$decorati.find()) || [];
57
+ const decorationCount = fg('platform_editor_show_diff_scroll_navigation') ? getScrollableDecorations(pluginState === null || pluginState === void 0 ? void 0 : pluginState.decorations) : (pluginState === null || pluginState === void 0 ? void 0 : (_pluginState$decorati = pluginState.decorations) === null || _pluginState$decorati === void 0 ? void 0 : _pluginState$decorati.find()) || [];
57
58
  return {
58
59
  isDisplayingChanges: decorationCount.length > 0,
59
60
  activeIndex: pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex,
@@ -21,11 +21,14 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
21
21
  // Iterate over the document nodes within the range
22
22
  doc.nodesBetween(from, to, function (node, pos) {
23
23
  if (node.isBlock) {
24
- decorations.push(createBlockChangedDecoration({
24
+ var decoration = createBlockChangedDecoration({
25
25
  from: pos,
26
26
  to: pos + node.nodeSize,
27
27
  name: node.type.name
28
- }, colourScheme));
28
+ }, colourScheme);
29
+ if (decoration) {
30
+ decorations.push(decoration);
31
+ }
29
32
  }
30
33
  });
31
34
  return decorations;
@@ -0,0 +1,90 @@
1
+ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
2
+ export var editingStyle = convertToInlineCss({
3
+ background: "var(--ds-background-accent-purple-subtlest, #F8EEFE)",
4
+ textDecoration: 'underline',
5
+ textDecorationStyle: 'dotted',
6
+ textDecorationThickness: "var(--ds-space-025, 2px)",
7
+ textDecorationColor: "var(--ds-border-accent-purple, #AF59E1)"
8
+ });
9
+ export var editingStyleActive = convertToInlineCss({
10
+ background: "var(--ds-background-accent-purple-subtler, #EED7FC)",
11
+ textDecoration: 'underline',
12
+ textDecorationStyle: 'dotted',
13
+ textDecorationThickness: "var(--ds-space-025, 2px)",
14
+ textDecorationColor: "var(--ds-text-accent-purple, #803FA5)"
15
+ });
16
+ export var deletedContentStyle = convertToInlineCss({
17
+ color: "var(--ds-text-accent-gray, #505258)",
18
+ textDecoration: 'line-through',
19
+ position: 'relative',
20
+ opacity: 0.6
21
+ });
22
+ export var deletedContentStyleActive = convertToInlineCss({
23
+ color: "var(--ds-text, #292A2E)",
24
+ textDecoration: 'line-through',
25
+ textDecorationColor: "var(--ds-text-accent-gray, #505258)",
26
+ position: 'relative',
27
+ opacity: 1
28
+ });
29
+ export var deletedContentStyleNew = convertToInlineCss({
30
+ color: "var(--ds-text-accent-gray, #505258)",
31
+ textDecoration: 'line-through',
32
+ position: 'relative',
33
+ opacity: 0.8
34
+ });
35
+ export var deletedContentStyleNewActive = convertToInlineCss({
36
+ color: "var(--ds-text, #292A2E)",
37
+ textDecoration: 'line-through',
38
+ textDecorationColor: "var(--ds-text-accent-gray, #505258)",
39
+ position: 'relative',
40
+ opacity: 1
41
+ });
42
+ export var deletedContentStyleUnbounded = convertToInlineCss({
43
+ position: 'absolute',
44
+ top: '50%',
45
+ width: '100%',
46
+ display: 'inline-block',
47
+ borderTop: "1px solid ".concat("var(--ds-text-accent-gray, #505258)"),
48
+ pointerEvents: 'none',
49
+ zIndex: 1
50
+ });
51
+ var editingStyleQuoteNode = convertToInlineCss({
52
+ borderLeft: "2px solid ".concat("var(--ds-border-accent-purple, #AF59E1)")
53
+ });
54
+ var editingStyleRuleNode = convertToInlineCss({
55
+ backgroundColor: "var(--ds-border-accent-purple, #AF59E1)"
56
+ });
57
+ var editingStyleNode = convertToInlineCss({
58
+ boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-purple, #AF59E1)"),
59
+ borderRadius: "var(--ds-radius-small, 4px)"
60
+ });
61
+ var editingStyleCardBlockNode = convertToInlineCss({
62
+ boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-purple, #AF59E1)"),
63
+ borderRadius: "var(--ds-radius-medium, 6px)"
64
+ });
65
+ var standardDecorationMarkerVariableName = convertToInlineCss({
66
+ '--diff-decoration-marker-color': "var(--ds-border-accent-purple, #AF59E1)"
67
+ });
68
+ export var getStandardNodeStyle = function getStandardNodeStyle(nodeName) {
69
+ if (['mediaSingle', 'mediaGroup', 'table',
70
+ // Handle table separately to avoid border issues
71
+ 'tableRow', 'tableCell', 'tableHeader', 'paragraph',
72
+ // Paragraph and heading nodes do not need special styling
73
+ 'heading', 'hardBreak', 'decisionList', 'taskList', 'taskItem', 'bulletList', 'orderedList', 'layoutSection'].includes(nodeName)) {
74
+ // Layout nodes do not need special styling
75
+ return undefined;
76
+ }
77
+ if (['extension', 'embedCard', 'listItem'].includes(nodeName)) {
78
+ return standardDecorationMarkerVariableName;
79
+ }
80
+ if (nodeName === 'blockquote') {
81
+ return editingStyleQuoteNode;
82
+ }
83
+ if (nodeName === 'rule') {
84
+ return editingStyleRuleNode;
85
+ }
86
+ if (nodeName === 'blockCard') {
87
+ return editingStyleCardBlockNode;
88
+ }
89
+ return editingStyleNode;
90
+ };