@atlaskit/editor-plugin-show-diff 16.1.1 → 17.0.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 (42) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/afm-products/tsconfig.json +3 -0
  3. package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +67 -22
  4. package/dist/cjs/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +242 -26
  5. package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +71 -37
  6. package/dist/cjs/pm-plugins/decorations/colorSchemes/schemes.js +5 -1
  7. package/dist/cjs/pm-plugins/decorations/colorSchemes/types.js +0 -2
  8. package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +21 -14
  9. package/dist/cjs/pm-plugins/decorations/extractContributorTags.js +123 -43
  10. package/dist/cjs/pm-plugins/decorations/revealStyles.js +5 -1
  11. package/dist/cjs/pm-plugins/getScrollableDecorations.js +48 -19
  12. package/dist/cjs/pm-plugins/utils/baseNodeName.js +25 -0
  13. package/dist/cjs/pm-plugins/utils/taggableBlockNodes.js +37 -0
  14. package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +39 -2
  15. package/dist/es2019/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +196 -10
  16. package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +51 -19
  17. package/dist/es2019/pm-plugins/decorations/colorSchemes/schemes.js +3 -0
  18. package/dist/es2019/pm-plugins/decorations/colorSchemes/types.js +0 -2
  19. package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +23 -14
  20. package/dist/es2019/pm-plugins/decorations/extractContributorTags.js +60 -7
  21. package/dist/es2019/pm-plugins/decorations/revealStyles.js +5 -1
  22. package/dist/es2019/pm-plugins/getScrollableDecorations.js +44 -19
  23. package/dist/es2019/pm-plugins/utils/baseNodeName.js +18 -0
  24. package/dist/es2019/pm-plugins/utils/taggableBlockNodes.js +28 -0
  25. package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +67 -22
  26. package/dist/esm/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +243 -26
  27. package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +71 -37
  28. package/dist/esm/pm-plugins/decorations/colorSchemes/schemes.js +5 -1
  29. package/dist/esm/pm-plugins/decorations/colorSchemes/types.js +0 -2
  30. package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +21 -14
  31. package/dist/esm/pm-plugins/decorations/extractContributorTags.js +123 -43
  32. package/dist/esm/pm-plugins/decorations/revealStyles.js +5 -1
  33. package/dist/esm/pm-plugins/getScrollableDecorations.js +48 -19
  34. package/dist/esm/pm-plugins/utils/baseNodeName.js +20 -0
  35. package/dist/esm/pm-plugins/utils/taggableBlockNodes.js +32 -0
  36. package/dist/types/pm-plugins/calculateDiff/simplifyChangesWithAttribution.d.ts +20 -1
  37. package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +4 -11
  38. package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +9 -8
  39. package/dist/types/pm-plugins/getScrollableDecorations.d.ts +2 -2
  40. package/dist/types/pm-plugins/utils/baseNodeName.d.ts +16 -0
  41. package/dist/types/pm-plugins/utils/taggableBlockNodes.d.ts +14 -0
  42. package/package.json +12 -11
@@ -73,6 +73,7 @@ exports.getDeletedHighlightHoverColor = getDeletedHighlightHoverColor;
73
73
  exports.getDeletedInlineRevealColors = getDeletedInlineRevealColors;
74
74
  exports.getInsertedInlineRevealColors = getInsertedInlineRevealColors;
75
75
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
76
+ var _agentBrandColorSchemes = require("@atlaskit/agent-color/agent-brand-color-schemes");
76
77
  var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
77
78
  var _getStandardDeletedTextDecorationStyle = require("./getStandardDeletedTextDecorationStyle");
78
79
  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; }
@@ -191,40 +192,48 @@ var textAccentMap = {
191
192
  gray: "var(--ds-text-accent-gray, #505258)",
192
193
  lime: "var(--ds-text-accent-lime, #4C6B1F)"
193
194
  };
195
+ var getBrand = function getBrand(color) {
196
+ return Object.prototype.hasOwnProperty.call(_agentBrandColorSchemes.agentBrandColorSchemes, color) ? _agentBrandColorSchemes.agentBrandColorSchemes[color] : undefined;
197
+ };
194
198
  function bgSubtlest(color) {
195
- return bgSubtlestMap[color];
199
+ var _getBrand$background, _getBrand;
200
+ return (_getBrand$background = (_getBrand = getBrand(color)) === null || _getBrand === void 0 ? void 0 : _getBrand.background) !== null && _getBrand$background !== void 0 ? _getBrand$background : bgSubtlestMap[color];
196
201
  }
