@atlaskit/editor-plugin-show-diff 10.5.1 → 10.5.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.
Files changed (24) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +30 -3
  3. package/dist/cjs/pm-plugins/decorations/colorSchemes/standard.js +13 -1
  4. package/dist/cjs/pm-plugins/decorations/colorSchemes/traditional.js +15 -2
  5. package/dist/cjs/pm-plugins/decorations/createChangedRowDecorationWidgets.js +83 -26
  6. package/dist/cjs/pm-plugins/decorations/createInlineChangedDecoration.js +23 -4
  7. package/dist/cjs/pm-plugins/decorations/utils/getAttrChangeRanges.js +64 -4
  8. package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +30 -3
  9. package/dist/es2019/pm-plugins/decorations/colorSchemes/standard.js +12 -0
  10. package/dist/es2019/pm-plugins/decorations/colorSchemes/traditional.js +14 -1
  11. package/dist/es2019/pm-plugins/decorations/createChangedRowDecorationWidgets.js +67 -9
  12. package/dist/es2019/pm-plugins/decorations/createInlineChangedDecoration.js +16 -1
  13. package/dist/es2019/pm-plugins/decorations/utils/getAttrChangeRanges.js +53 -4
  14. package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +30 -3
  15. package/dist/esm/pm-plugins/decorations/colorSchemes/standard.js +12 -0
  16. package/dist/esm/pm-plugins/decorations/colorSchemes/traditional.js +14 -1
  17. package/dist/esm/pm-plugins/decorations/createChangedRowDecorationWidgets.js +85 -28
  18. package/dist/esm/pm-plugins/decorations/createInlineChangedDecoration.js +23 -4
  19. package/dist/esm/pm-plugins/decorations/utils/getAttrChangeRanges.js +63 -4
  20. package/dist/types/pm-plugins/decorations/colorSchemes/standard.d.ts +1 -0
  21. package/dist/types/pm-plugins/decorations/colorSchemes/traditional.d.ts +2 -1
  22. package/dist/types/pm-plugins/decorations/createInlineChangedDecoration.d.ts +4 -1
  23. package/dist/types/pm-plugins/decorations/utils/getAttrChangeRanges.d.ts +11 -1
  24. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @atlaskit/editor-plugin-show-diff
2
2
 
3
+ ## 10.5.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [`154b76531a593`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/154b76531a593) -
8
+ Fix table diff cell overlays to use rounded corners for inserting row diffs when
9
+ platform_editor_table_diff_rounded_corners is enabled
10
+
11
+ ## 10.5.2
12
+
13
+ ### Patch Changes
14
+
15
+ - [`75c7e6a9aa4ec`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/75c7e6a9aa4ec) -
16
+ [ux] Improve showing diff for attribute changes for inline nodes.
17
+ - Updated dependencies
18
+
3
19
  ## 10.5.1
4
20
 
5
21
  ### Patch Changes
@@ -427,16 +427,43 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
427
427
  isInserted: true
428
428
  })));
429
429
  });
