@atlaskit/editor-plugin-show-diff 16.0.3 → 16.0.5

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 (22) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +12 -1
  3. package/dist/cjs/pm-plugins/calculateDiff/isOpenTokenOnlyChange.js +32 -0
  4. package/dist/cjs/pm-plugins/decorations/createAnchorDecorationWidgets.js +13 -1
  5. package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +6 -6
  6. package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +8 -10
  7. package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +2 -1
  8. package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +12 -1
  9. package/dist/es2019/pm-plugins/calculateDiff/isOpenTokenOnlyChange.js +27 -0
  10. package/dist/es2019/pm-plugins/decorations/createAnchorDecorationWidgets.js +13 -1
  11. package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +6 -6
  12. package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +6 -8
  13. package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +2 -1
  14. package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +12 -1
  15. package/dist/esm/pm-plugins/calculateDiff/isOpenTokenOnlyChange.js +26 -0
  16. package/dist/esm/pm-plugins/decorations/createAnchorDecorationWidgets.js +13 -1
  17. package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +6 -6
  18. package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +8 -10
  19. package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +2 -1
  20. package/dist/types/pm-plugins/calculateDiff/isOpenTokenOnlyChange.d.ts +22 -0
  21. package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.d.ts +2 -3
  22. package/package.json +3 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @atlaskit/editor-plugin-show-diff
2
2
 
3
+ ## 16.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 16.0.4
10
+
11
+ ### Patch Changes
12
+
13
+ - [`d12940d0a5964`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d12940d0a5964) -
14
+ Fix layout and decision diff underlines and attribution colors, preserve column width styles, and
15
+ align the blue indicator outside layout column borders under platform_editor_ai_show_diff_patch_1.
16
+ - [`f044fcdd726df`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f044fcdd726df) -
17
+ [EDITOR-8912] Under `platform_editor_ai_show_diff_patch_1`, a change that spans only a block
18
+ node's open token no longer draws a deleted-content widget. A same-type node replacement (an AI
19
+ suggestion rewriting a code block, say) reports the node's attribute change separately from its
20
+ content change, and the attribute half has no deleted content — it rendered as an empty copy of
21
+ the block, e.g. an empty code block above the real diff. Its inserted side, and the node's content
22
+ change, are unaffected.
23
+ - Updated dependencies
24
+
3
25
  ## 16.0.3
4
26
 
5
27
  ### Patch Changes
@@ -32,6 +32,7 @@ var _isExtendedEnabled = require("../isExtendedEnabled");
32
32
  var _diffBySteps = require("./diffBySteps");
33
33
  var _groupChangesByBlock = require("./groupChangesByBlock");
34
34
  var _isMarkOnlyChange = require("./isMarkOnlyChange");
35
+ var _isOpenTokenOnlyChange = require("./isOpenTokenOnlyChange");
35
36
  var _optimizeChanges = require("./optimizeChanges");
36
37
  var _selectTokenEncoder2 = require("./selectTokenEncoder");
37
38
  var _simplifyChangesWithAttribution = require("./simplifyChangesWithAttribution");
@@ -505,6 +506,16 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
505
506
  newDoc: tr.doc
506
507
  });
507
508
 
509
+ // The deleted side of a change over a node's open token is an attribute state rather than
510
+ // content, so there is nothing for the deleted-content widget to draw. Decided here, with
511
+ // the other deleted-side suppressions, so the widget is never asked for a slice it can only
512
+ // render as an empty copy of the block (EDITOR-8912). Its inserted side is untouched, and
513
+ // the node's content change is a change of its own.
514
+ var hasNoDeletedContent = (0, _fg.fg)('platform_editor_ai_show_diff_patch_1') && change.deleted.length > 0 && (0, _isOpenTokenOnlyChange.isOpenTokenOnlyChange)({
515
+ change: change,
516
+ originalDoc: originalDoc
517
+ });
518
+
508
519
  // Hoisted because it decides BOTH where the deleted widget is anchored and — since the
509
520
  // widget pins whichever end of the range it sits at — how the indicator anchors below are
510
521
  // allowed to move.
@@ -623,7 +634,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
623
634
  coarseTableCellsOnly: useCoarseTableDecoration
624
635
  }))));
625
636
  }
