@atlaskit/editor-plugin-show-diff 4.1.1 → 4.1.3

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.
@@ -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
  *
@@ -52,124 +25,6 @@ export const createInlineChangedDecoration = (change, colourScheme, isActive = f
52
25
  'data-testid': 'show-diff-changed-decoration'
53
26
  }, {});
54
27
  };
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
- }
94
- };
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
28
  export const getDeletedContentStyleUnbounded = colourScheme => colourScheme === 'traditional' ? deletedTraditionalContentStyleUnbounded : deletedContentStyleUnbounded;
174
29
  export const getDeletedContentStyle = (colourScheme, isActive = false) => {
175
30
  if (colourScheme === 'traditional') {
@@ -188,6 +43,9 @@ const getNodeClass = name => {
188
43
  return undefined;
189
44
  }
190
45
  };
46
+ const getBlockNodeStyle = (name, colourScheme) => {
47
+ return colourScheme === 'traditional' ? getTraditionalNodeStyle(name) : getStandardNodeStyle(name);
48
+ };
191
49
 
192
50
  /**
193
51
  * Inline decoration used for insertions as the content already exists in the document
@@ -196,10 +54,22 @@ const getNodeClass = name => {
196
54
  * @returns Prosemirror inline decoration
197
55
  */
198
56
  export const createBlockChangedDecoration = (change, colourScheme) => Decoration.node(change.from, change.to, {
199
- style: getEditorStyleNode(change.name, colourScheme),
57
+ style: getBlockNodeStyle(change.name, colourScheme),
200
58
  'data-testid': 'show-diff-changed-decoration-node',
201
59
  class: getNodeClass(change.name)
202
60
  }, {});
61
+ const createContentWrapper = (colourScheme, isActive = false) => {
62
+ const wrapper = document.createElement('span');
63
+ const baseStyle = convertToInlineCss({
64
+ position: 'relative',
65
+ width: 'fit-content'
66
+ });
67
+ wrapper.setAttribute('style', `${baseStyle}${getDeletedContentStyle(colourScheme, isActive)}`);
68
+ const strikethrough = document.createElement('span');
69
+ strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colourScheme));
70
+ wrapper.append(strikethrough);
71
+ return wrapper;
72
+ };
203
73
  export const createDeletedContentDecoration = ({
204
74
  change,
205
75
  doc,
@@ -238,20 +108,6 @@ export const createDeletedContentDecoration = ({
238
108
  * or sliced End depth is and match only the entire node.
239
109
  */
240
110
  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
111
  // Helper function to handle multiple child nodes
256
112
  const handleMultipleChildNodes = node => {
257
113
  if (node.content.childCount > 1 && node.type.inlineContent) {
@@ -259,16 +115,15 @@ export const createDeletedContentDecoration = ({
259
115
  const childNodeView = serializer.tryCreateNodeView(childNode);
260
116
  if (childNodeView) {
261
117
  const lineBreak = document.createElement('br');
262
- targetNode = node;
263
118
  dom.append(lineBreak);
264
- const wrapper = createWrapperWithStrikethrough();
119
+ const wrapper = createContentWrapper(colourScheme, isActive);
265
120
  wrapper.append(childNodeView);
266
121
  dom.append(wrapper);
267
122
  } else {
268
123
  // Fallback to serializing the individual child node
269
124
  const serializedChild = serializer.serializeNode(childNode);
270
125
  if (serializedChild) {
271
- const wrapper = createWrapperWithStrikethrough();
126
+ const wrapper = createContentWrapper(colourScheme, isActive);
272
127
  wrapper.append(serializedChild);
273
128
  dom.append(wrapper);
274
129
  }
@@ -283,19 +138,13 @@ export const createDeletedContentDecoration = ({
283
138
  const isFirst = slice.content.firstChild === node;
284
139
  const isLast = slice.content.lastChild === node;
285
140
  const hasInlineContent = node.content.childCount > 0 && node.type.inlineContent === true;
286
- let targetNode;
287
141
  let fallbackSerialization;
142
+ if (handleMultipleChildNodes(node)) {
143
+ return;
144
+ }
288
145
  if ((isFirst || isLast && slice.content.childCount > 2) && hasInlineContent) {
289
- if (handleMultipleChildNodes(node)) {
290
- return;
291
- }
292
- targetNode = node;
293
146
  fallbackSerialization = () => serializer.serializeFragment(node.content);
294
147
  } else if (isLast && slice.content.childCount === 2) {
295
- if (handleMultipleChildNodes(node)) {
296
- return;
297
- }
298
- targetNode = node;
299
148
  fallbackSerialization = () => {
300
149
  if (node.type.name === 'text') {
301
150
  return document.createTextNode(node.text || '');
@@ -308,25 +157,21 @@ export const createDeletedContentDecoration = ({
308
157
  return serializer.serializeFragment(node.content);
309
158
  };
310
159
  } else {
311
- if (handleMultipleChildNodes(node)) {
312
- return;
313
- }
314
- targetNode = node;
315
160
  fallbackSerialization = () => serializer.serializeNode(node);
316
161
  }
317
162
 
318
163
  // Try to create node view, fallback to serialization
319
- const nodeView = serializer.tryCreateNodeView(targetNode);
164
+ const nodeView = serializer.tryCreateNodeView(node);
320
165
  if (nodeView) {
321
- if (targetNode.isInline) {
322
- const wrapper = createWrapperWithStrikethrough();
166
+ if (node.isInline) {
167
+ const wrapper = createContentWrapper(colourScheme, isActive);
323
168
  wrapper.append(nodeView);
324
169
  dom.append(wrapper);
325
170
  } else {
326
171
  // Handle all block nodes with unified function
327
- handleBlockNodeView(dom, nodeView, targetNode, colourScheme, intl);
172
+ handleBlockNodeView(dom, nodeView, node, colourScheme, intl);
328
173
  }
329
- } else if (nodeViewSerializer.getFilteredNodeViewBlocklist(['paragraph', 'tableRow']).has(targetNode.type.name)) {
174
+ } else if (nodeViewSerializer.getFilteredNodeViewBlocklist(['paragraph', 'tableRow']).has(node.type.name)) {
330
175
  // 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
176
  return;
332
177
  } else {
@@ -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
+ };
@@ -0,0 +1,70 @@
1
+ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
2
+ export var 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 var 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 var deletedTraditionalContentStyle = convertToInlineCss({
17
+ textDecorationColor: "var(--ds-border-accent-red, #E2483D)",
18
+ textDecoration: 'line-through',
19
+ position: 'relative',
20
+ opacity: 1
21
+ });
22
+ export var deletedTraditionalContentStyleUnbounded = convertToInlineCss({
23
+ position: 'absolute',
24
+ top: '50%',
25
+ width: '100%',
26
+ display: 'inline-block',
27
+ borderTop: "1px solid ".concat("var(--ds-border-accent-red, #E2483D)"),
28
+ pointerEvents: 'none',
29
+ zIndex: 1
30
+ });
31
+ var traditionalStyleQuoteNode = convertToInlineCss({
32
+ borderLeft: "2px solid ".concat("var(--ds-border-accent-green, #22A06B)")
33
+ });
34
+ var traditionalStyleRuleNode = convertToInlineCss({
35
+ backgroundColor: "var(--ds-border-accent-green, #22A06B)"
36
+ });
37
+ var traditionalStyleNode = convertToInlineCss({
38
+ boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-green, #22A06B)"),
39
+ borderRadius: "var(--ds-radius-small, 4px)"
40
+ });
41
+ var traditionalStyleCardBlockNode = convertToInlineCss({
42
+ boxShadow: "0 0 0 1px ".concat("var(--ds-border-accent-green, #22A06B)"),
43
+ borderRadius: "var(--ds-radius-medium, 6px)"
44
+ });
45
+ var traditionalDecorationMarkerVariable = convertToInlineCss({
46
+ '--diff-decoration-marker-color': "var(--ds-border-accent-green, #22A06B)"
47
+ });
48
+ export var getTraditionalNodeStyle = function 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
+ };