430
- (0, _getAttrChangeRanges.getAttrChangeRanges)(tr.doc, attrSteps).forEach(function (change) {
430
+ (0, _getAttrChangeRanges.getAttrChangeRanges)(tr.doc, attrSteps, originalDoc).forEach(function (change) {
431
431
  if (change.isInline) {
432
- // Inline nodes (e.g. date) need an inline decoration rather than a block decoration
432
+ // Inline nodes (e.g. date, emoji, mention, status) need an inline decoration rather than a block decoration
433
433
  var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
434
+ var isAtomicInlineNodeFlag = (0, _expValEquals.expValEquals)('platform_editor_improve_inline_diffs', 'isEnabled', true);
434
435
  decorations.push.apply(decorations, (0, _toConsumableArray2.default)((0, _createInlineChangedDecoration.createInlineChangedDecoration)({
435
436
  change: change,
436
437
  colorScheme: colorScheme,
437
438
  isActive: isActive,
438
- isInserted: true
439
+ isInserted: true,
440
+ isAtomicInlineNode: isAtomicInlineNodeFlag,
441
+ inlineNodeName: change.inlineNodeName,
442
+ // Suppress the border-bottom underline for atomic inline nodeviews —
443
+ // it doesn't render on custom nodeview DOM elements and is unnecessary noise.
444
+ hideAddedDiffsUnderline: isAtomicInlineNodeFlag,
445
+ diffType: diffType
439
446
  })));
447
+ // If we have the original node position, also render the old node as a "deleted" widget
448
+ // so the user can see what it looked like before the change.
449
+ if (change.fromA !== undefined && change.toA !== undefined && (0, _expValEquals.expValEquals)('platform_editor_improve_inline_diffs', 'isEnabled', true)) {
450
+ decorations.push.apply(decorations, (0, _toConsumableArray2.default)((0, _createNodeChangedDecorationWidget.createNodeChangedDecorationWidget)({
451
+ change: {
452
+ fromA: change.fromA,
453
+ toA: change.toA,
454
+ fromB: change.fromB,
455
+ toB: change.toB,
456
+ deleted: []
457
+ },
458
+ doc: originalDoc,
459
+ nodeViewSerializer: nodeViewSerializer,
460
+ colorScheme: colorScheme,
461
+ newDoc: tr.doc,
462
+ intl: intl,
463
+ activeIndexPos: activeIndexPos,
464
+ isInserted: false
465
+ })));
466
+ }
440
467
  } else {
441
468
  decorations.push.apply(decorations, (0, _toConsumableArray2.default)(calculateNodesForBlockDecoration({
442
469
  doc: tr.doc,
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.standardDecorationMarkerVariable = exports.editingStyleRuleNode = exports.editingStyleQuoteNode = exports.editingStyleNode = exports.editingStyleExtendedNoUnderline = exports.editingStyleExtended = exports.editingStyleCardBlockNode = exports.editingStyleActiveExtendedNoUnderline = exports.editingStyleActiveExtended = exports.editingStyleActive = exports.editingStyle = exports.editingContentStyleInBlockExtendedNoUnderline = exports.editingContentStyleInBlockExtended = exports.editingContentStyleInBlock = exports.deletedStyleQuoteNodeWithLozengeActive = exports.deletedStyleQuoteNodeWithLozenge = exports.deletedStyleQuoteNode = exports.deletedRowStyle = exports.deletedInlineContentStyleExtended = exports.deletedDecorationMarkerVariable = exports.deletedContentStyleUnbounded = exports.deletedContentStyleNew = exports.deletedContentStyleActive = exports.deletedContentStyle = exports.deletedCellOverlayStyle = exports.deletedCellOverlayRoundedStyle = exports.deletedBlockOutlineRoundedActive = exports.deletedBlockOutlineRounded = exports.deletedBlockOutlineActive = exports.deletedBlockOutline = exports.addedCellOverlayStyle = void 0;
6
+ exports.standardDecorationMarkerVariable = exports.editingStyleRuleNode = exports.editingStyleQuoteNode = exports.editingStyleNode = exports.editingStyleExtendedNoUnderline = exports.editingStyleExtended = exports.editingStyleCardBlockNode = exports.editingStyleActiveExtendedNoUnderline = exports.editingStyleActiveExtended = exports.editingStyleActive = exports.editingStyle = exports.editingContentStyleInBlockExtendedNoUnderline = exports.editingContentStyleInBlockExtended = exports.editingContentStyleInBlock = exports.deletedStyleQuoteNodeWithLozengeActive = exports.deletedStyleQuoteNodeWithLozenge = exports.deletedStyleQuoteNode = exports.deletedRowStyle = exports.deletedInlineContentStyleExtended = exports.deletedDecorationMarkerVariable = exports.deletedContentStyleUnbounded = exports.deletedContentStyleNew = exports.deletedContentStyleActive = exports.deletedContentStyle = exports.deletedCellOverlayStyle = exports.deletedCellOverlayRoundedStyle = exports.deletedBlockOutlineRoundedActive = exports.deletedBlockOutlineRounded = exports.deletedBlockOutlineActive = exports.deletedBlockOutline = exports.addedCellOverlayStyle = exports.addedCellOverlayRoundedStyle = void 0;
7
7
  var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
8
8
  // delete on platform_editor_diff_plugin_extended cleanup
9
9
  var editingStyle = exports.editingStyle = (0, _lazyNodeView.convertToInlineCss)({
@@ -176,6 +176,18 @@ var addedCellOverlayStyle = exports.addedCellOverlayStyle = (0, _lazyNodeView.co
176
176
  outline: "1px solid ".concat("var(--ds-border-accent-purple, #AF59E1)"),
177
177
  pointerEvents: 'none'
178
178
  });
179
+ var addedCellOverlayRoundedStyle = exports.addedCellOverlayRoundedStyle = (0, _lazyNodeView.convertToInlineCss)({
180
+ position: 'absolute',
181
+ top: 0,
182
+ left: 0,
183
+ width: '100%',
184
+ height: '100%',
185
+ backgroundColor: "rgba(from ".concat("var(--ds-background-accent-purple-subtlest, #F8EEFE)", " r g b / 0.5)"),
186
+ zIndex: 2,
187
+ outline: "1px solid ".concat("var(--ds-border-accent-purple, #AF59E1)"),
188
+ pointerEvents: 'none',
189
+ borderRadius: 'inherit'
190
+ });
179
191
  var deletedCellOverlayStyle = exports.deletedCellOverlayStyle = (0, _lazyNodeView.convertToInlineCss)({
180
192
  position: 'absolute',
181
193
  top: 0,
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.deletedTraditionalStyleQuoteNodeActive = exports.deletedTraditionalStyleQuoteNode = exports.deletedTraditionalRowStyle = exports.deletedTraditionalContentStyleUnboundedActive = exports.deletedTraditionalContentStyleUnbounded = exports.deletedTraditionalCellOverlayStyle = exports.deletedTraditionalCellOverlayRoundedStyle = exports.deletedTraditionalBlockOutlineRoundedNew = exports.deletedTraditionalBlockOutlineRoundedActive = exports.deletedTraditionalBlockOutlineRounded = exports.deletedTraditionalBlockOutlineNew = exports.deletedTraditionalBlockOutlineActive = exports.deletedTraditionalBlockOutline = void 0;
8
8
  exports.getDeletedTraditionalInlineStyle = getDeletedTraditionalInlineStyle;
9
- exports.traditionalStyleRuleNodeNew = exports.traditionalStyleRuleNodeActive = exports.traditionalStyleRuleNode = exports.traditionalStyleQuoteNodeNew = exports.traditionalStyleQuoteNodeActive = exports.traditionalStyleQuoteNode = exports.traditionalStyleNodeNew = exports.traditionalStyleNodeActive = exports.traditionalStyleNode = exports.traditionalStyleCardBlockNodeNew = exports.traditionalStyleCardBlockNodeActive = exports.traditionalStyleCardBlockNode = exports.traditionalInsertStyleActive = exports.traditionalInsertStyle = exports.traditionalDeletedDecorationMarkerVariableNew = exports.traditionalDeletedDecorationMarkerVariableActive = exports.traditionalDeletedDecorationMarkerVariable = exports.traditionalDecorationMarkerVariableNew = exports.traditionalDecorationMarkerVariableActive = exports.traditionalDecorationMarkerVariable = exports.traditionalAddedCellOverlayStyleNew = exports.traditionalAddedCellOverlayStyle = void 0;
9
+ exports.traditionalStyleRuleNodeNew = exports.traditionalStyleRuleNodeActive = exports.traditionalStyleRuleNode = exports.traditionalStyleQuoteNodeNew = exports.traditionalStyleQuoteNodeActive = exports.traditionalStyleQuoteNode = exports.traditionalStyleNodeNew = exports.traditionalStyleNodeActive = exports.traditionalStyleNode = exports.traditionalStyleCardBlockNodeNew = exports.traditionalStyleCardBlockNodeActive = exports.traditionalStyleCardBlockNode = exports.traditionalInsertStyleActive = exports.traditionalInsertStyle = exports.traditionalDeletedDecorationMarkerVariableNew = exports.traditionalDeletedDecorationMarkerVariableActive = exports.traditionalDeletedDecorationMarkerVariable = exports.traditionalDecorationMarkerVariableNew = exports.traditionalDecorationMarkerVariableActive = exports.traditionalDecorationMarkerVariable = exports.traditionalAddedCellOverlayStyleNew = exports.traditionalAddedCellOverlayStyle = exports.traditionalAddedCellOverlayRoundedStyle = void 0;
10
10
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
11
11
  var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
12
12
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -93,7 +93,7 @@ var deletedTraditionalBlockOutlineRoundedActive = exports.deletedTraditionalBloc
93
93
  borderRadius: "calc(".concat("var(--ds-radius-xsmall, 2px)", " + 1px)")
94
94
  });
95
95
 
96
- /** Scroll-navigation “new” emphasis: 4px ring (see {@link traditionalStyleNodeNew}). */
96
+ /** Scroll-navigation “new” emphasis: 4px ring. */
97
97
  var deletedTraditionalBlockOutlineNew = exports.deletedTraditionalBlockOutlineNew = (0, _lazyNodeView.convertToInlineCss)({
98
98
  boxShadow: "0 0 0 4px ".concat("var(--ds-background-accent-red-subtlest, #FFECEB)"),
99
99
  borderRadius: "var(--ds-radius-small, 4px)"
@@ -193,6 +193,19 @@ var traditionalAddedCellOverlayStyle = exports.traditionalAddedCellOverlayStyle
193
193
  outline: "1px solid ".concat("var(--ds-border-accent-green, #22A06B)"),
194
194
  pointerEvents: 'none'
195
195
  });
196
+ var traditionalAddedCellOverlayRoundedStyle = exports.traditionalAddedCellOverlayRoundedStyle = (0, _lazyNodeView.convertToInlineCss)({
197
+ position: 'absolute',
198
+ top: 0,
199
+ left: 0,
200
+ width: '100%',
201
+ height: '100%',
202
+ backgroundColor: "rgba(from ".concat("var(--ds-background-accent-green-subtlest, #DCFFF1)", " r g b / 0.5)"),
203
+ zIndex: 2,
204
+ outline: "1px solid ".concat("var(--ds-border-accent-green, #22A06B)"),
205
+ pointerEvents: 'none',
206
+ border: 'inherit',
207
+ borderRadius: 'inherit'
208
+ });
196
209
  var traditionalAddedCellOverlayStyleNew = exports.traditionalAddedCellOverlayStyleNew = (0, _lazyNodeView.convertToInlineCss)({
197
210
  position: 'absolute',
198
211
  top: 0,
@@ -11,6 +11,7 @@ var _document = require("@atlaskit/editor-common/utils/document");
11
11
  var _utils = require("@atlaskit/editor-prosemirror/utils");
12
12
  var _view = require("@atlaskit/editor-prosemirror/view");
13
13
  var _tableMap = require("@atlaskit/editor-tables/table-map");
14
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
14
15
  var _isExtendedEnabled = require("../isExtendedEnabled");
15
16
  var _standard = require("./colorSchemes/standard");
16
17
  var _traditional = require("./colorSchemes/traditional");
@@ -21,14 +22,55 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
21
22
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
22
23
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
23
24
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
25
+ /**
26
+ * Inserted table rows are rendered as decoration widgets, so their cells do not get the
27
+ * `data-reaches-*` attrs normally applied by the table cell node view. Mirror that boundary
28
+ * metadata here so the existing rounded-table CSS can round widget cells like real table cells.
29
+ */
30
+ var getChangedRowCellEdgeAttrs = function getChangedRowCellEdgeAttrs(_ref) {
31
+ var rowNode = _ref.rowNode,
32
+ rowStart = _ref.rowStart,
33
+ tableMap = _ref.tableMap;
34
+ var cellEdgeAttrs = [];
35
+ rowNode.content.forEach(function (cellNode, cellOffset) {
36
+ if (cellNode.type.name !== 'tableCell' && cellNode.type.name !== 'tableHeader') {
37
+ return;
38
+ }
39
+ var cellRect = tableMap.findCell(rowStart + 1 + cellOffset);
40
+ cellEdgeAttrs.push({
41
+ reachesBottom: cellRect.bottom >= tableMap.height,
42
+ reachesLeft: cellRect.left === 0,
43
+ reachesRight: cellRect.right >= tableMap.width,
44
+ reachesTop: cellRect.top === 0
45
+ });
46
+ });
47
+ return cellEdgeAttrs;
48
+ };
49
+ var applyCellEdgeAttrs = function applyCellEdgeAttrs(cell, edgeAttrs) {
50
+ if (!edgeAttrs) {
51
+ return;
52
+ }
53
+ if (edgeAttrs.reachesTop) {
54
+ cell.setAttribute('data-reaches-top', 'true');
55
+ }
56
+ if (edgeAttrs.reachesBottom) {
57
+ cell.setAttribute('data-reaches-bottom', 'true');
58
+ }
59
+ if (edgeAttrs.reachesLeft) {
60
+ cell.setAttribute('data-reaches-left', 'true');
61
+ }
62
+ if (edgeAttrs.reachesRight) {
63
+ cell.setAttribute('data-reaches-right', 'true');
64
+ }
65
+ };
24
66
  /**
25
67
  * Extracts information about deleted table rows from a change
26
68
  */
27
- var extractChangedRows = function extractChangedRows(_ref) {
28
- var change = _ref.change,
29
- originalDoc = _ref.originalDoc,
30
- newDoc = _ref.newDoc,
31
- diffType = _ref.diffType;
69
+ var extractChangedRows = function extractChangedRows(_ref2) {
70
+ var change = _ref2.change,
71
+ originalDoc = _ref2.originalDoc,
72
+ newDoc = _ref2.newDoc,
73
+ diffType = _ref2.diffType;
32
74
  var changedRows = [];
33
75
 
34
76
  // Find the table in the original document
@@ -69,12 +111,18 @@ var extractChangedRows = function extractChangedRows(_ref) {
69
111
  // Check if this row overlaps with the deletion range
70
112
  var rowOverlapsChange = rowStart >= changeStartInTable && rowStart < changeEndInTable || rowEnd > changeStartInTable && rowEnd <= changeEndInTable || rowStart < changeStartInTable && rowEnd > changeEndInTable;
71
113
  if (rowOverlapsChange && rowNode.type.name === 'tableRow' && ((0, _isExtendedEnabled.isExtendedEnabled)(diffType) || !isEmptyRow(rowNode))) {
114
+ var cellEdgeAttrs = (0, _isExtendedEnabled.isExtendedEnabled)(diffType) && (0, _expValEquals.expValEquals)('platform_editor_table_diff_rounded_corners', 'isEnabled', true) ? getChangedRowCellEdgeAttrs({
115
+ rowNode: rowNode,
116
+ rowStart: rowStart,
117
+ tableMap: oldTableMap
118
+ }) : undefined;
72
119
  var startOfRow = newTableMap.mapByRow.slice().reverse().find(function (row) {
73
120
  return row[0] + tableNew.pos < change.fromB && change.fromB < row[row.length - 1] + tableNew.pos;
74
121
  });
75
122
  changedRows.push({
76
123
  rowIndex: rowIndex,
77
124
  rowNode: rowNode,
125
+ cellEdgeAttrs: cellEdgeAttrs,
78
126
  fromA: tableOld.pos + 1 + rowStart,
79
127
  toA: tableOld.pos + 1 + rowEnd,
80
128
  fromB: startOfRow ? startOfRow[0] + tableNew.start : change.fromB
@@ -123,7 +171,7 @@ var isEmptyRow = function isEmptyRow(rowNode) {
123
171
  /**
124
172
  * Creates a DOM representation of a deleted table row
125
173
  */
126
- var createChangedRowDOM = function createChangedRowDOM(rowNode, nodeViewSerializer, colorScheme, isInserted, diffType) {
174
+ var createChangedRowDOM = function createChangedRowDOM(rowNode, cellEdgeAttrs, nodeViewSerializer, colorScheme, isInserted, diffType) {
127
175
  var tr = document.createElement('tr');
128
176
  if ((0, _isExtendedEnabled.isExtendedEnabled)(diffType)) {
129
177
  if (!isInserted) {
@@ -135,15 +183,23 @@ var createChangedRowDOM = function createChangedRowDOM(rowNode, nodeViewSerializ
135
183
  tr.setAttribute('data-testid', 'show-diff-deleted-row');
136
184
 
137
185
  // Serialize each cell in the row
186
+ var cellIndex = 0;
138
187
  rowNode.content.forEach(function (cellNode) {
139
188
  if (cellNode.type.name === 'tableCell' || cellNode.type.name === 'tableHeader') {
140
189
  var nodeView = nodeViewSerializer.tryCreateNodeView(cellNode);
141
190
  if (nodeView) {
142
- if (nodeView instanceof HTMLElement && (0, _isExtendedEnabled.isExtendedEnabled)(diffType)) {
143
- var overlay = document.createElement('span');
144
- var overlayStyle = colorScheme === 'traditional' ? isInserted ? _traditional.traditionalAddedCellOverlayStyle : _traditional.deletedTraditionalCellOverlayStyle : isInserted ? _standard.addedCellOverlayStyle : _standard.deletedCellOverlayStyle;
145
- overlay.setAttribute('style', overlayStyle);
146
- nodeView.appendChild(overlay);
191
+ if (nodeView instanceof HTMLElement) {
192
+ applyCellEdgeAttrs(nodeView, cellEdgeAttrs === null || cellEdgeAttrs === void 0 ? void 0 : cellEdgeAttrs[cellIndex]);
193
+ if ((0, _isExtendedEnabled.isExtendedEnabled)(diffType)) {
194
+ var overlay = document.createElement('span');
195
+ var isRoundedTable = (0, _expValEquals.expValEquals)('platform_editor_table_diff_rounded_corners', 'isEnabled', true);
196
+ var isTraditional = colorScheme === 'traditional';
197
+ var deletedCellStyle = isTraditional ? _traditional.deletedTraditionalCellOverlayStyle : _standard.deletedCellOverlayStyle;
198
+ var addedCellStyle = isTraditional ? isRoundedTable ? _traditional.traditionalAddedCellOverlayRoundedStyle : _traditional.traditionalAddedCellOverlayStyle : isRoundedTable ? _standard.addedCellOverlayRoundedStyle : _standard.addedCellOverlayStyle;
199
+ var overlayStyle = isInserted ? addedCellStyle : deletedCellStyle;
200
+ overlay.setAttribute('style', overlayStyle);
201
+ nodeView.appendChild(overlay);
202
+ }
147
203
  }
148
204
  tr.appendChild(nodeView);
149
205
  } else {
@@ -153,6 +209,7 @@ var createChangedRowDOM = function createChangedRowDOM(rowNode, nodeViewSerializ
153
209
  tr.appendChild(serializedContent);
154
210
  }
155
211
  }
212
+ cellIndex++;
156
213
  }
157
214
  });
158
215
  return tr;
@@ -161,11 +218,11 @@ var createChangedRowDOM = function createChangedRowDOM(rowNode, nodeViewSerializ
161
218
  /**
162
219
  * Expands a diff to include whole changed rows when table rows are affected
163
220
  */
164
- var expandDiffForChangedRows = function expandDiffForChangedRows(_ref2) {
165
- var changes = _ref2.changes,
166
- originalDoc = _ref2.originalDoc,
167
- newDoc = _ref2.newDoc,
168
- diffType = _ref2.diffType;
221
+ var expandDiffForChangedRows = function expandDiffForChangedRows(_ref3) {
222
+ var changes = _ref3.changes,
223
+ originalDoc = _ref3.originalDoc,
224
+ newDoc = _ref3.newDoc,
225
+ diffType = _ref3.diffType;
169
226
  var rowInfo = [];
170
227
  var _iterator = _createForOfIteratorHelper(changes),
171
228
  _step;
@@ -194,15 +251,15 @@ var expandDiffForChangedRows = function expandDiffForChangedRows(_ref2) {
194
251
  /**
195
252
  * Main function to handle deleted rows - computes diff and creates decorations
196
253
  */
197
- var createChangedRowDecorationWidgets = exports.createChangedRowDecorationWidgets = function createChangedRowDecorationWidgets(_ref3) {
198
- var changes = _ref3.changes,
199
- originalDoc = _ref3.originalDoc,
200
- newDoc = _ref3.newDoc,
201
- nodeViewSerializer = _ref3.nodeViewSerializer,
202
- colorScheme = _ref3.colorScheme,
203
- _ref3$isInserted = _ref3.isInserted,
204
- isInserted = _ref3$isInserted === void 0 ? false : _ref3$isInserted,
205
- diffType = _ref3.diffType;
254
+ var createChangedRowDecorationWidgets = exports.createChangedRowDecorationWidgets = function createChangedRowDecorationWidgets(_ref4) {
255
+ var changes = _ref4.changes,
256
+ originalDoc = _ref4.originalDoc,
257
+ newDoc = _ref4.newDoc,
258
+ nodeViewSerializer = _ref4.nodeViewSerializer,
259
+ colorScheme = _ref4.colorScheme,
260
+ _ref4$isInserted = _ref4.isInserted,
261
+ isInserted = _ref4$isInserted === void 0 ? false : _ref4$isInserted,
262
+ diffType = _ref4.diffType;
206
263
  // First, expand the changes to include complete deleted rows
207
264
  var changedRows = expandDiffForChangedRows({
208
265
  changes: changes.filter(function (change) {
@@ -213,7 +270,7 @@ var createChangedRowDecorationWidgets = exports.createChangedRowDecorationWidget
213
270
  diffType: diffType
214
271
  });
215
272
  return changedRows.map(function (changedRow) {
216
- var rowDOM = createChangedRowDOM(changedRow.rowNode, nodeViewSerializer, colorScheme, isInserted, diffType);
273
+ var rowDOM = createChangedRowDOM(changedRow.rowNode, changedRow.cellEdgeAttrs, nodeViewSerializer, colorScheme, isInserted, diffType);
217
274
 
218
275
  // Find safe insertion position for the deleted row
219
276
  var safeInsertPos = (0, _findSafeInsertPos.findSafeInsertPos)(newDoc, changedRow.fromB - 1,
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.createInlineChangedDecoration = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
10
  var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
10
11
  var _view = require("@atlaskit/editor-prosemirror/view");
11
12
  var _isExtendedEnabled = require("../isExtendedEnabled");
@@ -13,9 +14,21 @@ var _standard = require("./colorSchemes/standard");
13
14
  var _traditional = require("./colorSchemes/traditional");
14
15
  var _createAnchorDecorationWidgets = require("./createAnchorDecorationWidgets");
15
16
  var _decorationKeys = require("./decorationKeys");
17
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
18
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
16
19
  var displayNoneStyle = (0, _lazyNodeView.convertToInlineCss)({
17
20
  display: 'none'
18
21
  });
22
+ var getAtomicInlineNodeClassName = function getAtomicInlineNodeClassName(inlineNodeName, colorScheme) {
23
+ var classNames = ['show-diff-atomic-inline-changed'];
24
+ if (inlineNodeName) {
25
+ classNames.push("show-diff-atomic-inline-changed-".concat(inlineNodeName));
26
+ }
27
+ if (colorScheme === 'traditional') {
28
+ classNames.push('show-diff-atomic-inline-changed-traditional');
29
+ }
30
+ return classNames.join(' ');
31
+ };
19
32
  /**
20
33
  * Inline decoration used for insertions as the content already exists in the document
21
34
  *
@@ -30,6 +43,8 @@ var createInlineChangedDecoration = exports.createInlineChangedDecoration = func
30
43
  isActive = _ref$isActive === void 0 ? false : _ref$isActive,
31
44
  _ref$isInserted = _ref.isInserted,
32
45
  isInserted = _ref$isInserted === void 0 ? true : _ref$isInserted,
46
+ _ref$isAtomicInlineNo = _ref.isAtomicInlineNode,
47
+ isAtomicInlineNode = _ref$isAtomicInlineNo === void 0 ? false : _ref$isAtomicInlineNo,
33
48
  _ref$shouldHideDelete = _ref.shouldHideDeleted,
34
49
  shouldHideDeleted = _ref$shouldHideDelete === void 0 ? false : _ref$shouldHideDelete,
35
50
  _ref$showIndicators = _ref.showIndicators,
@@ -37,7 +52,8 @@ var createInlineChangedDecoration = exports.createInlineChangedDecoration = func
37
52
  doc = _ref.doc,
38
53
  diffType = _ref.diffType,
39
54
  _ref$hideAddedDiffsUn = _ref.hideAddedDiffsUnderline,
40
- hideAddedDiffsUnderline = _ref$hideAddedDiffsUn === void 0 ? false : _ref$hideAddedDiffsUn;
55
+ hideAddedDiffsUnderline = _ref$hideAddedDiffsUn === void 0 ? false : _ref$hideAddedDiffsUn,
56
+ inlineNodeName = _ref.inlineNodeName;
41
57
  var diffId = crypto.randomUUID();
42
58
  if (shouldHideDeleted) {
43
59
  return [_view.Decoration.inline(change.fromB, change.toB, {
@@ -76,10 +92,13 @@ var createInlineChangedDecoration = exports.createInlineChangedDecoration = func
76
92
  style = isActive ? _standard.editingStyleActive : _standard.editingStyle;
77
93
  }
78
94
  }
79
- var decorations = [_view.Decoration.inline(change.fromB, change.toB, {
80
- style: style,
95
+ var decorations = [_view.Decoration.inline(change.fromB, change.toB, _objectSpread(_objectSpread({
96
+ style: style
97
+ }, isAtomicInlineNode && isInserted && {
98
+ class: getAtomicInlineNodeClassName(inlineNodeName, colorScheme)
99
+ }), {}, {
81
100
  'data-testid': 'show-diff-changed-decoration'
82
- }, (0, _decorationKeys.buildDiffDecorationSpec)({
101
+ }), (0, _decorationKeys.buildDiffDecorationSpec)({
83
102
  decorationType: 'inline',
84
103
  diffId: diffId,
85
104
  isActive: isActive
@@ -1,11 +1,16 @@
1
1
  "use strict";
2
2
 
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
3
4
  Object.defineProperty(exports, "__esModule", {
4
5
  value: true
5
6
  });
6
7
  exports.stepIsValidAttrChange = exports.getAttrChangeRanges = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
7
9
  var _steps = require("@atlaskit/adf-schema/steps");
8
10
  var _transform = require("@atlaskit/editor-prosemirror/transform");
11
+ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
12
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
13
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
9
14
  var filterUndefined = function filterUndefined(x) {
10
15
  return !!x;
11
16
  };
@@ -19,6 +24,26 @@ var dateAttrs = ['timestamp'];
19
24
  // Attribute that indicates a task item state change
20
25
  var taskItemAttrs = ['state'];
21
26
 
27
+ // Attributes that indicate an emoji change
28
+ var emojiAttrs = ['shortName', 'id', 'text'];
29
+
30
+ // Attributes that indicate a mention change (who is mentioned)
31
+ var mentionAttrs = ['id', 'text'];
32
+
33
+ // Attributes that indicate a status change (label or colour)
34
+ var statusAttrs = ['text', 'color'];
35
+
36
+ // Map of node type name → the attrs that represent a meaningful content change for that node
37
+ var inlineNodeAttrMap = {
38
+ date: dateAttrs,
39
+ emoji: emojiAttrs,
40
+ mention: mentionAttrs,
41
+ status: statusAttrs
42
+ };
43
+ var isInlineAttrChangeNodeName = function isInlineAttrChangeNodeName(nodeName) {
44
+ return nodeName in inlineNodeAttrMap;
45
+ };
46
+
22
47
  // Attributes excluded from extension change detection (not meaningful content changes)
23
48
  var extensionExcludedAttrs = ['localId'];
24
49
 
@@ -33,7 +58,7 @@ var getStepAttrs = function getStepAttrs(step) {
33
58
  }
34
59
  return [];
35
60
  };
36
- var getAttrChangeRanges = exports.getAttrChangeRanges = function getAttrChangeRanges(doc, steps) {
61
+ var getAttrChangeRanges = exports.getAttrChangeRanges = function getAttrChangeRanges(doc, steps, originalDoc) {
37
62
  return steps.map(function (step) {
38
63
  if (!(step instanceof _transform.AttrStep) && !(step instanceof _steps.SetAttrsStep)) {
39
64
  return undefined;
@@ -45,14 +70,39 @@ var getAttrChangeRanges = exports.getAttrChangeRanges = function getAttrChangeRa
45
70
  // date node: timestamp attribute change — highlight the date node itself (inline)
46
71
  if (stepAttrs.some(function (v) {
47
72
  return dateAttrs.includes(v);
48
- }) && (nodeAtPos === null || nodeAtPos === void 0 ? void 0 : nodeAtPos.type.name) === 'date') {
73
+ }) && (nodeAtPos === null || nodeAtPos === void 0 ? void 0 : nodeAtPos.type.name) === 'date' && !(0, _expValEquals.expValEquals)('platform_editor_improve_inline_diffs', 'isEnabled', true)) {
49
74
  return {
50
75
  fromB: step.pos,
51
76
  toB: step.pos + nodeAtPos.nodeSize,
52
- isInline: true
77
+ isInline: true,
78
+ inlineNodeName: 'date'
53
79
  };
54
80
  }
55
81
 
82
+ // The following inline node attr changes are gated behind platform_editor_improve_inline_diffs.
83
+ // The changeset path (createDecorationsForChange) handles the deletion widget via
84
+ // prosemirror-changeset; we only need to add the inline insertion highlight here.
85
+ if ((0, _expValEquals.expValEquals)('platform_editor_improve_inline_diffs', 'isEnabled', true) && nodeAtPos) {
86
+ var nodeName = nodeAtPos.type.name;
87
+ if (isInlineAttrChangeNodeName(nodeName)) {
88
+ var watchedAttrs = inlineNodeAttrMap[nodeName];
89
+ if (stepAttrs.some(function (v) {
90
+ return watchedAttrs.includes(v);
91
+ })) {
92
+ var originalNodeAtPos = originalDoc === null || originalDoc === void 0 ? void 0 : originalDoc.nodeAt(step.pos);
93
+ return _objectSpread({
94
+ fromB: step.pos,
95
+ toB: step.pos + nodeAtPos.nodeSize,
96
+ isInline: true,
97
+ inlineNodeName: nodeName
98
+ }, originalNodeAtPos && {
99
+ fromA: step.pos,
100
+ toA: step.pos + originalNodeAtPos.nodeSize
101
+ });
102
+ }
103
+ }
104
+ }
105
+
56
106
  // taskItem node: state attribute change — highlight the taskItem node
57
107
  if (stepAttrs.some(function (v) {
58
108
  return taskItemAttrs.includes(v);
@@ -86,7 +136,17 @@ var getAttrChangeRanges = exports.getAttrChangeRanges = function getAttrChangeRa
86
136
  };
87
137
  }
88
138
  return undefined;
89
- }).filter(filterUndefined);
139
+ }).filter(filterUndefined)
140
+ // Deduplicate by node position: multiple AttrSteps on the same node
141
+ // (e.g. setNodeAttribute(pos, 'text', ...) + setNodeAttribute(pos, 'color', ...))
142
+ // should produce only one decoration, not one per step.
143
+ // Gated behind the same experiment as the inline node attr changes that introduced
144
+ // the possibility of multiple ranges for the same node position.
145
+ .filter(function (range, i, arr) {
146
+ return !(0, _expValEquals.expValEquals)('platform_editor_improve_inline_diffs', 'isEnabled', true) || arr.findIndex(function (r) {
147
+ return r.fromB === range.fromB;
148
+ }) === i;
149
+ });
90
150
  };
91
151
 
92
152
  /**
@@ -390,16 +390,43 @@ const calculateDiffDecorationsInner = ({
390
390
  isInserted: true
391
391
  }));
392
392
  });
393
- getAttrChangeRanges(tr.doc, attrSteps).forEach(change => {
393
+ getAttrChangeRanges(tr.doc, attrSteps, originalDoc).forEach(change => {
394
394
  if (change.isInline) {
395
- // Inline nodes (e.g. date) need an inline decoration rather than a block decoration
395
+ // Inline nodes (e.g. date, emoji, mention, status) need an inline decoration rather than a block decoration
396
396
  const isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
397
+ const isAtomicInlineNodeFlag = expValEquals('platform_editor_improve_inline_diffs', 'isEnabled', true);
397
398
  decorations.push(...createInlineChangedDecoration({
398
399
  change,
399
400
  colorScheme,
400
401
  isActive,
401
- isInserted: true
402
+ isInserted: true,
403
+ isAtomicInlineNode: isAtomicInlineNodeFlag,
404
+ inlineNodeName: change.inlineNodeName,
405
+ // Suppress the border-bottom underline for atomic inline nodeviews —
406
+ // it doesn't render on custom nodeview DOM elements and is unnecessary noise.
407
+ hideAddedDiffsUnderline: isAtomicInlineNodeFlag,
408
+ diffType
402
409
  }));
410
+ // If we have the original node position, also render the old node as a "deleted" widget
411
+ // so the user can see what it looked like before the change.
412
+ if (change.fromA !== undefined && change.toA !== undefined && expValEquals('platform_editor_improve_inline_diffs', 'isEnabled', true)) {
413
+ decorations.push(...createNodeChangedDecorationWidget({
414
+ change: {
415
+ fromA: change.fromA,
416
+ toA: change.toA,
417
+ fromB: change.fromB,
418
+ toB: change.toB,
419
+ deleted: []
420
+ },
421
+ doc: originalDoc,
422
+ nodeViewSerializer,
423
+ colorScheme,
424
+ newDoc: tr.doc,
425
+ intl,
426
+ activeIndexPos,
427
+ isInserted: false
428
+ }));
429
+ }
403
430
  } else {
404
431
  decorations.push(...calculateNodesForBlockDecoration({
405
432
  doc: tr.doc,
@@ -170,6 +170,18 @@ export const addedCellOverlayStyle = convertToInlineCss({
170
170
  outline: `1px solid ${"var(--ds-border-accent-purple, #AF59E1)"}`,
171
171
  pointerEvents: 'none'
172
172
  });
173
+ export const addedCellOverlayRoundedStyle = convertToInlineCss({
174
+ position: 'absolute',
175
+ top: 0,
176
+ left: 0,
177
+ width: '100%',
178
+ height: '100%',
179
+ backgroundColor: `rgba(from ${"var(--ds-background-accent-purple-subtlest, #F8EEFE)"} r g b / 0.5)`,
180
+ zIndex: 2,
181
+ outline: `1px solid ${"var(--ds-border-accent-purple, #AF59E1)"}`,
182
+ pointerEvents: 'none',
183
+ borderRadius: 'inherit'
184
+ });
173
185
  export const deletedCellOverlayStyle = convertToInlineCss({
174
186
  position: 'absolute',
175
187
  top: 0,
@@ -82,7 +82,7 @@ export const deletedTraditionalBlockOutlineRoundedActive = convertToInlineCss({
82
82
  borderRadius: `calc(${"var(--ds-radius-xsmall, 2px)"} + 1px)`
83
83
  });
84
84
 
85
- /** Scroll-navigation “new” emphasis: 4px ring (see {@link traditionalStyleNodeNew}). */
85
+ /** Scroll-navigation “new” emphasis: 4px ring. */
86
86
  export const deletedTraditionalBlockOutlineNew = convertToInlineCss({
87
87
  boxShadow: `0 0 0 4px ${"var(--ds-background-accent-red-subtlest, #FFECEB)"}`,
88
88
  borderRadius: "var(--ds-radius-small, 4px)"
@@ -185,6 +185,19 @@ export const traditionalAddedCellOverlayStyle = convertToInlineCss({
185
185
  outline: `1px solid ${"var(--ds-border-accent-green, #22A06B)"}`,
186
186
  pointerEvents: 'none'
187
187
  });
188
+ export const traditionalAddedCellOverlayRoundedStyle = convertToInlineCss({
189
+ position: 'absolute',
190
+ top: 0,
191
+ left: 0,
192
+ width: '100%',
193
+ height: '100%',
194
+ backgroundColor: `rgba(from ${"var(--ds-background-accent-green-subtlest, #DCFFF1)"} r g b / 0.5)`,
195
+ zIndex: 2,
196
+ outline: `1px solid ${"var(--ds-border-accent-green, #22A06B)"}`,
197
+ pointerEvents: 'none',
198
+ border: 'inherit',
199
+ borderRadius: 'inherit'
200
+ });
188
201
  export const traditionalAddedCellOverlayStyleNew = convertToInlineCss({
189
202
  position: 'absolute',
190
203
  top: 0,