626
- if (change.deleted.length > 0 && !isMarkOnly) {
637
+ if (change.deleted.length > 0 && !isMarkOnly && !hasNoDeletedContent) {
627
638
  var _shouldHideDeleted = shouldHideDeletedSide({
628
639
  change: change,
629
640
  diffType: diffType,
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.isOpenTokenOnlyChange = void 0;
7
+ /**
8
+ * Whether a change spans nothing but a block node's open token, so its deleted side carries no
9
+ * content.
10
+ *
11
+ * The attribute-aware token encoder folds a node's diffable attributes into its open token, so a
12
+ * same-type replacement — an AI suggestion rewriting a code block — is reported as two changes: one
13
+ * over the single position of that token, carrying the attribute change, and one for the content.
14
+ * Slicing the first yields the node with none of its content, which leaves the deleted-content
15
+ * widget nothing to draw but an empty copy of the block (EDITOR-8912). The content change is a
16
+ * change of its own and is decorated in place.
17
+ *
18
+ * A whole node is not matched: its range covers its close token too. Neither is an empty leaf (a
19
+ * `rule`, a `blockCard`), which is one position but slices closed rather than open.
20
+ */
21
+ var isOpenTokenOnlyChange = exports.isOpenTokenOnlyChange = function isOpenTokenOnlyChange(_ref) {
22
+ var change = _ref.change,
23
+ originalDoc = _ref.originalDoc;
24
+ if (change.toA - change.fromA !== 1) {
25
+ return false;
26
+ }
27
+ var slice = originalDoc.slice(change.fromA, change.toA);
28
+ // `childCount === 1` already means `firstChild` is there; the optional chain is for the type,
29
+ // which has it nullable.
30
+ var node = slice.content.firstChild;
31
+ return (slice.openStart > 0 || slice.openEnd > 0) && slice.content.childCount === 1 && (node === null || node === void 0 ? void 0 : node.isBlock) === true && node.content.size === 0;
32
+ };
@@ -51,6 +51,16 @@ var edgeCases = function edgeCases(doc, from) {
51
51
  var node = resolved.node,
52
52
  nodeStart = resolved.nodeStart,
53
53
  beforePos = resolved.beforePos;
54
+ if (node.type.name === 'layoutSection' && (0, _fg.fg)('platform_editor_ai_show_diff_patch_1')) {
55
+ // Columns extend past the node-view wrapper via negative margins (12px or 20px).
56
+ // Measure their container so the indicator stays outside the diff outline, including
57
+ // breakout layouts and after responsive resizing, without changing the column geometry.
58
+ return {
59
+ beforePos: beforePos,
60
+ measurePos: beforePos,
61
+ measureSelector: '[data-layout-section]'
62
+ };
63
+ }
54
64
 
55
65
  /**
56
66
  * All resizable nodes will need dynamic calculations of the block indicator left anchor
@@ -158,10 +168,12 @@ var createLeftAnchorWidget = exports.createLeftAnchorWidget = function createLef
158
168
  anchor.style.setProperty('transform', 'translateX(-50%)');
159
169
  wrapper.appendChild(anchor);
160
170
  var measureWidth = function measureWidth() {
171
+ var _nodeDOM$querySelecto;
161
172
  if (getPos() === undefined || edgeCase.measurePos === undefined) {
162
173
  return;
163
174
  }
164
- var dom = view.nodeDOM(edgeCase.measurePos);
175
+ var nodeDOM = view.nodeDOM(edgeCase.measurePos);
176
+ var dom = edgeCase.measureSelector && nodeDOM instanceof HTMLElement ? (_nodeDOM$querySelecto = nodeDOM.querySelector(edgeCase.measureSelector)) !== null && _nodeDOM$querySelecto !== void 0 ? _nodeDOM$querySelecto : nodeDOM : nodeDOM;
165
177
  if (dom instanceof HTMLElement) {
166
178
  // The left anchor only needs the container width so the
167
179
  // IndicatorBar can align against the block's horizontal extent.
@@ -217,25 +217,25 @@ var applyMultiContainerLikeStyles = function applyMultiContainerLikeStyles(_ref6
217
217
  var targetNodeName = (0, _expValEquals.expValEquals)('platform_editor_nest_table_in_panel', 'isEnabled', true) ? (0, _nodeTypeUtils.getBaseNodeTypeName)(targetNode.type) : targetNode.type.name;
218
218
  var nodeSpecificStyle = (0, _wrapBlockNodeViewStyles.getChangedNodeStyle)(targetNodeName, colorScheme, isInserted, isActive, diffType, hideAddedDiffsUnderline) || '';
219
219
  if (targetNode.type.name === 'decisionList') {
220
- var nestedInsertedNodeStyle = (0, _wrapBlockNodeViewStyles.resolveNestedInsertedNodeStyle)();
220
+ var nestedInsertedNodeStyle = (0, _wrapBlockNodeViewStyles.resolveNestedInsertedNodeStyle)(colorScheme);
221
221
  element.querySelectorAll('li').forEach(function (listItem) {
222
222
  var currentListItemStyle = listItem.getAttribute('style') || '';
223
- listItem.setAttribute('style', "".concat(currentListItemStyle).concat(nestedInsertedNodeStyle));
223
+ listItem.setAttribute('style', (0, _fg.fg)('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentListItemStyle, nestedInsertedNodeStyle) : "".concat(currentListItemStyle).concat(nestedInsertedNodeStyle));
224
224
  });
225
225
  } else if (targetNode.type.name === 'layoutSection') {
226
- var _nestedInsertedNodeStyle = (0, _wrapBlockNodeViewStyles.resolveNestedInsertedNodeStyle)();
226
+ var _nestedInsertedNodeStyle = (0, _wrapBlockNodeViewStyles.resolveNestedInsertedNodeStyle)(colorScheme);
227
227
  element.querySelectorAll('[data-layout-column="true"]').forEach(function (section) {
228
228
  var currentSectionStyle = section.getAttribute('style') || '';
229
- section.setAttribute('style', "".concat(currentSectionStyle).concat(_nestedInsertedNodeStyle));
229
+ section.setAttribute('style', (0, _fg.fg)('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentSectionStyle, _nestedInsertedNodeStyle) : "".concat(currentSectionStyle).concat(_nestedInsertedNodeStyle));
230
230
  });
231
231
  } else if (targetNode.type.name === 'taskList') {
232
- var _nestedInsertedNodeStyle2 = (0, _wrapBlockNodeViewStyles.resolveNestedInsertedNodeStyle)();
232
+ var _nestedInsertedNodeStyle2 = (0, _wrapBlockNodeViewStyles.resolveNestedInsertedNodeStyle)(colorScheme);
233
233
  element.querySelectorAll('li').forEach(function (listItem) {
234
234
  var currentListItemStyle = listItem.getAttribute('style') || '';
235
235
  listItem.setAttribute('style', "".concat(currentListItemStyle).concat(_nestedInsertedNodeStyle2));
236
236
  });
237
237
  }
238
- element.setAttribute('style', "".concat(currentStyle, ";").concat(nodeSpecificStyle));
238
+ element.setAttribute('style', (0, _fg.fg)('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentStyle, nodeSpecificStyle) : "".concat(currentStyle, ";").concat(nodeSpecificStyle));
239
239
  };
240
240
  var combineStyles = function combineStyles(currentStyle, appendedStyle) {
241
241
  var separator = currentStyle && appendedStyle && !currentStyle.trimEnd().endsWith(';') ? '; ' : '';
@@ -7,6 +7,7 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.resolveRemovedLozengeStyle = exports.resolveNestedInsertedNodeStyle = exports.resolveDeletedNodeCSSVariables = exports.resolveCellOverlayStyle = exports.isTextLikeBlockNode = exports.isMultiContainerBlockNode = exports.hasRestingDeletedRing = exports.getInsertedContentStyle = exports.getDeletedContentStyleUnbounded = exports.getDeletedContentStyle = exports.getChangedNodeStyle = exports.getChangedContentStyle = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
10
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
10
11
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
11
12
  var _isExtendedEnabled = require("../../isExtendedEnabled");
12
13
  var _factory = require("../colorSchemes/factory");
@@ -30,9 +31,7 @@ var getColorScheme = function getColorScheme(colorScheme) {
30
31
  };
31
32
 
32
33
  /**
33
- * Inserted content inside a multi-container or list node always uses the standard scheme, so a
34
- * traditional diff shows purple here. Pre-existing: these call sites predate traditional.
35
- * Preserved as-is; see EDITOR-8281.
34
+ * Preserve the historical purple nested outlines when the layout/decision diff patch is off.
36
35
  */
37
36
  var nestedContentScheme = _schemes.standardScheme;
38
37
 
@@ -68,7 +67,7 @@ var getChangedNodeStyleNext = function getChangedNodeStyleNext(nodeName, colorSc
68
67
  var colors = getColorScheme(colorScheme);
69
68
  if ((0, _isExtendedEnabled.isExtendedEnabled)(diffType) && isInserted) {
70
69
  if (isMultiContainerBlockNode(nodeName)) {
71
- return hideAddedDiffsUnderline ? (0, _factory.buildInsertStyleInBlockExtendedNoUnderline)(nestedContentScheme) : (0, _factory.buildInsertStyleInBlockExtended)(nestedContentScheme);
70
+ return hideAddedDiffsUnderline || (0, _fg.fg)('platform_editor_ai_show_diff_patch_1') ? (0, _factory.buildInsertStyleInBlockExtendedNoUnderline)(nestedContentScheme) : (0, _factory.buildInsertStyleInBlockExtended)(nestedContentScheme);
72
71
  }
73
72
  if (isTextLikeBlockNode(nodeName)) {
74
73
  return undefined;
@@ -129,8 +128,8 @@ var resolveRemovedLozengeStyleNext = function resolveRemovedLozengeStyleNext(col
129
128
  var colors = getColorScheme(colorScheme);
130
129
  return isActive ? (0, _factory.buildDeletedLozengeActiveStyle)(colors) : (0, _factory.buildDeletedLozengeStyle)(colors);
131
130
  };
132
- var resolveNestedInsertedNodeStyleNext = function resolveNestedInsertedNodeStyleNext() {
133
- return (0, _factory.buildInsertStyleNode)(nestedContentScheme);
131
+ var resolveNestedInsertedNodeStyleNext = function resolveNestedInsertedNodeStyleNext(colorScheme) {
132
+ return (0, _factory.buildInsertStyleNode)((0, _fg.fg)('platform_editor_ai_show_diff_patch_1') ? getColorScheme(colorScheme) : nestedContentScheme);
134
133
  };
135
134
 
136
135
  // Only 'stateful' schemes have a resting ring.
@@ -194,11 +193,10 @@ var resolveRemovedLozengeStyle = exports.resolveRemovedLozengeStyle = function r
194
193
 
195
194
  /**
196
195
  * Style for inserted content nested inside a multi-container or list node — the `decisionList` and
197
- * `taskList` `li`s and the `layoutSection` columns. Scheme-independent: see
198
- * `nestedContentScheme` above.
196
+ * `taskList` `li`s and the `layoutSection` columns.
199
197
  */
200
- var resolveNestedInsertedNodeStyle = exports.resolveNestedInsertedNodeStyle = function resolveNestedInsertedNodeStyle() {
201
- return (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_show_diff_color_scheme_refactor') ? resolveNestedInsertedNodeStyleNext() : (0, _wrapBlockNodeViewStyles.resolveNestedInsertedNodeStyleLegacy)();
198
+ var resolveNestedInsertedNodeStyle = exports.resolveNestedInsertedNodeStyle = function resolveNestedInsertedNodeStyle(colorScheme) {
199
+ return (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_show_diff_color_scheme_refactor') ? resolveNestedInsertedNodeStyleNext(colorScheme) : (0, _wrapBlockNodeViewStyles.resolveNestedInsertedNodeStyleLegacy)();
202
200
  };
203
201
 
204
202
  /**
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.resolveRemovedLozengeStyleLegacy = exports.resolveNestedInsertedNodeStyleLegacy = exports.resolveCellOverlayStyleLegacy = exports.hasRestingDeletedRingLegacy = exports.getInsertedContentStyleLegacy = exports.getDeletedContentStyleUnboundedLegacy = exports.getDeletedContentStyleLegacy = exports.getChangedNodeStyleLegacy = exports.getChangedContentStyleLegacy = void 0;
7
7
  var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
8
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
8
9
  var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
9
10
  var _isExtendedEnabled = require("../../isExtendedEnabled");
10
11
  var _standard = require("../colorSchemes/standard");
@@ -112,7 +113,7 @@ var getChangedNodeStyleLegacy = exports.getChangedNodeStyleLegacy = function get
112
113
  var isTraditional = colorScheme === 'traditional';
113
114
  if ((0, _isExtendedEnabled.isExtendedEnabled)(diffType) && isInserted) {
114
115
  if (isMultiContainerBlockNode(nodeName)) {
115
- return hideAddedDiffsUnderline ? _standard.editingContentStyleInBlockExtendedNoUnderline : _standard.editingContentStyleInBlockExtended;
116
+ return hideAddedDiffsUnderline || (0, _fg.fg)('platform_editor_ai_show_diff_patch_1') ? _standard.editingContentStyleInBlockExtendedNoUnderline : _standard.editingContentStyleInBlockExtended;
116
117
  }
117
118
  if (isTextLikeBlockNode(nodeName)) {
118
119
  return undefined;
@@ -22,6 +22,7 @@ import { getDefaultDiffType, isExtendedEnabled } from '../isExtendedEnabled';
22
22
  import { diffBySteps } from './diffBySteps';
23
23
  import { groupChangesByBlock } from './groupChangesByBlock';
24
24
  import { isMarkOnlyChange } from './isMarkOnlyChange';
25
+ import { isOpenTokenOnlyChange } from './isOpenTokenOnlyChange';
25
26
  import { optimizeChanges } from './optimizeChanges';
26
27
  import { selectTokenEncoder } from './selectTokenEncoder';
27
28
  import { collapseOverlappingChanges, simplifyChangesWithAttribution } from './simplifyChangesWithAttribution';
@@ -464,6 +465,16 @@ const calculateDiffDecorationsInner = ({
464
465
  newDoc: tr.doc
465
466
  });
466
467
 
468
+ // The deleted side of a change over a node's open token is an attribute state rather than
469
+ // content, so there is nothing for the deleted-content widget to draw. Decided here, with
470
+ // the other deleted-side suppressions, so the widget is never asked for a slice it can only
471
+ // render as an empty copy of the block (EDITOR-8912). Its inserted side is untouched, and
472
+ // the node's content change is a change of its own.
473
+ const hasNoDeletedContent = fg('platform_editor_ai_show_diff_patch_1') && change.deleted.length > 0 && isOpenTokenOnlyChange({
474
+ change,
475
+ originalDoc
476
+ });
477
+
467
478
  // Hoisted because it decides BOTH where the deleted widget is anchored and — since the
468
479
  // widget pins whichever end of the range it sits at — how the indicator anchors below are
469
480
  // allowed to move.
@@ -573,7 +584,7 @@ const calculateDiffDecorationsInner = ({
573
584
  coarseTableCellsOnly: useCoarseTableDecoration
574
585
  }));
575
586
  }
576
- if (change.deleted.length > 0 && !isMarkOnly) {
587
+ if (change.deleted.length > 0 && !isMarkOnly && !hasNoDeletedContent) {
577
588
  const shouldHideDeleted = shouldHideDeletedSide({
578
589
  change,
579
590
  diffType,
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Whether a change spans nothing but a block node's open token, so its deleted side carries no
3
+ * content.
4
+ *
5
+ * The attribute-aware token encoder folds a node's diffable attributes into its open token, so a
6
+ * same-type replacement — an AI suggestion rewriting a code block — is reported as two changes: one
7
+ * over the single position of that token, carrying the attribute change, and one for the content.
8
+ * Slicing the first yields the node with none of its content, which leaves the deleted-content
9
+ * widget nothing to draw but an empty copy of the block (EDITOR-8912). The content change is a
10
+ * change of its own and is decorated in place.
11
+ *
12
+ * A whole node is not matched: its range covers its close token too. Neither is an empty leaf (a
13
+ * `rule`, a `blockCard`), which is one position but slices closed rather than open.
14
+ */
15
+ export const isOpenTokenOnlyChange = ({
16
+ change,
17
+ originalDoc
18
+ }) => {
19
+ if (change.toA - change.fromA !== 1) {
20
+ return false;
21
+ }
22
+ const slice = originalDoc.slice(change.fromA, change.toA);
23
+ // `childCount === 1` already means `firstChild` is there; the optional chain is for the type,
24
+ // which has it nullable.
25
+ const node = slice.content.firstChild;
26
+ return (slice.openStart > 0 || slice.openEnd > 0) && slice.content.childCount === 1 && (node === null || node === void 0 ? void 0 : node.isBlock) === true && node.content.size === 0;
27
+ };
@@ -44,6 +44,16 @@ const edgeCases = (doc, from) => {
44
44
  nodeStart,
45
45
  beforePos
46
46
  } = resolved;
47
+ if (node.type.name === 'layoutSection' && fg('platform_editor_ai_show_diff_patch_1')) {
48
+ // Columns extend past the node-view wrapper via negative margins (12px or 20px).
49
+ // Measure their container so the indicator stays outside the diff outline, including
50
+ // breakout layouts and after responsive resizing, without changing the column geometry.
51
+ return {
52
+ beforePos,
53
+ measurePos: beforePos,
54
+ measureSelector: '[data-layout-section]'
55
+ };
56
+ }
47
57
 
48
58
  /**
49
59
  * All resizable nodes will need dynamic calculations of the block indicator left anchor
@@ -152,10 +162,12 @@ export const createLeftAnchorWidget = ({
152
162
  anchor.style.setProperty('transform', 'translateX(-50%)');
153
163
  wrapper.appendChild(anchor);
154
164
  const measureWidth = () => {
165
+ var _nodeDOM$querySelecto;
155
166
  if (getPos() === undefined || edgeCase.measurePos === undefined) {
156
167
  return;
157
168
  }
158
- const dom = view.nodeDOM(edgeCase.measurePos);
169
+ const nodeDOM = view.nodeDOM(edgeCase.measurePos);
170
+ const dom = edgeCase.measureSelector && nodeDOM instanceof HTMLElement ? (_nodeDOM$querySelecto = nodeDOM.querySelector(edgeCase.measureSelector)) !== null && _nodeDOM$querySelecto !== void 0 ? _nodeDOM$querySelecto : nodeDOM : nodeDOM;
159
171
  if (dom instanceof HTMLElement) {
160
172
  // The left anchor only needs the container width so the
161
173
  // IndicatorBar can align against the block's horizontal extent.
@@ -206,25 +206,25 @@ const applyMultiContainerLikeStyles = ({
206
206
  const targetNodeName = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? getBaseNodeTypeName(targetNode.type) : targetNode.type.name;
207
207
  const nodeSpecificStyle = getChangedNodeStyle(targetNodeName, colorScheme, isInserted, isActive, diffType, hideAddedDiffsUnderline) || '';
208
208
  if (targetNode.type.name === 'decisionList') {
209
- const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
209
+ const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle(colorScheme);
210
210
  element.querySelectorAll('li').forEach(listItem => {
211
211
  const currentListItemStyle = listItem.getAttribute('style') || '';
212
- listItem.setAttribute('style', `${currentListItemStyle}${nestedInsertedNodeStyle}`);
212
+ listItem.setAttribute('style', fg('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentListItemStyle, nestedInsertedNodeStyle) : `${currentListItemStyle}${nestedInsertedNodeStyle}`);
213
213
  });
214
214
  } else if (targetNode.type.name === 'layoutSection') {
215
- const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
215
+ const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle(colorScheme);
216
216
  element.querySelectorAll('[data-layout-column="true"]').forEach(section => {
217
217
  const currentSectionStyle = section.getAttribute('style') || '';
218
- section.setAttribute('style', `${currentSectionStyle}${nestedInsertedNodeStyle}`);
218
+ section.setAttribute('style', fg('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentSectionStyle, nestedInsertedNodeStyle) : `${currentSectionStyle}${nestedInsertedNodeStyle}`);
219
219
  });
220
220
  } else if (targetNode.type.name === 'taskList') {
221
- const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
221
+ const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle(colorScheme);
222
222
  element.querySelectorAll('li').forEach(listItem => {
223
223
  const currentListItemStyle = listItem.getAttribute('style') || '';
224
224
  listItem.setAttribute('style', `${currentListItemStyle}${nestedInsertedNodeStyle}`);
225
225
  });
226
226
  }
227
- element.setAttribute('style', `${currentStyle};${nodeSpecificStyle}`);
227
+ element.setAttribute('style', fg('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentStyle, nodeSpecificStyle) : `${currentStyle};${nodeSpecificStyle}`);
228
228
  };
229
229
  const combineStyles = (currentStyle, appendedStyle) => {
230
230
  const separator = currentStyle && appendedStyle && !currentStyle.trimEnd().endsWith(';') ? '; ' : '';
@@ -11,6 +11,7 @@
11
11
  * keeping the `*Next` bodies.
12
12
  */
13
13
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
14
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
14
15
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
15
16
  import { isExtendedEnabled } from '../../isExtendedEnabled';
16
17
  import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildAddedCellOverlayStyleNew, buildDeletedCellOverlayRoundedStyle, buildDeletedCellOverlayStyle, buildDeletedInlineContentStyle, buildDeletedInlineContentStyleExtended, buildDeletedLozengeActiveStyle, buildDeletedLozengeStyle, buildDeletedNodeCSSVariables, buildDeletedQuoteNodeWithLozengeStyle, buildDeletedStrikethroughLine, buildDeletedWrappedBlockOutline, buildInsertedBlockNodeStyle, buildInsertedInlineStyle, buildInsertStyleInBlockExtended, buildInsertStyleInBlockExtendedNoUnderline, buildInsertStyleNode } from '../colorSchemes/factory';
@@ -19,9 +20,7 @@ import { getChangedContentStyleLegacy, getChangedNodeStyleLegacy, getDeletedCont
19
20
  const getColorScheme = colorScheme => colorSchemeRegistry[colorScheme !== null && colorScheme !== void 0 ? colorScheme : 'standard'];
20
21
 
21
22
  /**
22
- * Inserted content inside a multi-container or list node always uses the standard scheme, so a
23
- * traditional diff shows purple here. Pre-existing: these call sites predate traditional.
24
- * Preserved as-is; see EDITOR-8281.
23
+ * Preserve the historical purple nested outlines when the layout/decision diff patch is off.
25
24
  */
26
25
  const nestedContentScheme = standardScheme;
27
26
 
@@ -49,7 +48,7 @@ const getChangedNodeStyleNext = (nodeName, colorScheme, isInserted = false, isAc
49
48
  const colors = getColorScheme(colorScheme);
50
49
  if (isExtendedEnabled(diffType) && isInserted) {
51
50
  if (isMultiContainerBlockNode(nodeName)) {
52
- return hideAddedDiffsUnderline ? buildInsertStyleInBlockExtendedNoUnderline(nestedContentScheme) : buildInsertStyleInBlockExtended(nestedContentScheme);
51
+ return hideAddedDiffsUnderline || fg('platform_editor_ai_show_diff_patch_1') ? buildInsertStyleInBlockExtendedNoUnderline(nestedContentScheme) : buildInsertStyleInBlockExtended(nestedContentScheme);
53
52
  }
54
53
  if (isTextLikeBlockNode(nodeName)) {
55
54
  return undefined;
@@ -101,7 +100,7 @@ const resolveRemovedLozengeStyleNext = (colorScheme, isActive) => {
101
100
  const colors = getColorScheme(colorScheme);
102
101
  return isActive ? buildDeletedLozengeActiveStyle(colors) : buildDeletedLozengeStyle(colors);
103
102
  };
104
- const resolveNestedInsertedNodeStyleNext = () => buildInsertStyleNode(nestedContentScheme);
103
+ const resolveNestedInsertedNodeStyleNext = colorScheme => buildInsertStyleNode(fg('platform_editor_ai_show_diff_patch_1') ? getColorScheme(colorScheme) : nestedContentScheme);
105
104
 
106
105
  // Only 'stateful' schemes have a resting ring.
107
106
  const hasRestingDeletedRingNext = colorScheme => getColorScheme(colorScheme).deletedNodeEmphasis === 'stateful';
@@ -138,10 +137,9 @@ export const resolveRemovedLozengeStyle = (colorScheme, isActive) => isExperimen
138
137
 
139
138
  /**
140
139
  * Style for inserted content nested inside a multi-container or list node — the `decisionList` and
141
- * `taskList` `li`s and the `layoutSection` columns. Scheme-independent: see
142
- * `nestedContentScheme` above.
140
+ * `taskList` `li`s and the `layoutSection` columns.
143
141
  */
144
- export const resolveNestedInsertedNodeStyle = () => isExperimentEnabled('platform_editor_show_diff_color_scheme_refactor') ? resolveNestedInsertedNodeStyleNext() : resolveNestedInsertedNodeStyleLegacy();
142
+ export const resolveNestedInsertedNodeStyle = colorScheme => isExperimentEnabled('platform_editor_show_diff_color_scheme_refactor') ? resolveNestedInsertedNodeStyleNext(colorScheme) : resolveNestedInsertedNodeStyleLegacy();
145
143
 
146
144
  /**
147
145
  * Whether the colour scheme draws a resting (non-active) ring on a deleted media/embed node, which
@@ -9,6 +9,7 @@
9
9
  * `colorSchemes/standard.ts`, `colorSchemes/traditional.ts` (EDITOR-8281).
10
10
  */
11
11
  import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
12
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
12
13
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
13
14
  import { isExtendedEnabled } from '../../isExtendedEnabled';
14
15
  import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyleUnbounded, deletedInlineContentStyleExtended, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlockExtended, editingContentStyleInBlockExtendedNoUnderline, editingStyleExtended, editingStyleExtendedNoUnderline, editingStyleActiveExtended, editingStyleActiveExtendedNoUnderline, editingStyleNode, getStandardDeletedContentStyle, getStandardDeletedContentStyleActive, getStandardDeletedContentStyleNew, addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from '../colorSchemes/standard';
@@ -97,7 +98,7 @@ export const getChangedNodeStyleLegacy = (nodeName, colorScheme, isInserted = fa
97
98
  const isTraditional = colorScheme === 'traditional';
98
99
  if (isExtendedEnabled(diffType) && isInserted) {
99
100
  if (isMultiContainerBlockNode(nodeName)) {
100
- return hideAddedDiffsUnderline ? editingContentStyleInBlockExtendedNoUnderline : editingContentStyleInBlockExtended;
101
+ return hideAddedDiffsUnderline || fg('platform_editor_ai_show_diff_patch_1') ? editingContentStyleInBlockExtendedNoUnderline : editingContentStyleInBlockExtended;
101
102
  }
102
103
  if (isTextLikeBlockNode(nodeName)) {
103
104
  return undefined;
@@ -30,6 +30,7 @@ import { getDefaultDiffType, isExtendedEnabled } from '../isExtendedEnabled';
30
30
  import { diffBySteps } from './diffBySteps';
31
31
  import { groupChangesByBlock } from './groupChangesByBlock';
32
32
  import { isMarkOnlyChange } from './isMarkOnlyChange';
33
+ import { isOpenTokenOnlyChange } from './isOpenTokenOnlyChange';
33
34
  import { optimizeChanges } from './optimizeChanges';
34
35
  import { selectTokenEncoder } from './selectTokenEncoder';
35
36
  import { collapseOverlappingChanges, simplifyChangesWithAttribution } from './simplifyChangesWithAttribution';
@@ -498,6 +499,16 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
498
499
  newDoc: tr.doc
499
500
  });
500
501
 
502
+ // The deleted side of a change over a node's open token is an attribute state rather than
503
+ // content, so there is nothing for the deleted-content widget to draw. Decided here, with
504
+ // the other deleted-side suppressions, so the widget is never asked for a slice it can only
505
+ // render as an empty copy of the block (EDITOR-8912). Its inserted side is untouched, and
506
+ // the node's content change is a change of its own.
507
+ var hasNoDeletedContent = fg('platform_editor_ai_show_diff_patch_1') && change.deleted.length > 0 && isOpenTokenOnlyChange({
508
+ change: change,
509
+ originalDoc: originalDoc
510
+ });
511
+
501
512
  // Hoisted because it decides BOTH where the deleted widget is anchored and — since the
502
513
  // widget pins whichever end of the range it sits at — how the indicator anchors below are
503
514
  // allowed to move.
@@ -616,7 +627,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
616
627
  coarseTableCellsOnly: useCoarseTableDecoration
617
628
  }))));
618
629
  }
619
- if (change.deleted.length > 0 && !isMarkOnly) {
630
+ if (change.deleted.length > 0 && !isMarkOnly && !hasNoDeletedContent) {
620
631
  var _shouldHideDeleted = shouldHideDeletedSide({
621
632
  change: change,
622
633
  diffType: diffType,
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Whether a change spans nothing but a block node's open token, so its deleted side carries no
3
+ * content.
4
+ *
5
+ * The attribute-aware token encoder folds a node's diffable attributes into its open token, so a
6
+ * same-type replacement — an AI suggestion rewriting a code block — is reported as two changes: one
7
+ * over the single position of that token, carrying the attribute change, and one for the content.
8
+ * Slicing the first yields the node with none of its content, which leaves the deleted-content
9
+ * widget nothing to draw but an empty copy of the block (EDITOR-8912). The content change is a
10
+ * change of its own and is decorated in place.
11
+ *
12
+ * A whole node is not matched: its range covers its close token too. Neither is an empty leaf (a
13
+ * `rule`, a `blockCard`), which is one position but slices closed rather than open.
14
+ */
15
+ export var isOpenTokenOnlyChange = function isOpenTokenOnlyChange(_ref) {
16
+ var change = _ref.change,
17
+ originalDoc = _ref.originalDoc;
18
+ if (change.toA - change.fromA !== 1) {
19
+ return false;
20
+ }
21
+ var slice = originalDoc.slice(change.fromA, change.toA);
22
+ // `childCount === 1` already means `firstChild` is there; the optional chain is for the type,
23
+ // which has it nullable.
24
+ var node = slice.content.firstChild;
25
+ return (slice.openStart > 0 || slice.openEnd > 0) && slice.content.childCount === 1 && (node === null || node === void 0 ? void 0 : node.isBlock) === true && node.content.size === 0;
26
+ };
@@ -45,6 +45,16 @@ var edgeCases = function edgeCases(doc, from) {
45
45
  var node = resolved.node,
46
46
  nodeStart = resolved.nodeStart,
47
47
  beforePos = resolved.beforePos;
48
+ if (node.type.name === 'layoutSection' && fg('platform_editor_ai_show_diff_patch_1')) {
49
+ // Columns extend past the node-view wrapper via negative margins (12px or 20px).
50
+ // Measure their container so the indicator stays outside the diff outline, including
51
+ // breakout layouts and after responsive resizing, without changing the column geometry.
52
+ return {
53
+ beforePos: beforePos,
54
+ measurePos: beforePos,
55
+ measureSelector: '[data-layout-section]'
56
+ };
57
+ }
48
58
 
49
59
  /**
50
60
  * All resizable nodes will need dynamic calculations of the block indicator left anchor
@@ -152,10 +162,12 @@ export var createLeftAnchorWidget = function createLeftAnchorWidget(_ref) {
152
162
  anchor.style.setProperty('transform', 'translateX(-50%)');
153
163
  wrapper.appendChild(anchor);
154
164
  var measureWidth = function measureWidth() {
165
+ var _nodeDOM$querySelecto;
155
166
  if (getPos() === undefined || edgeCase.measurePos === undefined) {
156
167
  return;
157
168
  }
158
- var dom = view.nodeDOM(edgeCase.measurePos);
169
+ var nodeDOM = view.nodeDOM(edgeCase.measurePos);
170
+ var dom = edgeCase.measureSelector && nodeDOM instanceof HTMLElement ? (_nodeDOM$querySelecto = nodeDOM.querySelector(edgeCase.measureSelector)) !== null && _nodeDOM$querySelecto !== void 0 ? _nodeDOM$querySelecto : nodeDOM : nodeDOM;
159
171
  if (dom instanceof HTMLElement) {
160
172
  // The left anchor only needs the container width so the
161
173
  // IndicatorBar can align against the block's horizontal extent.
@@ -210,25 +210,25 @@ var applyMultiContainerLikeStyles = function applyMultiContainerLikeStyles(_ref6
210
210
  var targetNodeName = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? getBaseNodeTypeName(targetNode.type) : targetNode.type.name;
211
211
  var nodeSpecificStyle = getChangedNodeStyle(targetNodeName, colorScheme, isInserted, isActive, diffType, hideAddedDiffsUnderline) || '';
212
212
  if (targetNode.type.name === 'decisionList') {
213
- var nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
213
+ var nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle(colorScheme);
214
214
  element.querySelectorAll('li').forEach(function (listItem) {
215
215
  var currentListItemStyle = listItem.getAttribute('style') || '';
216
- listItem.setAttribute('style', "".concat(currentListItemStyle).concat(nestedInsertedNodeStyle));
216
+ listItem.setAttribute('style', fg('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentListItemStyle, nestedInsertedNodeStyle) : "".concat(currentListItemStyle).concat(nestedInsertedNodeStyle));
217
217
  });
218
218
  } else if (targetNode.type.name === 'layoutSection') {
219
- var _nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
219
+ var _nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle(colorScheme);
220
220
  element.querySelectorAll('[data-layout-column="true"]').forEach(function (section) {
221
221
  var currentSectionStyle = section.getAttribute('style') || '';
222
- section.setAttribute('style', "".concat(currentSectionStyle).concat(_nestedInsertedNodeStyle));
222
+ section.setAttribute('style', fg('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentSectionStyle, _nestedInsertedNodeStyle) : "".concat(currentSectionStyle).concat(_nestedInsertedNodeStyle));
223
223
  });
224
224
  } else if (targetNode.type.name === 'taskList') {
225
- var _nestedInsertedNodeStyle2 = resolveNestedInsertedNodeStyle();
225
+ var _nestedInsertedNodeStyle2 = resolveNestedInsertedNodeStyle(colorScheme);
226
226
  element.querySelectorAll('li').forEach(function (listItem) {
227
227
  var currentListItemStyle = listItem.getAttribute('style') || '';
228
228
  listItem.setAttribute('style', "".concat(currentListItemStyle).concat(_nestedInsertedNodeStyle2));
229
229
  });
230
230
  }
231
- element.setAttribute('style', "".concat(currentStyle, ";").concat(nodeSpecificStyle));
231
+ element.setAttribute('style', fg('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentStyle, nodeSpecificStyle) : "".concat(currentStyle, ";").concat(nodeSpecificStyle));
232
232
  };
233
233
  var combineStyles = function combineStyles(currentStyle, appendedStyle) {
234
234
  var separator = currentStyle && appendedStyle && !currentStyle.trimEnd().endsWith(';') ? '; ' : '';
@@ -14,6 +14,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
14
14
  * keeping the `*Next` bodies.
15
15
  */
16
16
  import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
17
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
17
18
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
18
19
  import { isExtendedEnabled } from '../../isExtendedEnabled';
19
20
  import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildAddedCellOverlayStyleNew, buildDeletedCellOverlayRoundedStyle, buildDeletedCellOverlayStyle, buildDeletedInlineContentStyle, buildDeletedInlineContentStyleExtended, buildDeletedLozengeActiveStyle, buildDeletedLozengeStyle, buildDeletedNodeCSSVariables, buildDeletedQuoteNodeWithLozengeStyle, buildDeletedStrikethroughLine, buildDeletedWrappedBlockOutline, buildInsertedBlockNodeStyle, buildInsertedInlineStyle, buildInsertStyleInBlockExtended, buildInsertStyleInBlockExtendedNoUnderline, buildInsertStyleNode } from '../colorSchemes/factory';
@@ -24,9 +25,7 @@ var getColorScheme = function getColorScheme(colorScheme) {
24
25
  };
25
26
 
26
27
  /**
27
- * Inserted content inside a multi-container or list node always uses the standard scheme, so a
28
- * traditional diff shows purple here. Pre-existing: these call sites predate traditional.
29
- * Preserved as-is; see EDITOR-8281.
28
+ * Preserve the historical purple nested outlines when the layout/decision diff patch is off.
30
29
  */
31
30
  var nestedContentScheme = standardScheme;
32
31
 
@@ -62,7 +61,7 @@ var getChangedNodeStyleNext = function getChangedNodeStyleNext(nodeName, colorSc
62
61
  var colors = getColorScheme(colorScheme);
63
62
  if (isExtendedEnabled(diffType) && isInserted) {
64
63
  if (isMultiContainerBlockNode(nodeName)) {
65
- return hideAddedDiffsUnderline ? buildInsertStyleInBlockExtendedNoUnderline(nestedContentScheme) : buildInsertStyleInBlockExtended(nestedContentScheme);
64
+ return hideAddedDiffsUnderline || fg('platform_editor_ai_show_diff_patch_1') ? buildInsertStyleInBlockExtendedNoUnderline(nestedContentScheme) : buildInsertStyleInBlockExtended(nestedContentScheme);
66
65
  }
67
66
  if (isTextLikeBlockNode(nodeName)) {
68
67
  return undefined;
@@ -123,8 +122,8 @@ var resolveRemovedLozengeStyleNext = function resolveRemovedLozengeStyleNext(col
123
122
  var colors = getColorScheme(colorScheme);
124
123
  return isActive ? buildDeletedLozengeActiveStyle(colors) : buildDeletedLozengeStyle(colors);
125
124
  };
126
- var resolveNestedInsertedNodeStyleNext = function resolveNestedInsertedNodeStyleNext() {
127
- return buildInsertStyleNode(nestedContentScheme);
125
+ var resolveNestedInsertedNodeStyleNext = function resolveNestedInsertedNodeStyleNext(colorScheme) {
126
+ return buildInsertStyleNode(fg('platform_editor_ai_show_diff_patch_1') ? getColorScheme(colorScheme) : nestedContentScheme);
128
127
  };
129
128
 
130
129
  // Only 'stateful' schemes have a resting ring.
@@ -188,11 +187,10 @@ export var resolveRemovedLozengeStyle = function resolveRemovedLozengeStyle(colo
188
187
 
189
188
  /**
190
189
  * Style for inserted content nested inside a multi-container or list node — the `decisionList` and
191
- * `taskList` `li`s and the `layoutSection` columns. Scheme-independent: see
192
- * `nestedContentScheme` above.
190
+ * `taskList` `li`s and the `layoutSection` columns.
193
191
  */
194
- export var resolveNestedInsertedNodeStyle = function resolveNestedInsertedNodeStyle() {
195
- return isExperimentEnabled('platform_editor_show_diff_color_scheme_refactor') ? resolveNestedInsertedNodeStyleNext() : resolveNestedInsertedNodeStyleLegacy();
192
+ export var resolveNestedInsertedNodeStyle = function resolveNestedInsertedNodeStyle(colorScheme) {
193
+ return isExperimentEnabled('platform_editor_show_diff_color_scheme_refactor') ? resolveNestedInsertedNodeStyleNext(colorScheme) : resolveNestedInsertedNodeStyleLegacy();
196
194
  };
197
195
 
198
196
  /**
@@ -9,6 +9,7 @@
9
9
  * `colorSchemes/standard.ts`, `colorSchemes/traditional.ts` (EDITOR-8281).
10
10
  */
11
11
  import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
12
+ import { fg } from '@atlaskit/platform-feature-flags/fg';
12
13
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
13
14
  import { isExtendedEnabled } from '../../isExtendedEnabled';
14
15
  import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyleUnbounded, deletedInlineContentStyleExtended, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlockExtended, editingContentStyleInBlockExtendedNoUnderline, editingStyleExtended, editingStyleExtendedNoUnderline, editingStyleActiveExtended, editingStyleActiveExtendedNoUnderline, editingStyleNode, getStandardDeletedContentStyle, getStandardDeletedContentStyleActive, getStandardDeletedContentStyleNew, addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from '../colorSchemes/standard';
@@ -105,7 +106,7 @@ export var getChangedNodeStyleLegacy = function getChangedNodeStyleLegacy(nodeNa
105
106
  var isTraditional = colorScheme === 'traditional';
106
107
  if (isExtendedEnabled(diffType) && isInserted) {
107
108
  if (isMultiContainerBlockNode(nodeName)) {
108
- return hideAddedDiffsUnderline ? editingContentStyleInBlockExtendedNoUnderline : editingContentStyleInBlockExtended;
109
+ return hideAddedDiffsUnderline || fg('platform_editor_ai_show_diff_patch_1') ? editingContentStyleInBlockExtendedNoUnderline : editingContentStyleInBlockExtended;
109
110
  }
110
111
  if (isTextLikeBlockNode(nodeName)) {
111
112
  return undefined;
@@ -0,0 +1,22 @@
1
+ import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
2
+ /**
3
+ * Whether a change spans nothing but a block node's open token, so its deleted side carries no
4
+ * content.
5
+ *
6
+ * The attribute-aware token encoder folds a node's diffable attributes into its open token, so a
7
+ * same-type replacement — an AI suggestion rewriting a code block — is reported as two changes: one
8
+ * over the single position of that token, carrying the attribute change, and one for the content.
9
+ * Slicing the first yields the node with none of its content, which leaves the deleted-content
10
+ * widget nothing to draw but an empty copy of the block (EDITOR-8912). The content change is a
11
+ * change of its own and is decorated in place.
12
+ *
13
+ * A whole node is not matched: its range covers its close token too. Neither is an empty leaf (a
14
+ * `rule`, a `blockCard`), which is one position but slices closed rather than open.
15
+ */
16
+ export declare const isOpenTokenOnlyChange: ({ change, originalDoc, }: {
17
+ change: {
18
+ fromA: number;
19
+ toA: number;
20
+ };
21
+ originalDoc: PMNode;
22
+ }) => boolean;
@@ -29,10 +29,9 @@ export declare const resolveCellOverlayStyle: (args: {
29
29
  export declare const resolveRemovedLozengeStyle: (colorScheme: ColorScheme | undefined, isActive: boolean) => string;
30
30
  /**
31
31
  * Style for inserted content nested inside a multi-container or list node — the `decisionList` and
32
- * `taskList` `li`s and the `layoutSection` columns. Scheme-independent: see
33
- * `nestedContentScheme` above.
32
+ * `taskList` `li`s and the `layoutSection` columns.
34
33
  */
35
- export declare const resolveNestedInsertedNodeStyle: () => string;
34
+ export declare const resolveNestedInsertedNodeStyle: (colorScheme?: ColorScheme) => string;
36
35
  /**
37
36
  * Whether the colour scheme draws a resting (non-active) ring on a deleted media/embed node, which
38
37
  * is what the `show-diff-deleted-outline-new` class styles in editor-core's smartCardStyles.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-show-diff",
3
- "version": "16.0.3",
3
+ "version": "16.0.5",
4
4
  "description": "ShowDiff plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -32,7 +32,7 @@
32
32
  "@atlaskit/platform-feature-experiments": "^0.3.0",
33
33
  "@atlaskit/platform-feature-flags": "^2.2.0",
34
34
  "@atlaskit/primitives": "^22.5.0",
35
- "@atlaskit/tmp-editor-statsig": "^190.0.0",
35
+ "@atlaskit/tmp-editor-statsig": "^192.0.0",
36
36
  "@atlaskit/tokens": "^16.12.0",
37
37
  "@babel/runtime": "^7.0.0",
38
38
  "@compiled/react": "^1.0.2",
@@ -57,7 +57,7 @@
57
57
  "@atlassian/confluence-presets": "workspace:^",
58
58
  "@atlassian/content-reconciliation": "^0.1.3506",
59
59
  "@atlassian/editor-ai-injected-editors": "^32.0.0",
60
- "@atlassian/editor-plugin-ai": "^72.0.0",
60
+ "@atlassian/editor-plugin-ai": "^72.1.0",
61
61
  "@atlassian/structured-docs-types": "workspace:^",
62
62
  "react": "^19.2.0",
63
63
  "react-dom": "^19.2.0",