197
202
  function bgSubtlestPressed(color) {
198
- return bgSubtlestPressedMap[color];
203
+ var _getBrand$background2, _getBrand2;
204
+ return (_getBrand$background2 = (_getBrand2 = getBrand(color)) === null || _getBrand2 === void 0 ? void 0 : _getBrand2.background) !== null && _getBrand$background2 !== void 0 ? _getBrand$background2 : bgSubtlestPressedMap[color];
199
205
  }
200
206
  function bgSubtler(color) {
201
- return bgSubtlerMap[color];
207
+ var _getBrand$border, _getBrand3;
208
+ return (_getBrand$border = (_getBrand3 = getBrand(color)) === null || _getBrand3 === void 0 ? void 0 : _getBrand3.border) !== null && _getBrand$border !== void 0 ? _getBrand$border : bgSubtlerMap[color];
202
209
  }
203
210
  function bgBolder(color) {
204
- return bgBolderMap[color];
211
+ var _getBrand$bold, _getBrand4;
212
+ return (_getBrand$bold = (_getBrand4 = getBrand(color)) === null || _getBrand4 === void 0 ? void 0 : _getBrand4.bold) !== null && _getBrand$bold !== void 0 ? _getBrand$bold : bgBolderMap[color];
205
213
  }
206
214
  function bgSubtlerPressed(color) {
207
- return bgSubtlerPressedMap[color];
215
+ var _getBrand$background3, _getBrand5;
216
+ return (_getBrand$background3 = (_getBrand5 = getBrand(color)) === null || _getBrand5 === void 0 ? void 0 : _getBrand5.background) !== null && _getBrand$background3 !== void 0 ? _getBrand$background3 : bgSubtlerPressedMap[color];
208
217
  }
209
218
  function borderAccent(color) {
210
- return borderAccentMap[color];
219
+ var _getBrand$border2, _getBrand6;
220
+ return (_getBrand$border2 = (_getBrand6 = getBrand(color)) === null || _getBrand6 === void 0 ? void 0 : _getBrand6.border) !== null && _getBrand$border2 !== void 0 ? _getBrand$border2 : borderAccentMap[color];
211
221
  }
212
222
  function textAccent(color) {
213
- return textAccentMap[color];
223
+ var _getBrand$accentText, _getBrand7;
224
+ return (_getBrand$accentText = (_getBrand7 = getBrand(color)) === null || _getBrand7 === void 0 ? void 0 : _getBrand7.accentText) !== null && _getBrand$accentText !== void 0 ? _getBrand$accentText : textAccentMap[color];
225
+ }
226
+ function deletedBackground(color) {
227
+ var _getBrand$emphasisBac, _getBrand8;
228
+ return (_getBrand$emphasisBac = (_getBrand8 = getBrand(color)) === null || _getBrand8 === void 0 ? void 0 : _getBrand8.emphasisBackground) !== null && _getBrand$emphasisBac !== void 0 ? _getBrand$emphasisBac : bgSubtlest(color);
214
229
  }
215
230
 
216
- /**
217
- * Presentation tokens for a contributor tag in one diff colour.
218
- *
219
- * A `bolder` fill rather than the `subtlest` tint the highlight uses: the tag is a label on the
220
- * change, and at tag size a tint reads as a second, weaker highlight sitting above the real one.
221
- * `inverse` is the only text tone that reads on a bolder fill, and it needs no per-colour map —
222
- * which is also why the tag carries no border: the fill alone bounds it.
223
- */
231
+ /** Contributor tags use a bold fill with a contrasting foreground, including branded schemes. */
224
232
  function getAccentTokens(color) {
233
+ var _getBrand$boldText, _getBrand9;
225
234
  return {
226
235
  background: bgBolder(color),
227
- text: "var(--ds-text-inverse, #FFFFFF)"
236
+ text: (_getBrand$boldText = (_getBrand9 = getBrand(color)) === null || _getBrand9 === void 0 ? void 0 : _getBrand9.boldText) !== null && _getBrand$boldText !== void 0 ? _getBrand$boldText : "var(--ds-text-inverse, #FFFFFF)"
228
237
  };
229
238
  }
230
239
 
