@atlaskit/editor-plugin-show-diff 13.0.10 → 13.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/afm-cc/tsconfig.json +3 -0
  3. package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +259 -23
  4. package/dist/cjs/pm-plugins/decorations/colorSchemes/schemes.js +21 -5
  5. package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +87 -105
  6. package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.styles.legacy.js +124 -0
  7. package/dist/cjs/pm-plugins/decorations/createChangedRowDecorationWidgets.js +15 -12
  8. package/dist/cjs/pm-plugins/decorations/createChangedRowDecorationWidgets.styles.legacy.js +37 -0
  9. package/dist/cjs/pm-plugins/decorations/createInlineChangedDecoration.js +109 -59
  10. package/dist/cjs/pm-plugins/decorations/createInlineChangedDecoration.styles.legacy.js +67 -0
  11. package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +30 -168
  12. package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +205 -0
  13. package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +225 -0
  14. package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +247 -23
  15. package/dist/es2019/pm-plugins/decorations/colorSchemes/schemes.js +20 -4
  16. package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +85 -105
  17. package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.styles.legacy.js +118 -0
  18. package/dist/es2019/pm-plugins/decorations/createChangedRowDecorationWidgets.js +15 -12
  19. package/dist/es2019/pm-plugins/decorations/createChangedRowDecorationWidgets.styles.legacy.js +33 -0
  20. package/dist/es2019/pm-plugins/decorations/createInlineChangedDecoration.js +82 -37
  21. package/dist/es2019/pm-plugins/decorations/createInlineChangedDecoration.styles.legacy.js +62 -0
  22. package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +15 -140
  23. package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +143 -0
  24. package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +200 -0
  25. package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +248 -23
  26. package/dist/esm/pm-plugins/decorations/colorSchemes/schemes.js +20 -4
  27. package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +87 -105
  28. package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.styles.legacy.js +118 -0
  29. package/dist/esm/pm-plugins/decorations/createChangedRowDecorationWidgets.js +15 -12
  30. package/dist/esm/pm-plugins/decorations/createChangedRowDecorationWidgets.styles.legacy.js +32 -0
  31. package/dist/esm/pm-plugins/decorations/createInlineChangedDecoration.js +109 -59
  32. package/dist/esm/pm-plugins/decorations/createInlineChangedDecoration.styles.legacy.js +61 -0
  33. package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +15 -153
  34. package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +198 -0
  35. package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +218 -0
  36. package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +78 -6
  37. package/dist/types/pm-plugins/decorations/colorSchemes/schemes.d.ts +3 -0
  38. package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +13 -3
  39. package/dist/types/pm-plugins/decorations/createBlockChangedDecoration.styles.legacy.d.ts +14 -0
  40. package/dist/types/pm-plugins/decorations/createChangedRowDecorationWidgets.styles.legacy.d.ts +22 -0
  41. package/dist/types/pm-plugins/decorations/createInlineChangedDecoration.styles.legacy.d.ts +26 -0
  42. package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.d.ts +39 -0
  43. package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.d.ts +40 -0
  44. package/package.json +3 -2
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Pre-refactor code preserved for the OFF cohort of
3
+ * `platform_editor_show_diff_color_scheme_refactor`.
4
+ *
5
+ * This is a verbatim copy of the `getBlockNodeStyle` and the cell-overlay style selection that
6
+ * lived in `createBlockChangedDecoration.ts` before the `colorSchemeRegistry` + `factory.ts`
7
+ * migration. Do not modify it — it exists so the OFF cohort keeps the exact pre-refactor style
8
+ * strings. Delete this file at cleanup, together with `colorSchemes/standard.ts`,
9
+ * `colorSchemes/traditional.ts` (EDITOR-8281).
10
+ */
11
+ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
12
+ import { isExtendedEnabled } from '../isExtendedEnabled';
13
+ import { standardDecorationMarkerVariable, deletedDecorationMarkerVariable, editingStyleQuoteNode, editingStyleRuleNode, editingStyleCardBlockNode, editingStyleNode, deletedContentStyleNew, deletedStyleQuoteNode, addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from './colorSchemes/standard';
14
+ import { traditionalDecorationMarkerVariableActive, traditionalDecorationMarkerVariableNew, traditionalDeletedDecorationMarkerVariableActive, traditionalDeletedDecorationMarkerVariableNew, traditionalStyleQuoteNodeActive, traditionalStyleQuoteNodeNew, traditionalStyleRuleNodeActive, traditionalStyleRuleNodeNew, traditionalStyleCardBlockNodeActive, traditionalStyleCardBlockNodeNew, traditionalStyleNodeActive, traditionalStyleNodeNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, traditionalAddedCellOverlayStyle, traditionalAddedCellOverlayRoundedStyle, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle } from './colorSchemes/traditional';
15
+
16
+ /** Verbatim copy of the pre-refactor cell-overlay style selection. */
17
+ export const resolveCellOverlayStyleLegacy = ({
18
+ colorScheme,
19
+ isRoundedTable,
20
+ useAddedStyle
21
+ }) => {
22
+ const isTraditional = colorScheme === 'traditional';
23
+ const addedCellStyle = isTraditional ? isRoundedTable ? traditionalAddedCellOverlayRoundedStyle : traditionalAddedCellOverlayStyle : isRoundedTable ? addedCellOverlayRoundedStyle : addedCellOverlayStyle;
24
+ const deletedCellStyle = isTraditional ? isRoundedTable ? deletedTraditionalCellOverlayRoundedStyle : deletedTraditionalCellOverlayStyle : isRoundedTable ? deletedCellOverlayRoundedStyle : deletedCellOverlayStyle;
25
+ return useAddedStyle ? addedCellStyle : deletedCellStyle;
26
+ };
27
+ export const getBlockNodeStyleLegacy = ({
28
+ nodeName,
29
+ colorScheme,
30
+ isInserted = true,
31
+ isActive = false,
32
+ diffType
33
+ }) => {
34
+ const isTraditional = colorScheme === 'traditional';
35
+ if (['mediaSingle', 'mediaGroup', 'table',
36
+ // Handle table separately to avoid border issues
37
+ 'tableRow', 'paragraph',
38
+ // Paragraph and heading nodes do not need special styling
39
+ 'heading', 'hardBreak', 'decisionList', 'taskList', 'bulletList', 'orderedList', 'layoutSection'].includes(nodeName)) {
40
+ // Layout nodes do not need special styling
41
+ return undefined;
42
+ }
43
+ // Media nodes inside mediaSingle should not get position:relative
44
+ // as it shifts the image outside its parent container (e.g. panel)
45
+ if (nodeName === 'media') {
46
+ if (!isInserted && isExtendedEnabled(diffType)) {
47
+ return isTraditional ? getDeletedTraditionalInlineStyle(false) : deletedDecorationMarkerVariable;
48
+ }
49
+ return isTraditional ? isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew : editingStyleNode;
50
+ }
51
+ if (['tableCell', 'tableHeader'].includes(nodeName)) {
52
+ if (isExtendedEnabled(diffType)) {
53
+ // This is used for positioning the cell overlay widget decorations
54
+ return convertToInlineCss({
55
+ position: 'relative'
56
+ });
57
+ }
58
+ // When gate is off, it should return undefined as above
59
+ return undefined;
60
+ }
61
+ if (nodeName === 'panel') {
62
+ if (!isInserted && isExtendedEnabled(diffType)) {
63
+ return isTraditional ? getDeletedTraditionalInlineStyle(false) : deletedDecorationMarkerVariable;
64
+ }
65
+ return isTraditional ? isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew : editingStyleNode;
66
+ }
67
+ if (['extension', 'embedCard', 'listItem'].includes(nodeName)) {
68
+ if (isExtendedEnabled(diffType)) {
69
+ if (isInserted) {
70
+ return isTraditional && isActive ? traditionalDecorationMarkerVariableActive : isTraditional ? traditionalDecorationMarkerVariableNew : standardDecorationMarkerVariable;
71
+ } else {
72
+ if (nodeName === 'listItem') {
73
+ return isTraditional && isActive ? traditionalDeletedDecorationMarkerVariableActive : isTraditional ? traditionalDeletedDecorationMarkerVariableNew : deletedDecorationMarkerVariable;
74
+ }
75
+ return isTraditional && isActive ? traditionalDeletedDecorationMarkerVariableActive : isTraditional ? traditionalDeletedDecorationMarkerVariableNew : deletedContentStyleNew;
76
+ }
77
+ }
78
+ return isTraditional && isActive ? traditionalDecorationMarkerVariableActive : isTraditional ? traditionalDecorationMarkerVariableNew : standardDecorationMarkerVariable;
79
+ }
80
+ if (nodeName === 'blockquote') {
81
+ if (isExtendedEnabled(diffType)) {
82
+ if (isInserted) {
83
+ return isTraditional ? isActive ? traditionalStyleQuoteNodeActive : traditionalStyleQuoteNodeNew : editingStyleQuoteNode;
84
+ } else {
85
+ return isTraditional ? deletedTraditionalStyleQuoteNode : deletedStyleQuoteNode;
86
+ }
87
+ }
88
+ return isTraditional ? isActive ? traditionalStyleQuoteNodeActive : traditionalStyleQuoteNodeNew : editingStyleQuoteNode;
89
+ }
90
+ if (nodeName === 'rule') {
91
+ if (isExtendedEnabled(diffType)) {
92
+ if (isInserted) {
93
+ return isTraditional ? isActive ? traditionalStyleRuleNodeActive : traditionalStyleRuleNodeNew : editingStyleRuleNode;
94
+ } else {
95
+ return isTraditional ? getDeletedTraditionalInlineStyle(false) : deletedContentStyleNew;
96
+ }
97
+ }
98
+ return isTraditional ? isActive ? traditionalStyleRuleNodeActive : traditionalStyleRuleNodeNew : editingStyleRuleNode;
99
+ }
100
+ if (nodeName === 'blockCard') {
101
+ if (isExtendedEnabled(diffType)) {
102
+ if (isInserted) {
103
+ return isTraditional ? isActive ? traditionalStyleCardBlockNodeActive : traditionalStyleCardBlockNodeNew : editingStyleCardBlockNode;
104
+ } else {
105
+ return isTraditional ? getDeletedTraditionalInlineStyle(false) : deletedContentStyleNew;
106
+ }
107
+ }
108
+ return isTraditional ? isActive ? traditionalStyleCardBlockNodeActive : traditionalStyleCardBlockNodeNew : editingStyleCardBlockNode;
109
+ }
110
+ if (isExtendedEnabled(diffType)) {
111
+ if (isInserted) {
112
+ return isTraditional ? isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew : editingStyleNode;
113
+ } else {
114
+ return isTraditional ? getDeletedTraditionalInlineStyle(false) : deletedContentStyleNew;
115
+ }
116
+ }
117
+ return isTraditional ? isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew : editingStyleNode;
118
+ };
@@ -2,13 +2,16 @@ import { areNodesEqualIgnoreAttrs } from '@atlaskit/editor-common/utils/document
2
2
  import { findParentNodeClosestToPos } from '@atlaskit/editor-prosemirror/utils';
3
3
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
4
4
  import { TableMap } from '@atlaskit/editor-tables/table-map';
5
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
5
6
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
6
7
  import { isExtendedEnabled } from '../isExtendedEnabled';
7
- import { addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedRowStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from './colorSchemes/standard';
8
- import { deletedTraditionalRowStyle, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle, traditionalAddedCellOverlayStyle, traditionalAddedCellOverlayRoundedStyle } from './colorSchemes/traditional';
8
+ import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildDeletedCellOverlayRoundedStyle, buildDeletedCellOverlayStyle, buildDeletedRowStyle } from './colorSchemes/factory';
9
+ import { colorSchemeRegistry } from './colorSchemes/schemes';
10
+ import { resolveCellOverlayStyleLegacy, resolveDeletedRowStyleLegacy } from './createChangedRowDecorationWidgets.styles.legacy';
9
11
  import { buildDiffDecorationSpec } from './decorationKeys';
10
12
  import { findSafeInsertPos } from './utils/findSafeInsertPos';
11
13
  import { applyCellEdgeAttrs, getRowCellEdgeAttrs } from './utils/tableCellEdgeAttrs';
14
+ const DEFAULT_COLOR_SCHEME = 'standard';
12
15
  /**
13
16
  * Extracts information about deleted table rows from a change
14
17
  */
@@ -112,12 +115,11 @@ const isEmptyRow = rowNode => {
112
115
  */
113
116
  const createChangedRowDOM = (rowNode, cellEdgeAttrs, nodeViewSerializer, colorScheme, isInserted, diffType) => {
114
117
  const tr = document.createElement('tr');
115
- if (isExtendedEnabled(diffType)) {
116
- if (!isInserted) {
117
- tr.setAttribute('style', colorScheme === 'traditional' ? deletedTraditionalRowStyle : deletedRowStyle);
118
- }
119
- } else {
120
- tr.setAttribute('style', colorScheme === 'traditional' ? deletedTraditionalRowStyle : deletedRowStyle);
118
+ const colors = colorSchemeRegistry[colorScheme !== null && colorScheme !== void 0 ? colorScheme : DEFAULT_COLOR_SCHEME];
119
+
120
+ // Inserted rows keep their natural styling; the row strikethrough is deletions only.
121
+ if (!isExtendedEnabled(diffType) || !isInserted) {
122
+ tr.setAttribute('style', isExperimentEnabled('platform_editor_show_diff_color_scheme_refactor') ? buildDeletedRowStyle(colors) : resolveDeletedRowStyleLegacy(colorScheme));
121
123
  }
122
124
  tr.setAttribute('data-testid', 'show-diff-deleted-row');
123
125
 
@@ -132,10 +134,11 @@ const createChangedRowDOM = (rowNode, cellEdgeAttrs, nodeViewSerializer, colorSc
132
134
  if (isExtendedEnabled(diffType)) {
133
135
  const overlay = document.createElement('span');
134
136
  const isRoundedTable = expValEquals('platform_editor_table_diff_rounded_corners', 'isEnabled', true);
135
- const isTraditional = colorScheme === 'traditional';
136
- const deletedCellStyle = isTraditional ? isRoundedTable ? deletedTraditionalCellOverlayRoundedStyle : deletedTraditionalCellOverlayStyle : isRoundedTable ? deletedCellOverlayRoundedStyle : deletedCellOverlayStyle;
137
- const addedCellStyle = isTraditional ? isRoundedTable ? traditionalAddedCellOverlayRoundedStyle : traditionalAddedCellOverlayStyle : isRoundedTable ? addedCellOverlayRoundedStyle : addedCellOverlayStyle;
138
- const overlayStyle = isInserted ? addedCellStyle : deletedCellStyle;
137
+ const overlayStyle = isExperimentEnabled('platform_editor_show_diff_color_scheme_refactor') ? isInserted ? isRoundedTable ? buildAddedCellOverlayRoundedStyle(colors) : buildAddedCellOverlayStyle(colors) : isRoundedTable ? buildDeletedCellOverlayRoundedStyle(colors) : buildDeletedCellOverlayStyle(colors) : resolveCellOverlayStyleLegacy({
138
+ colorScheme,
139
+ isInserted,
140
+ isRoundedTable
141
+ });
139
142
  overlay.setAttribute('style', overlayStyle);
140
143
  nodeView.appendChild(overlay);
141
144
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Pre-refactor code preserved for the OFF cohort of
3
+ * `platform_editor_show_diff_color_scheme_refactor`.
4
+ *
5
+ * These resolvers reproduce the per-scheme string-constant style decisions that
6
+ * `createChangedRowDOM` made before the `colorSchemeRegistry` + `factory.ts` migration, verbatim.
7
+ *
8
+ * Do not modify. Delete this file at experiment cleanup (EDITOR-8281).
9
+ */
10
+
11
+ import { addedCellOverlayRoundedStyle, addedCellOverlayStyle, deletedCellOverlayRoundedStyle, deletedCellOverlayStyle, deletedRowStyle } from './colorSchemes/standard';
12
+ import { deletedTraditionalCellOverlayRoundedStyle, deletedTraditionalCellOverlayStyle, deletedTraditionalRowStyle, traditionalAddedCellOverlayRoundedStyle, traditionalAddedCellOverlayStyle } from './colorSchemes/traditional';
13
+
14
+ /**
15
+ * Pre-refactor deleted-row style for the `<tr>` element.
16
+ */
17
+ export const resolveDeletedRowStyleLegacy = colorScheme => {
18
+ return colorScheme === 'traditional' ? deletedTraditionalRowStyle : deletedRowStyle;
19
+ };
20
+
21
+ /**
22
+ * Pre-refactor cell overlay style.
23
+ */
24
+ export const resolveCellOverlayStyleLegacy = ({
25
+ colorScheme,
26
+ isInserted,
27
+ isRoundedTable
28
+ }) => {
29
+ const isTraditional = colorScheme === 'traditional';
30
+ const deletedCellStyle = isTraditional ? isRoundedTable ? deletedTraditionalCellOverlayRoundedStyle : deletedTraditionalCellOverlayStyle : isRoundedTable ? deletedCellOverlayRoundedStyle : deletedCellOverlayStyle;
31
+ const addedCellStyle = isTraditional ? isRoundedTable ? traditionalAddedCellOverlayRoundedStyle : traditionalAddedCellOverlayStyle : isRoundedTable ? addedCellOverlayRoundedStyle : addedCellOverlayStyle;
32
+ return isInserted ? addedCellStyle : deletedCellStyle;
33
+ };
@@ -1,23 +1,85 @@
1
1
  import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
2
2
  import { Decoration } from '@atlaskit/editor-prosemirror/view';
3
+ import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
3
4
  import { isExtendedEnabled } from '../isExtendedEnabled';
4
- import { editingStyle, editingStyleExtended, editingStyleExtendedNoUnderline, editingStyleActive, editingStyleActiveExtended, editingStyleActiveExtendedNoUnderline, deletedContentStyle, deletedContentStyleActive, deletedInlineContentStyleExtended } from './colorSchemes/standard';
5
- import { traditionalInsertStyle, traditionalInsertStyleActive, getDeletedTraditionalInlineStyle } from './colorSchemes/traditional';
5
+ import { buildAtomicInlineChangedCSSVariables, buildDeletedInlineContentStyleExtended, buildDeletedInlineStyle, buildDeletedInlineStyleStandard, buildInsertStyle, buildInsertStyleActive, buildInsertStyleExtended, buildInsertStyleExtendedActive, buildInsertStyleExtendedNoUnderline, buildInsertStyleExtendedNoUnderlineActive } from './colorSchemes/factory';
6
+ import { colorSchemeRegistry } from './colorSchemes/schemes';
6
7
  import { createInlineIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
8
+ import { getAtomicInlineNodeClassNameLegacy, resolveInlineChangedStyleLegacy } from './createInlineChangedDecoration.styles.legacy';
7
9
  import { buildDiffDecorationSpec } from './decorationKeys';
8
10
  const displayNoneStyle = convertToInlineCss({
9
11
  display: 'none'
10
12
  });
11
- const getAtomicInlineNodeClassName = (inlineNodeName, colorScheme) => {
13
+ const DEFAULT_COLOR_SCHEME = 'standard';
14
+ const getColorScheme = colorScheme => colorSchemeRegistry[colorScheme !== null && colorScheme !== void 0 ? colorScheme : DEFAULT_COLOR_SCHEME];
15
+
16
+ /**
17
+ * Class names for an atomic inline node decoration (date, emoji, mention, status). Scheme-agnostic
18
+ * — `buildAtomicInlineChangedCSSVariables()` supplies the colour inline on the same element.
19
+ */
20
+ const getAtomicInlineNodeClassName = inlineNodeName => {
12
21
  const classNames = ['show-diff-atomic-inline-changed'];
13
22
  if (inlineNodeName) {
14
23
  classNames.push(`show-diff-atomic-inline-changed-${inlineNodeName}`);
15
24
  }
16
- if (colorScheme === 'traditional') {
17
- classNames.push('show-diff-atomic-inline-changed-traditional');
18
- }
19
25
  return classNames.join(' ');
20
26
  };
27
+
28
+ /** Inline style for inserted content under the extended diff experience. */
29
+ const getExtendedInsertStyle = (colors, isActive, hideAddedDiffsUnderline) => {
30
+ if (colors.insertedInlineTreatment === 'underline') {
31
+ // hideAddedDiffsUnderline only targets the 'borderBottom' rule, so it does not apply here.
32
+ return isActive ? buildInsertStyleActive(colors) : buildInsertStyle(colors);
33
+ }
34
+ if (isActive) {
35
+ return hideAddedDiffsUnderline ? buildInsertStyleExtendedNoUnderlineActive(colors) : buildInsertStyleExtendedActive(colors);
36
+ }
37
+ return hideAddedDiffsUnderline ? buildInsertStyleExtendedNoUnderline(colors) : buildInsertStyleExtended(colors);
38
+ };
39
+
40
+ /** Inline style for deleted content under the extended diff experience. */
41
+ const getExtendedDeletedStyle = (colors, isActive) => {
42
+ if (colors.deletedInlineTreatment === 'strikethrough') {
43
+ // Identical in both states — the block decoration carries the active emphasis.
44
+ return buildDeletedInlineStyle(colors, false);
45
+ }
46
+ return buildDeletedInlineStyleStandard(colors, isActive ? 'active' : 'default') + buildDeletedInlineContentStyleExtended(colors);
47
+ };
48
+
49
+ /** Registry-driven inline `style` for a changed-content decoration. */
50
+ const resolveInlineChangedStyleRefactored = ({
51
+ colors,
52
+ diffType,
53
+ hideAddedDiffsUnderline,
54
+ isActive,
55
+ isInserted
56
+ }) => {
57
+ if (isExtendedEnabled(diffType)) {
58
+ return isInserted ? getExtendedInsertStyle(colors, isActive, hideAddedDiffsUnderline) : getExtendedDeletedStyle(colors, isActive);
59
+ }
60
+ return isActive ? buildInsertStyleActive(colors) : buildInsertStyle(colors);
61
+ };
62
+
63
+ /**
64
+ * Single gate for the inline `style` string: registry + factory when the refactor is on, the
65
+ * verbatim pre-refactor per-scheme constants when it is off.
66
+ */
67
+ const resolveInlineChangedStyle = args => isExperimentEnabled('platform_editor_show_diff_color_scheme_refactor') ? resolveInlineChangedStyleRefactored(args) : resolveInlineChangedStyleLegacy(args);
68
+
69
+ /**
70
+ * Single gate for the atomic-inline-node decoration attributes. The two cohorts differ in the DOM:
71
+ * on, the colour rides on an inline CSS variable and the class list is scheme-agnostic; off, the
72
+ * colour comes from a `-traditional` class and no variable is emitted. Returned together so the
73
+ * class list and style suffix can never be mixed across cohorts.
74
+ */
75
+ const resolveAtomicInlineAttrs = (inlineNodeName, colorScheme, colors) => isExperimentEnabled('platform_editor_show_diff_color_scheme_refactor') ? {
76
+ className: getAtomicInlineNodeClassName(inlineNodeName),
77
+ styleSuffix: buildAtomicInlineChangedCSSVariables(colors)
78
+ } : {
79
+ className: getAtomicInlineNodeClassNameLegacy(inlineNodeName, colorScheme),
80
+ styleSuffix: ''
81
+ };
82
+
21
83
  /**
22
84
  * Inline decoration used for insertions as the content already exists in the document
23
85
  *
@@ -50,38 +112,21 @@ export const createInlineChangedDecoration = ({
50
112
  isActive
51
113
  }))];
52
114
  }
53
- let style;
54
- if (isExtendedEnabled(diffType)) {
55
- if (isInserted) {
56
- if (colorScheme === 'traditional') {
57
- style = isActive ? traditionalInsertStyleActive : traditionalInsertStyle;
58
- } else {
59
- style = isActive ? hideAddedDiffsUnderline ? editingStyleActiveExtendedNoUnderline : editingStyleActiveExtended : hideAddedDiffsUnderline ? editingStyleExtendedNoUnderline : editingStyleExtended;
60
- }
61
- } else {
62
- if (colorScheme === 'traditional') {
63
- style = getDeletedTraditionalInlineStyle(false);
64
- } else {
65
- style = isActive ? deletedContentStyleActive : deletedContentStyle;
66
- /**
67
- * Merge into existing styles when cleaning up
68
- */
69
- if (isExtendedEnabled(diffType)) {
70
- style += deletedInlineContentStyleExtended;
71
- }
72
- }
73
- }
74
- } else {
75
- if (colorScheme === 'traditional') {
76
- style = isActive ? traditionalInsertStyleActive : traditionalInsertStyle;
77
- } else {
78
- style = isActive ? editingStyleActive : editingStyle;
79
- }
80
- }
115
+ const colors = getColorScheme(colorScheme);
116
+ const style = resolveInlineChangedStyle({
117
+ colors,
118
+ colorScheme,
119
+ diffType,
120
+ hideAddedDiffsUnderline,
121
+ isActive,
122
+ isInserted
123
+ });
124
+ const isAtomicInlineInsertion = isAtomicInlineNode && isInserted;
125
+ const atomicInlineAttrs = isAtomicInlineInsertion ? resolveAtomicInlineAttrs(inlineNodeName, colorScheme, colors) : undefined;
81
126
  const decorations = [Decoration.inline(change.fromB, change.toB, {
82
- style,
83
- ...(isAtomicInlineNode && isInserted && {
84
- class: getAtomicInlineNodeClassName(inlineNodeName, colorScheme)
127
+ style: atomicInlineAttrs ? `${style}${atomicInlineAttrs.styleSuffix}` : style,
128
+ ...(atomicInlineAttrs && {
129
+ class: atomicInlineAttrs.className
85
130
  }),
86
131
  'data-testid': 'show-diff-changed-decoration'
87
132
  }, buildDiffDecorationSpec({
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Pre-refactor `createInlineChangedDecoration` styling code, preserved verbatim for the OFF cohort
3
+ * of `platform_editor_show_diff_color_scheme_refactor`.
4
+ *
5
+ * Do not modify — this module exists purely so the OFF cohort keeps running the exact code that
6
+ * shipped before the `colorSchemeRegistry` + `factory.ts` migration. Delete the whole file at
7
+ * experiment cleanup (EDITOR-8281).
8
+ */
9
+
10
+ import { isExtendedEnabled } from '../isExtendedEnabled';
11
+ import { deletedContentStyle, deletedContentStyleActive, deletedInlineContentStyleExtended, editingStyle, editingStyleActive, editingStyleActiveExtended, editingStyleActiveExtendedNoUnderline, editingStyleExtended, editingStyleExtendedNoUnderline } from './colorSchemes/standard';
12
+ import { getDeletedTraditionalInlineStyle, traditionalInsertStyle, traditionalInsertStyleActive } from './colorSchemes/traditional';
13
+ /**
14
+ * Pre-refactor inline `style` computation for `createInlineChangedDecoration`.
15
+ */
16
+ export const resolveInlineChangedStyleLegacy = ({
17
+ colorScheme,
18
+ diffType,
19
+ hideAddedDiffsUnderline,
20
+ isActive,
21
+ isInserted
22
+ }) => {
23
+ let style;
24
+ if (isExtendedEnabled(diffType)) {
25
+ if (isInserted) {
26
+ if (colorScheme === 'traditional') {
27
+ style = isActive ? traditionalInsertStyleActive : traditionalInsertStyle;
28
+ } else {
29
+ style = isActive ? hideAddedDiffsUnderline ? editingStyleActiveExtendedNoUnderline : editingStyleActiveExtended : hideAddedDiffsUnderline ? editingStyleExtendedNoUnderline : editingStyleExtended;
30
+ }
31
+ } else {
32
+ if (colorScheme === 'traditional') {
33
+ style = getDeletedTraditionalInlineStyle(false);
34
+ } else {
35
+ style = (isActive ? deletedContentStyleActive : deletedContentStyle) + deletedInlineContentStyleExtended;
36
+ }
37
+ }
38
+ } else {
39
+ if (colorScheme === 'traditional') {
40
+ style = isActive ? traditionalInsertStyleActive : traditionalInsertStyle;
41
+ } else {
42
+ style = isActive ? editingStyleActive : editingStyle;
43
+ }
44
+ }
45
+ return style;
46
+ };
47
+
48
+ /**
49
+ * Pre-refactor class names for an atomic inline node decoration (date, emoji, mention, status).
50
+ * The colour was carried by the per-scheme `-traditional` class rather than by an inline CSS
51
+ * variable on the same element.
52
+ */
53
+ export const getAtomicInlineNodeClassNameLegacy = (inlineNodeName, colorScheme) => {
54
+ const classNames = ['show-diff-atomic-inline-changed'];
55
+ if (inlineNodeName) {
56
+ classNames.push(`show-diff-atomic-inline-changed-${inlineNodeName}`);
57
+ }
58
+ if (colorScheme === 'traditional') {
59
+ classNames.push('show-diff-atomic-inline-changed-traditional');
60
+ }
61
+ return classNames.join(' ');
62
+ };
@@ -3,108 +3,8 @@ import { trackChangesMessages } from '@atlaskit/editor-common/messages';
3
3
  import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
4
4
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
5
5
  import { isExtendedEnabled } from '../../isExtendedEnabled';
6
- import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleUnbounded, deletedInlineContentStyleExtended, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlockExtended, editingContentStyleInBlockExtendedNoUnderline, editingStyleExtended, editingStyleExtendedNoUnderline, editingStyleActiveExtended, editingStyleActiveExtendedNoUnderline, editingStyleNode, addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from '../colorSchemes/standard';
7
- import { deletedTraditionalBlockOutlineActive, deletedTraditionalBlockOutlineNew, deletedTraditionalBlockOutlineRoundedActive, deletedTraditionalBlockOutlineRoundedNew, deletedTraditionalContentStyleUnbounded, deletedTraditionalContentStyleUnboundedActive, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, deletedTraditionalStyleQuoteNodeActive, traditionalInsertStyle, traditionalInsertStyleActive, traditionalStyleNodeActive, traditionalStyleNodeNew, traditionalAddedCellOverlayRoundedStyle, traditionalAddedCellOverlayStyleNew, deletedTraditionalCellOverlayStyle, deletedTraditionalCellOverlayRoundedStyle } from '../colorSchemes/traditional';
8
6
  import { applyTableCellEdgeAttrs } from './tableCellEdgeAttrs';
9
- const lozengeStyle = convertToInlineCss({
10
- display: 'inline-flex',
11
- boxSizing: 'border-box',
12
- position: 'static',
13
- blockSize: 'min-content',
14
- borderRadius: "var(--ds-radius-small, 4px)",
15
- overflow: 'hidden',
16
- paddingInlineStart: "var(--ds-space-050, 4px)",
17
- paddingInlineEnd: "var(--ds-space-050, 4px)",
18
- backgroundColor: "var(--ds-background-accent-gray-subtler, #DDDEE1)",
19
- font: "var(--ds-font-body-small, normal 400 12px/16px \"Atlassian Sans\", ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, \"Helvetica Neue\", sans-serif)",
20
- fontWeight: "var(--ds-font-weight-bold, 653)",
21
- textOverflow: 'ellipsis',
22
- whiteSpace: 'nowrap',
23
- color: "var(--ds-text-warning-inverse, #292A2E)"
24
- });
25
- const lozengeStyleActiveStandard = convertToInlineCss({
26
- display: 'inline-flex',
27
- boxSizing: 'border-box',
28
- position: 'static',
29
- blockSize: 'min-content',
30
- borderRadius: "var(--ds-radius-small, 4px)",
31
- overflow: 'hidden',
32
- paddingInlineStart: "var(--ds-space-050, 4px)",
33
- paddingInlineEnd: "var(--ds-space-050, 4px)",
34
- backgroundColor: "var(--ds-background-accent-red-subtler-pressed, #FD9891)",
35
- font: "var(--ds-font-body-small, normal 400 12px/16px \"Atlassian Sans\", ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, \"Helvetica Neue\", sans-serif)",
36
- fontWeight: "var(--ds-font-weight-bold, 653)",
37
- textOverflow: 'ellipsis',
38
- whiteSpace: 'nowrap',
39
- color: "var(--ds-text-warning-inverse, #292A2E)"
40
- });
41
- const lozengeStyleActiveTraditional = convertToInlineCss({
42
- display: 'inline-flex',
43
- boxSizing: 'border-box',
44
- position: 'static',
45
- blockSize: 'min-content',
46
- borderRadius: "var(--ds-radius-small, 4px)",
47
- overflow: 'hidden',
48
- paddingInlineStart: "var(--ds-space-050, 4px)",
49
- paddingInlineEnd: "var(--ds-space-050, 4px)",
50
- backgroundColor: "var(--ds-background-accent-red-subtler-pressed, #FD9891)",
51
- font: "var(--ds-font-body-small, normal 400 12px/16px \"Atlassian Sans\", ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, \"Helvetica Neue\", sans-serif)",
52
- fontWeight: "var(--ds-font-weight-bold, 653)",
53
- textOverflow: 'ellipsis',
54
- whiteSpace: 'nowrap',
55
- color: "var(--ds-text-warning-inverse, #292A2E)"
56
- });
57
- const getChangedContentStyle = (colorScheme, isActive = false, isInserted = false, diffType, hideAddedDiffsUnderline = false) => {
58
- if (isExtendedEnabled(diffType) && isInserted) {
59
- if (colorScheme === 'traditional') {
60
- return isActive ? traditionalInsertStyleActive : traditionalInsertStyle;
61
- }
62
- return isActive ? hideAddedDiffsUnderline ? editingStyleActiveExtendedNoUnderline : editingStyleActiveExtended : hideAddedDiffsUnderline ? editingStyleExtendedNoUnderline : editingStyleExtended;
63
- }
64
- if (colorScheme === 'traditional') {
65
- return getDeletedTraditionalInlineStyle(isActive);
66
- }
67
- if (isActive) {
68
- return deletedContentStyleActive;
69
- }
70
- return expValEquals('platform_editor_enghealth_a11y_jan_fixes', 'isEnabled', true) ? deletedContentStyleNew : deletedContentStyle;
71
- };
72
- const getChangedNodeStyle = (nodeName, colorScheme, isInserted = false, isActive = false, diffType, hideAddedDiffsUnderline = false) => {
73
- const isTraditional = colorScheme === 'traditional';
74
- if (isExtendedEnabled(diffType) && isInserted) {
75
- if (isMultiContainerBlockNode(nodeName)) {
76
- return hideAddedDiffsUnderline ? editingContentStyleInBlockExtendedNoUnderline : editingContentStyleInBlockExtended;
77
- }
78
- if (isTextLikeBlockNode(nodeName)) {
79
- return undefined;
80
- }
81
- if (isTraditional) {
82
- return isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew;
83
- }
84
- return editingStyleNode;
85
- }
86
- switch (nodeName) {
87
- case 'blockquote':
88
- if (isTraditional) {
89
- return isActive ? deletedTraditionalStyleQuoteNodeActive : deletedTraditionalStyleQuoteNode;
90
- }
91
- return isActive ? deletedStyleQuoteNodeWithLozengeActive : deletedStyleQuoteNodeWithLozenge;
92
- case 'expand':
93
- case 'decisionList':
94
- if (isTraditional) {
95
- return isActive ? deletedTraditionalBlockOutlineActive : deletedTraditionalBlockOutlineNew;
96
- }
97
- return isActive ? deletedBlockOutlineActive : deletedBlockOutline;
98
- case 'panel':
99
- case 'codeBlock':
100
- if (isTraditional) {
101
- return isActive ? deletedTraditionalBlockOutlineRoundedActive : deletedTraditionalBlockOutlineRoundedNew;
102
- }
103
- return isActive ? deletedBlockOutlineRoundedActive : deletedBlockOutlineRounded;
104
- default:
105
- return undefined;
106
- }
107
- };
7
+ import { getChangedContentStyle, getChangedNodeStyle, getDeletedContentStyle, getDeletedContentStyleUnbounded, getInsertedContentStyle, hasRestingDeletedRing, isMultiContainerBlockNode, isTextLikeBlockNode, resolveCellOverlayStyle, resolveNestedInsertedNodeStyle, resolveRemovedLozengeStyle } from './wrapBlockNodeViewStyles';
108
8
  const shouldShowRemovedLozenge = nodeName => {
109
9
  switch (nodeName) {
110
10
  case 'expand':
@@ -141,7 +41,8 @@ const maybeAddDeletedOutlineNewClass = ({
141
41
  if (name !== 'mediaSingle' && name !== 'embedCard') {
142
42
  return;
143
43
  }
144
- if (colorScheme === 'traditional' && !isActive) {
44
+ // Only schemes with a resting ring get the class.
45
+ if (hasRestingDeletedRing(colorScheme) && !isActive) {
145
46
  nodeView.classList.add('show-diff-deleted-outline-new');
146
47
  }
147
48
  };
@@ -153,24 +54,19 @@ const maybeAddDeletedOutlineNewClass = ({
153
54
  const shouldApplyStylesDirectly = nodeName => {
154
55
  return nodeName === 'heading';
155
56
  };
156
- const isMultiContainerBlockNode = nodeName => {
157
- return ['decisionList', 'layoutSection'].includes(nodeName);
158
- };
159
- const isTextLikeBlockNode = nodeName => {
160
- return ['heading', 'bulletList', 'orderedList', 'listItem', 'taskList', 'blockquote'].includes(nodeName);
161
- };
162
57
  const applyCellOverlayStyles = ({
163
58
  element,
164
59
  colorScheme,
165
60
  isInserted
166
61
  }) => {
167
62
  const isRoundedTable = expValEquals('platform_editor_table_diff_rounded_corners', 'isEnabled', true);
63
+ const overlayStyle = resolveCellOverlayStyle({
64
+ colorScheme,
65
+ isInserted,
66
+ isRoundedTable
67
+ });
168
68
  element.querySelectorAll('td, th').forEach(cell => {
169
69
  const overlay = document.createElement('span');
170
- const isTraditional = colorScheme === 'traditional';
171
- const deletedCellStyle = isTraditional ? isRoundedTable ? deletedTraditionalCellOverlayRoundedStyle : deletedTraditionalCellOverlayStyle : isRoundedTable ? deletedCellOverlayRoundedStyle : deletedCellOverlayStyle;
172
- const addedCellStyle = isTraditional ? isRoundedTable ? traditionalAddedCellOverlayRoundedStyle : traditionalAddedCellOverlayStyleNew : isRoundedTable ? addedCellOverlayRoundedStyle : addedCellOverlayStyle;
173
- const overlayStyle = isInserted ? addedCellStyle : deletedCellStyle;
174
70
  overlay.setAttribute('style', overlayStyle);
175
71
  cell.appendChild(overlay);
176
72
  });
@@ -194,7 +90,7 @@ const createRemovedLozenge = (intl, isActive = false, colorScheme) => {
194
90
 
195
91
  // Create vanilla HTML lozenge element with Atlaskit Lozenge styling (visual refresh)
196
92
  const lozengeElement = document.createElement('span');
197
- const lozengeInnerStyle = isActive && colorScheme === 'traditional' ? lozengeStyleActiveTraditional : isActive ? lozengeStyleActiveStandard : lozengeStyle;
93
+ const lozengeInnerStyle = resolveRemovedLozengeStyle(colorScheme, isActive);
198
94
  lozengeElement.setAttribute('style', lozengeInnerStyle);
199
95
  lozengeElement.textContent = intl.formatMessage(trackChangesMessages.removed).toUpperCase();
200
96
  container.appendChild(lozengeElement);
@@ -246,19 +142,22 @@ const applyMultiContainerLikeStyles = ({
246
142
  const targetNodeName = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? getBaseNodeTypeName(targetNode.type) : targetNode.type.name;
247
143
  const nodeSpecificStyle = getChangedNodeStyle(targetNodeName, colorScheme, isInserted, isActive, diffType, hideAddedDiffsUnderline) || '';
248
144
  if (targetNode.type.name === 'decisionList') {
145
+ const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
249
146
  element.querySelectorAll('li').forEach(listItem => {
250
147
  const currentListItemStyle = listItem.getAttribute('style') || '';
251
- listItem.setAttribute('style', `${currentListItemStyle}${editingStyleNode}`);
148
+ listItem.setAttribute('style', `${currentListItemStyle}${nestedInsertedNodeStyle}`);
252
149
  });
253
150
  } else if (targetNode.type.name === 'layoutSection') {
151
+ const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
254
152
  element.querySelectorAll('[data-layout-column="true"]').forEach(section => {
255
153
  const currentSectionStyle = section.getAttribute('style') || '';
256
- section.setAttribute('style', `${currentSectionStyle}${editingStyleNode}`);
154
+ section.setAttribute('style', `${currentSectionStyle}${nestedInsertedNodeStyle}`);
257
155
  });
258
156
  } else if (targetNode.type.name === 'taskList') {
157
+ const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
259
158
  element.querySelectorAll('li').forEach(listItem => {
260
159
  const currentListItemStyle = listItem.getAttribute('style') || '';
261
- listItem.setAttribute('style', `${currentListItemStyle}${editingStyleNode}`);
160
+ listItem.setAttribute('style', `${currentListItemStyle}${nestedInsertedNodeStyle}`);
262
161
  });
263
162
  }
264
163
  element.setAttribute('style', `${currentStyle};${nodeSpecificStyle}`);
@@ -581,30 +480,6 @@ export const wrapBlockNodeView = ({
581
480
  }
582
481
  }
583
482
  };
584
- const getDeletedContentStyleUnbounded = (colorScheme, isActive = false) => {
585
- if (colorScheme === 'traditional' && isActive) {
586
- return deletedTraditionalContentStyleUnboundedActive;
587
- }
588
- return colorScheme === 'traditional' ? deletedTraditionalContentStyleUnbounded : deletedContentStyleUnbounded;
589
- };
590
- const getInsertedContentStyle = (colorScheme, isActive = false, hideAddedDiffsUnderline = false) => {
591
- if (colorScheme === 'traditional') {
592
- return isActive ? traditionalInsertStyleActive : traditionalInsertStyle;
593
- }
594
- if (isActive) {
595
- return hideAddedDiffsUnderline ? editingStyleActiveExtendedNoUnderline : editingStyleActiveExtended;
596
- }
597
- return hideAddedDiffsUnderline ? editingStyleExtendedNoUnderline : editingStyleExtended;
598
- };
599
- const getDeletedContentStyle = (colorScheme, isActive = false, diffType) => {
600
- if (colorScheme === 'traditional') {
601
- return getDeletedTraditionalInlineStyle(isActive);
602
- }
603
- if (isExtendedEnabled(diffType)) {
604
- return (isActive ? deletedContentStyleActive : deletedContentStyleNew) + deletedInlineContentStyleExtended;
605
- }
606
- return isActive ? deletedContentStyleActive : deletedContentStyleNew;
607
- };
608
483
 
609
484
  /**
610
485
  * Injects a styled inner wrapper span around the children of a block node element.