@@ -246,18 +255,23 @@ function deletedCellOutline(colors) {
246
255
  // --- Inserted content styles ---
247
256
 
248
257
  function insertedInlineBorderColor(colors) {
249
- return colors.insertedInlineBorderTone === 'backgroundHovered' ? bgSubtlestHoveredMap[colors.insertColor] : borderAccent(colors.insertColor);
258
+ var _getBrand$border3, _getBrand0;
259
+ return colors.insertedInlineBorderTone === 'backgroundHovered' ? (_getBrand$border3 = (_getBrand0 = getBrand(colors.insertColor)) === null || _getBrand0 === void 0 ? void 0 : _getBrand0.border) !== null && _getBrand$border3 !== void 0 ? _getBrand$border3 : bgSubtlestHoveredMap[colors.insertColor] : borderAccent(colors.insertColor);
250
260
  }
251
261
 
252
262
  /** Inline inserted content — default state. */
253
263
  function buildInsertStyle(colors) {
254
- return (0, _lazyNodeView.convertToInlineCss)({
255
- background: bgSubtlest(colors.insertColor),
264
+ var brand = getBrand(colors.insertColor);
265
+ return (0, _lazyNodeView.convertToInlineCss)(_objectSpread(_objectSpread({
266
+ background: bgSubtlest(colors.insertColor)
267
+ }, brand ? {
268
+ color: brand.text
269
+ } : {}), {}, {
256
270
  textDecoration: 'underline',
257
271
  textDecorationStyle: colors.insertUnderlineStyle,
258
272
  textDecorationThickness: "var(--ds-space-025, 2px)",
259
273
  textDecorationColor: borderAccent(colors.insertColor)
260
- });
274
+ }));
261
275
  }
262
276
 
263
277
  /** Inline insert style for content within a block node (no background, underline only). */
@@ -272,11 +286,15 @@ function buildInsertStyleInBlock(colors) {
272
286
 
273
287
  /** Extended insert style — background + border-bottom underline. */
274
288
  function buildInsertStyleExtended(colors) {
275
- return (0, _lazyNodeView.convertToInlineCss)({
276
- background: bgSubtlest(colors.insertColor),
289
+ var brand = getBrand(colors.insertColor);
290
+ return (0, _lazyNodeView.convertToInlineCss)(_objectSpread(_objectSpread({
291
+ background: bgSubtlest(colors.insertColor)
292
+ }, brand ? {
293
+ color: brand.text
294
+ } : {}), {}, {
277
295
  borderBottom: "2px solid ".concat(insertedInlineBorderColor(colors)),
278
296
  padding: "1px 0 2px"
279
- });
297
+ }));
280
298
  }
281
299
 
282
300
  /** Extended insert style for content within a block node (border-bottom only, no background). */
@@ -289,27 +307,39 @@ function buildInsertStyleInBlockExtended(colors) {
289
307
 
290
308
  /** Active state of the extended insert style. */
291
309
  function buildInsertStyleExtendedActive(colors) {
292
- return (0, _lazyNodeView.convertToInlineCss)({
293
- background: bgSubtlerPressed(colors.insertActiveColor),
310
+ var brand = getBrand(colors.insertColor);
311
+ return (0, _lazyNodeView.convertToInlineCss)(_objectSpread(_objectSpread({
312
+ background: bgSubtlerPressed(colors.insertActiveColor)
313
+ }, brand ? {
314
+ color: brand.text
315
+ } : {}), {}, {
294
316
  borderBottom: "2px solid ".concat(borderAccent(colors.insertColor)),
295
317
  padding: "1px 0 2px"
296
- });
318
+ }));
297
319
  }
298
320
 
299
321
  /** Extended insert style without underline — background + padding only. */
300
322
  function buildInsertStyleExtendedNoUnderline(colors) {
301
- return (0, _lazyNodeView.convertToInlineCss)({
302
- background: bgSubtlest(colors.insertColor),
323
+ var brand = getBrand(colors.insertColor);
324
+ return (0, _lazyNodeView.convertToInlineCss)(_objectSpread(_objectSpread({
325
+ background: bgSubtlest(colors.insertColor)
326
+ }, brand ? {
327
+ color: brand.text
328
+ } : {}), {}, {
303
329
  padding: "1px 0 2px"
304
- });
330
+ }));
305
331
  }
306
332
 
307
333
  /** Active state of the no-underline extended insert style. */
308
334
  function buildInsertStyleExtendedNoUnderlineActive(colors) {
309
- return (0, _lazyNodeView.convertToInlineCss)({
310
- background: bgSubtlerPressed(colors.insertActiveColor),
335
+ var brand = getBrand(colors.insertColor);
336
+ return (0, _lazyNodeView.convertToInlineCss)(_objectSpread(_objectSpread({
337
+ background: bgSubtlerPressed(colors.insertActiveColor)
338
+ }, brand ? {
339
+ color: brand.text
340
+ } : {}), {}, {
311
341
  padding: "1px 0 2px"
312
- });
342
+ }));
313
343
  }
314
344
 
315
345
  /** No-underline extended insert style for block content (padding only). */
@@ -321,13 +351,17 @@ function buildInsertStyleInBlockExtendedNoUnderline(_colors) {
321
351
 
322
352
  /** Inline inserted content — active/focused state. */
323
353
  function buildInsertStyleActive(colors) {
324
- return (0, _lazyNodeView.convertToInlineCss)({
325
- background: bgSubtlerPressed(colors.insertActiveColor),
354
+ var brand = getBrand(colors.insertColor);
355
+ return (0, _lazyNodeView.convertToInlineCss)(_objectSpread(_objectSpread({
356
+ background: bgSubtlerPressed(colors.insertActiveColor)
357
+ }, brand ? {
358
+ color: brand.text
359
+ } : {}), {}, {
326
360
  textDecoration: 'underline',
327
361
  textDecorationStyle: colors.insertUnderlineStyle,
328
362
  textDecorationThickness: "var(--ds-space-025, 2px)",
329
363
  textDecorationColor: textAccent(colors.insertActiveColor)
330
- });
364
+ }));
331
365
  }
332
366
 
333
367
  // --- Deleted inline content styles ---
@@ -685,7 +719,7 @@ function buildDeletedInlineContentStyleExtended(colors) {
685
719
  // Under 'underline' emphasis the highlight stays on its resting tint — the same one hover paints —
686
720
  // so only the border carries the emphasis.
687
721
  var isUnderlineEmphasis = isActive && usesUnderlineEmphasis(colors);
688
- var backgroundColor = isActive && !isUnderlineEmphasis && colors.deletedInlineBorderTone === 'background' ? bgSubtlerPressed(colors.deleteActiveColor) : bgSubtlest(colors.deleteColor);
722
+ var backgroundColor = isActive && !isUnderlineEmphasis && colors.deletedInlineBorderTone === 'background' ? bgSubtlerPressed(colors.deleteActiveColor) : deletedBackground(colors.deleteColor);
689
723
  var borderColor = isUnderlineEmphasis ? borderAccent(colors.deleteActiveColor) : colors.deletedInlineBorderTone === 'background' ? backgroundColor : borderAccent(colors.deleteColor);
690
724
  return (0, _lazyNodeView.convertToInlineCss)({
691
725
  backgroundColor: backgroundColor,
@@ -895,7 +929,7 @@ function getDeletedInlineRevealColors(colors) {
895
929
  * paints at rest, so hovering restores the appearance rather than introducing a third one.
896
930
  */
897
931
  function getDeletedHighlightHoverColor(colors) {
898
- return bgSubtlest(colors.deleteColor);
932
+ return deletedBackground(colors.deleteColor);
899
933
  }
900
934
 
901
935
  /**
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.traditionalScheme = exports.standardScheme = exports.getLegacyColorScheme = exports.colorSchemeRegistry = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _agentBrandColorSchemes = require("@atlaskit/agent-color/agent-brand-color-schemes");
9
10
  var _types = require("./types");
10
11
  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; }
11
12
  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; }
@@ -84,9 +85,12 @@ var createAttributionScheme = function createAttributionScheme(color) {
84
85
  var attributionColorSchemes = Object.fromEntries(_types.PARTICIPANT_COLOR_SCHEMES.map(function (color) {
85
86
  return [color, createAttributionScheme(color)];
86
87
  }));
88
+ var brandSchemes = Object.fromEntries(Object.keys(_agentBrandColorSchemes.agentBrandColorSchemes).map(function (scheme) {
89
+ return [scheme, createAttributionScheme(scheme)];
90
+ }));
87
91
 
88
92
  /** Maps public schemes and attribution-only participant slots to their data objects. */
89
- var colorSchemeRegistry = exports.colorSchemeRegistry = _objectSpread(_objectSpread({}, attributionColorSchemes), {}, {
93
+ var colorSchemeRegistry = exports.colorSchemeRegistry = _objectSpread(_objectSpread(_objectSpread({}, attributionColorSchemes), brandSchemes), {}, {
90
94
  traditional: traditionalScheme,
91
95
  standard: standardScheme
92
96
  });
@@ -11,8 +11,6 @@ var PARTICIPANT_COLOR_SCHEMES = exports.PARTICIPANT_COLOR_SCHEMES = ['red', 'blu
11
11
 
12
12
  /** ADS accent hues used by the public and participant colour schemes. */
13
13
 
14
- /** A public scheme or an attribution participant slot resolved internally for one change. */
15
-
16
14
  /**
17
15
  * A show-diff colour scheme. Colour fields are ADS hues that `factory.ts` expands into token paths;
18
16
  * the rest encode structural differences no colour can express. Ring widths, padding, radius and
@@ -13,6 +13,7 @@ var _view = require("@atlaskit/editor-prosemirror/view");
13
13
  var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
14
14
  var _fg = require("@atlaskit/platform-feature-flags/fg");
15
15
  var _isExtendedEnabled = require("../isExtendedEnabled");
16
+ var _taggableBlockNodes = require("../utils/taggableBlockNodes");
16
17
  var _factory = require("./colorSchemes/factory");
17
18
  var _schemes = require("./colorSchemes/schemes");
18
19
  var _createAnchorDecorationWidgets = require("./createAnchorDecorationWidgets");
@@ -34,13 +35,6 @@ var UNSTYLED_NODES = ['mediaSingle', 'mediaGroup', 'table',
34
35
  'heading', 'hardBreak', 'decisionList', 'taskList', 'bulletList', 'orderedList', 'layoutSection'];
35
36
  var CELL_NODES = ['tableCell', 'tableHeader'];
36
37
 
37
- /**
38
- * Block nodes that host a contributor tag of their own — those whose whole box reads as one change.
39
- * Lists and tables are excluded: they decorate per item and per cell, with no one-tag-per-block
40
- * design yet. `blockCard` covers the datasource variant, which is the same node type.
41
- */
42
- var TAGGABLE_BLOCK_NODES = new Set(['blockCard', 'blockquote', 'bodiedExtension', 'codeBlock', 'embedCard', 'expand', 'extension', 'media', 'multiBodiedExtension', 'panel', 'rule']);
43
-
44
38
  /** Panels, rules and media can also sit in a table cell, which is out of scope for block tags. */
45
39
  var isInsideTable = function isInsideTable(doc, pos) {
46
40
  return (0, _utils.findParentNodeClosestToPos)(doc.resolve(pos), function (node) {
@@ -48,13 +42,23 @@ var isInsideTable = function isInsideTable(doc, pos) {
48
42
  }) !== undefined;
49
43
  };
50
44
 
51
- /** Whether this block can host a contributor tag of its own. */
45
+ /**
46
+ * Whether this block can host a contributor tag of its own.
47
+ *
48
+ * The node type is resolved from the document rather than matched on `change.name`, so a schema
49
+ * variant is recognised as the type it varies — see `isTaggableBlockNode`. `from` is the node's own
50
+ * position, so `nodeAt` returns exactly the node being decorated.
51
+ */
52
52
  var canTagBlock = function canTagBlock(_ref) {
53
+ var _doc$nodeAt;
53
54
  var diffType = _ref.diffType,
54
55
  doc = _ref.doc,
55
- from = _ref.from,
56
- name = _ref.name;
57
- return doc !== undefined && (0, _isExtendedEnabled.isExtendedEnabled)(diffType) && TAGGABLE_BLOCK_NODES.has(name) && !isInsideTable(doc, from);
56
+ from = _ref.from;
57
+ if (doc === undefined || !(0, _isExtendedEnabled.isExtendedEnabled)(diffType)) {
58
+ return false;
59
+ }
60
+ var nodeType = (_doc$nodeAt = doc.nodeAt(from)) === null || _doc$nodeAt === void 0 ? void 0 : _doc$nodeAt.type;
61
+ return nodeType !== undefined && (0, _taggableBlockNodes.isTaggableBlockNode)(nodeType) && !isInsideTable(doc, from);
58
62
  };
59
63
 
60
64
  /** Positioning context for the cell overlay widget decorations. */
@@ -196,8 +200,7 @@ var createBlockChangedDecoration = exports.createBlockChangedDecoration = functi
196
200
  var shouldTagBlock = showContributorTags && canTagBlock({
197
201
  diffType: diffType,
198
202
  doc: doc,
199
- from: change.from,
200
- name: change.name
203
+ from: change.from
201
204
  });
202
205
  // Named so this block's own tag can position against it; see `createContributorTagWidget`.
203
206
  var tagAnchorName = shouldTagBlock && (0, _createContributorTagWidget.isContributorTagWidgetEnabled)() ? (0, _decorationKeys.buildAnchorDecorationKey)({
@@ -241,7 +244,9 @@ var createBlockChangedDecoration = exports.createBlockChangedDecoration = functi
241
244
  key: 'cell-overlay-decoration'
242
245
  }));
243
246
  }
244
- // isInserted is only read under the extended experience, so pass it unconditionally.
247
+ // isInserted is only read under the extended experience, so pass it unconditionally. `change.name`
248
+ // verbatim: base-name resolution stays in `canTagBlock`, which needs tags on, so a schema
249
+ // variant's legacy style is untouched — see `resolveBaseNodeName`.
245
250
  var nodeStyle = getBlockNodeStyle({
246
251
  nodeName: change.name,
247
252
  colorScheme: colorScheme,
@@ -272,6 +277,8 @@ var createBlockChangedDecoration = exports.createBlockChangedDecoration = functi
272
277
  })));
273
278
  }
274
279
  if (decorations.length === 0) {
280
+ // An unstyled node type (paragraph, heading, list, layout, …) emits no decoration at all, so
281
+ // there is nothing for a tag to hang off even when the node type would otherwise be taggable.
275
282
  return decorations;
276
283
  }
277
284
  if (showIndicators && doc && (0, _isExtendedEnabled.isExtendedEnabled)(diffType)) {
@@ -5,8 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.extractContributorTags = void 0;
8
- var _toArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toArray"));
9
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _toArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toArray"));
10
10
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
11
11
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
12
12
  var _fg = require("@atlaskit/platform-feature-flags/fg");
@@ -57,6 +57,14 @@ var isSameBlockChange = function isSameBlockChange(inner, block) {
57
57
  return inner.spec.attributionKey === block.spec.attributionKey && (block.from <= inner.from && inner.to <= block.to || inner.from <= block.from && block.to <= inner.to);
58
58
  };
59
59
 
60
+ /**
61
+ * Whether `outer` is the box `inner` sits in, for one contributor. Nested blocks they inserted read
62
+ * as one change, so only the outermost keeps a tag (EDITOR-8932).
63
+ */
64
+ var containsBlock = function containsBlock(outer, inner) {
65
+ return outer.spec.attributionKey === inner.spec.attributionKey && outer.from <= inner.from && inner.to <= outer.to && outer.to - outer.from > inner.to - inner.from;
66
+ };
67
+
60
68
  /**
61
69
  * Which of two changes in the same range leads, and so is the one a tag captions. Position first,
62
70
  * then `side`, since deleted content shares its `from` with the content that replaced it and paints
@@ -77,6 +85,19 @@ var containedBy = function containedBy(targets, _ref2) {
77
85
  }).sort(byLeadingPosition);
78
86
  };
79
87
 
88
+ /**
89
+ * The stop a target is stepped to by: the narrowest one that wholly covers it. A stop's range is
90
+ * the union of the decorations grouped into it, so one inserted run's inline highlight stretches
91
+ * its stop over every block the run spans — including blocks that are a stop of their own. Picking
92
+ * the narrowest keeps each of those blocks in the stop that actually reaches it, rather than
93
+ * letting the widest stop claim them all and fold away every tag but the first (EDITOR-8932).
94
+ */
95
+ var owningStop = function owningStop(target, stops) {
96
+ return stops.reduce(function (narrowest, stop) {
97
+ return stop.from <= target.decoration.from && target.decoration.to <= stop.to && (narrowest === undefined || stop.to - stop.from < narrowest.to - narrowest.from) ? stop : narrowest;
98
+ }, undefined);
99
+ };
100
+
80
101
  /**
81
102
  * The one tag a navigation step reveals. `spec.isActive` is no use here: it covers everything the
82
103
  * group's union range touches, so several tags revealed over each other (EDITOR-8971). Hence
@@ -145,6 +166,10 @@ var extractContributorTags = exports.extractContributorTags = function extractCo
145
166
  });
146
167
  var linkedDiffIds = new Map();
147
168
  var folded = new Set();
169
+
170
+ /**
171
+ * A folded target keeps no tag of its own — it becomes a hover target of the host instead.
172
+ */
148
173
  var fold = function fold(host, target) {
149
174
  var _linkedDiffIds$get, _linkedDiffIds$get2;
150
175
  folded.add(target);
@@ -202,58 +227,113 @@ var extractContributorTags = exports.extractContributorTags = function extractCo
202
227
  if (_ret === 0) continue;
203
228
  }
204
229
 
230
+ // A nested block folds into the outermost one of the same contributor, so nesting adds no tags.
231
+ if ((0, _fg.fg)('confluence_ncs_step_diffing_version_history')) {
232
+ var blocksByContributor = new Map();
233
+ var _iterator2 = _createForOfIteratorHelper(blockTargets),
234
+ _step2;
235
+ try {
236
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
237
+ var _target$decoration$sp, _blocksByContributor$;
238
+ var target = _step2.value;
239
+ var key = (_target$decoration$sp = target.decoration.spec.attributionKey) !== null && _target$decoration$sp !== void 0 ? _target$decoration$sp : '';
240
+ blocksByContributor.set(key, [].concat((0, _toConsumableArray2.default)((_blocksByContributor$ = blocksByContributor.get(key)) !== null && _blocksByContributor$ !== void 0 ? _blocksByContributor$ : []), [target]));
241
+ }
242
+ } catch (err) {
243
+ _iterator2.e(err);
244
+ } finally {
245
+ _iterator2.f();
246
+ }
247
+ var _iterator3 = _createForOfIteratorHelper(blocksByContributor.values()),
248
+ _step3;
249
+ try {
250
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
251
+ var contributorBlocks = _step3.value;
252
+ // Block ranges nest rather than partially overlap, so ascending `from` then descending `to`
253
+ // reaches every block after the ones containing it. A stack of the blocks still open at
254
+ // this position then yields each block's container in one pass, rather than rescanning
255
+ // every block for the widest that contains it.
256
+ var nested = (0, _toConsumableArray2.default)(contributorBlocks).sort(function (left, right) {
257
+ return left.decoration.from - right.decoration.from || right.decoration.to - left.decoration.to;
258
+ });
259
+ var open = [];
260
+ var _iterator4 = _createForOfIteratorHelper(nested),
261
+ _step4;
262
+ try {
263
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
264
+ var _target = _step4.value;
265
+ while (open.length > 0 && !containsBlock(open[open.length - 1].decoration, _target.decoration)) {
266
+ open.pop();
267
+ }
268
+ // Outermost first, so the bottom of the stack is the block the tag survives on.
269
+ if (open.length > 0) {
270
+ fold(open[0], _target);
271
+ }
272
+ open.push(_target);
273
+ }
274
+ } catch (err) {
275
+ _iterator4.e(err);
276
+ } finally {
277
+ _iterator4.f();
278
+ }
279
+ }
280
+ } catch (err) {
281
+ _iterator3.e(err);
282
+ } finally {
283
+ _iterator3.f();
284
+ }
285
+ }
286
+
205
287
  // One tag per contributor per navigation stop. The folds above only catch a replacement's two
206
288
  // halves and a block's own highlights; two of one contributor's changes that merely touch are a
207
289
  // single stop (`groupTouchingDecorations`) yet kept a tag each, so the stop's trailing tag was
208
290
  // drawn but could never be stepped to (EDITOR-8971). It folds into the leading tag of its
209
291
  // contributor, staying a hover target. Contributors are kept apart: a stop spanning two of them
210
292
  // still captions each, rather than crediting one for the other's change.
211
- var _iterator2 = _createForOfIteratorHelper(stops !== null && stops !== void 0 ? stops : []),
212
- _step2;
213
- try {
214
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
215
- var stop = _step2.value;
216
- var byContributor = new Map();
217
- var _iterator3 = _createForOfIteratorHelper(containedBy(targets.filter(function (target) {
218
- return !folded.has(target);
219
- }), stop)),
220
- _step3;
221
- try {
222
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
223
- var _target$decoration$sp, _byContributor$get;
224
- var target = _step3.value;
225
- var key = (_target$decoration$sp = target.decoration.spec.attributionKey) !== null && _target$decoration$sp !== void 0 ? _target$decoration$sp : '';
226
- byContributor.set(key, [].concat((0, _toConsumableArray2.default)((_byContributor$get = byContributor.get(key)) !== null && _byContributor$get !== void 0 ? _byContributor$get : []), [target]));
293
+ // Each target is counted against one stop only see `owningStop`.
294
+ if (stops !== null && stops !== void 0 && stops.length) {
295
+ var byStopAndContributor = new Map();
296
+ var _iterator5 = _createForOfIteratorHelper(targets.filter(function (target) {
297
+ return !folded.has(target);
298
+ })),
299
+ _step5;
300
+ try {
301
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
302
+ var _target2$decoration$s, _byStopAndContributor;
303
+ var _target2 = _step5.value;
304
+ var stop = owningStop(_target2, stops);
305
+ if (stop === undefined) {
306
+ continue;
227
307
  }
228
- } catch (err) {
229
- _iterator3.e(err);
230
- } finally {
231
- _iterator3.f();
308
+ var _key = "".concat(stop.from, "-").concat(stop.to, "|").concat((_target2$decoration$s = _target2.decoration.spec.attributionKey) !== null && _target2$decoration$s !== void 0 ? _target2$decoration$s : '');
309
+ byStopAndContributor.set(_key, [].concat((0, _toConsumableArray2.default)((_byStopAndContributor = byStopAndContributor.get(_key)) !== null && _byStopAndContributor !== void 0 ? _byStopAndContributor : []), [_target2]));
232
310
  }
233
- var _iterator4 = _createForOfIteratorHelper(byContributor.values()),
234
- _step4;
235
- try {
236
- var _loop2 = function _loop2() {
237
- var _step4$value = (0, _toArray2.default)(_step4.value),
238
- leader = _step4$value[0],
239
- trailing = _arrayLikeToArray(_step4$value).slice(1);
240
- trailing.forEach(function (target) {
241
- return fold(leader, target);
242
- });
243
- };
244
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
245
- _loop2();
246
- }
247
- } catch (err) {
248
- _iterator4.e(err);
249
- } finally {
250
- _iterator4.f();
311
+ } catch (err) {
312
+ _iterator5.e(err);
313
+ } finally {
314
+ _iterator5.f();
315
+ }
316
+ var _iterator6 = _createForOfIteratorHelper(byStopAndContributor.values()),
317
+ _step6;
318
+ try {
319
+ var _loop2 = function _loop2() {
320
+ var members = _step6.value;
321
+ var _sort = (0, _toConsumableArray2.default)(members).sort(byLeadingPosition),
322
+ _sort2 = (0, _toArray2.default)(_sort),
323
+ leader = _sort2[0],
324
+ trailing = _arrayLikeToArray(_sort2).slice(1);
325
+ trailing.forEach(function (target) {
326
+ return fold(leader, target);
327
+ });
328
+ };
329
+ for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
330
+ _loop2();
251
331
  }
332
+ } catch (err) {
333
+ _iterator6.e(err);
334
+ } finally {
335
+ _iterator6.f();
252
336
  }
253
- } catch (err) {
254
- _iterator2.e(err);
255
- } finally {
256
- _iterator2.f();
257
337
  }
258
338
  var surviving = targets.filter(function (target) {
259
339
  return !folded.has(target);
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.resolveRevealStyle = exports.buildWipeableBackground = exports.applyRevealToElement = exports.REVEAL_BORDER_VAR = exports.REVEAL_BG_VAR = exports.REVEAL_ATTR = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _agentBrandColorSchemes = require("@atlaskit/agent-color/agent-brand-color-schemes");
9
10
  var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
10
11
  var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
11
12
  var _factory = require("./colorSchemes/factory");
@@ -115,6 +116,7 @@ var resolveRevealStyle = exports.resolveRevealStyle = function resolveRevealStyl
115
116
  return undefined;
116
117
  }
117
118
  var colors = getColorScheme(colorScheme);
119
+ var brand = isInserted && Object.prototype.hasOwnProperty.call(_agentBrandColorSchemes.agentBrandColorSchemes, colors.insertColor) ? _agentBrandColorSchemes.agentBrandColorSchemes[colors.insertColor] : undefined;
118
120
  var _resolveRevealColors = resolveRevealColors(colors, {
119
121
  hideAddedDiffsUnderline: hideAddedDiffsUnderline,
120
122
  isActive: isActive,
@@ -124,7 +126,9 @@ var resolveRevealStyle = exports.resolveRevealStyle = function resolveRevealStyl
124
126
  border = _resolveRevealColors.border;
125
127
  return {
126
128
  role: isInserted ? 'added' : 'deleted',
127
- style: (isInserted || !includeDeletedTextStyle ? '' : deletedTextOnlyStyle(colors, isActive)) + revealBaseStyle + buildWipeableBackground(background) + buildRevealVariables({
129
+ style: (brand ? (0, _lazyNodeView.convertToInlineCss)({
130
+ color: brand.text
131
+ }) : '') + (isInserted || !includeDeletedTextStyle ? '' : deletedTextOnlyStyle(colors, isActive)) + revealBaseStyle + buildWipeableBackground(background) + buildRevealVariables({
128
132
  background: background,
129
133
  border: border
130
134
  })