@atlaskit/editor-plugin-show-diff 14.3.2 → 14.4.2

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 (77) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/afm-cc/tsconfig.json +18 -0
  3. package/afm-products/tsconfig.json +18 -0
  4. package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +47 -26
  5. package/dist/cjs/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +61 -9
  6. package/dist/cjs/pm-plugins/decorations/colorSchemes/attributions.js +77 -20
  7. package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +10 -0
  8. package/dist/cjs/pm-plugins/decorations/colorSchemes/types.js +2 -0
  9. package/dist/cjs/pm-plugins/decorations/createAnchorDecorationWidgets.js +52 -7
  10. package/dist/cjs/pm-plugins/decorations/createContributorTagWidget.js +172 -0
  11. package/dist/cjs/pm-plugins/decorations/createInlineChangedDecoration.js +37 -5
  12. package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +40 -7
  13. package/dist/cjs/pm-plugins/decorations/decorationKeys.js +31 -5
  14. package/dist/cjs/pm-plugins/decorations/extractContributorTags.js +128 -0
  15. package/dist/cjs/pm-plugins/main.js +57 -6
  16. package/dist/cjs/pm-plugins/resolveDiffContributors.js +143 -0
  17. package/dist/cjs/showDiffPlugin.js +21 -6
  18. package/dist/cjs/ui/ContributorTag/ContributorTag.compiled.css +29 -0
  19. package/dist/cjs/ui/ContributorTag/ContributorTag.js +383 -0
  20. package/dist/cjs/ui/ContributorTag/ContributorTagWidget.js +50 -0
  21. package/dist/cjs/ui/ContributorTag/messages.js +24 -0
  22. package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +48 -27
  23. package/dist/es2019/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +39 -0
  24. package/dist/es2019/pm-plugins/decorations/colorSchemes/attributions.js +53 -11
  25. package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +9 -0
  26. package/dist/es2019/pm-plugins/decorations/colorSchemes/types.js +2 -0
  27. package/dist/es2019/pm-plugins/decorations/createAnchorDecorationWidgets.js +43 -1
  28. package/dist/es2019/pm-plugins/decorations/createContributorTagWidget.js +163 -0
  29. package/dist/es2019/pm-plugins/decorations/createInlineChangedDecoration.js +38 -5
  30. package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +38 -6
  31. package/dist/es2019/pm-plugins/decorations/decorationKeys.js +30 -2
  32. package/dist/es2019/pm-plugins/decorations/extractContributorTags.js +101 -0
  33. package/dist/es2019/pm-plugins/main.js +52 -3
  34. package/dist/es2019/pm-plugins/resolveDiffContributors.js +128 -0
  35. package/dist/es2019/showDiffPlugin.js +20 -5
  36. package/dist/es2019/ui/ContributorTag/ContributorTag.compiled.css +29 -0
  37. package/dist/es2019/ui/ContributorTag/ContributorTag.js +312 -0
  38. package/dist/es2019/ui/ContributorTag/ContributorTagWidget.js +43 -0
  39. package/dist/es2019/ui/ContributorTag/messages.js +18 -0
  40. package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +49 -28
  41. package/dist/esm/pm-plugins/calculateDiff/simplifyChangesWithAttribution.js +60 -8
  42. package/dist/esm/pm-plugins/decorations/colorSchemes/attributions.js +77 -19
  43. package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +9 -0
  44. package/dist/esm/pm-plugins/decorations/colorSchemes/types.js +2 -0
  45. package/dist/esm/pm-plugins/decorations/createAnchorDecorationWidgets.js +51 -6
  46. package/dist/esm/pm-plugins/decorations/createContributorTagWidget.js +166 -0
  47. package/dist/esm/pm-plugins/decorations/createInlineChangedDecoration.js +37 -5
  48. package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +40 -7
  49. package/dist/esm/pm-plugins/decorations/decorationKeys.js +30 -5
  50. package/dist/esm/pm-plugins/decorations/extractContributorTags.js +122 -0
  51. package/dist/esm/pm-plugins/main.js +57 -6
  52. package/dist/esm/pm-plugins/resolveDiffContributors.js +137 -0
  53. package/dist/esm/showDiffPlugin.js +21 -6
  54. package/dist/esm/ui/ContributorTag/ContributorTag.compiled.css +29 -0
  55. package/dist/esm/ui/ContributorTag/ContributorTag.js +375 -0
  56. package/dist/esm/ui/ContributorTag/ContributorTagWidget.js +43 -0
  57. package/dist/esm/ui/ContributorTag/messages.js +18 -0
  58. package/dist/types/entry-points/show-diff-plugin-type.d.ts +1 -1
  59. package/dist/types/pm-plugins/calculateDiff/calculateDiffDecorations.d.ts +7 -1
  60. package/dist/types/pm-plugins/calculateDiff/simplifyChangesWithAttribution.d.ts +10 -0
  61. package/dist/types/pm-plugins/decorations/colorSchemes/attributions.d.ts +24 -2
  62. package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +7 -1
  63. package/dist/types/pm-plugins/decorations/colorSchemes/schemes.d.ts +1 -2
  64. package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +2 -1
  65. package/dist/types/pm-plugins/decorations/createAnchorDecorationWidgets.d.ts +14 -0
  66. package/dist/types/pm-plugins/decorations/createContributorTagWidget.d.ts +55 -0
  67. package/dist/types/pm-plugins/decorations/createInlineChangedDecoration.d.ts +5 -1
  68. package/dist/types/pm-plugins/decorations/createNodeChangedDecorationWidget.d.ts +5 -1
  69. package/dist/types/pm-plugins/decorations/decorationKeys.d.ts +28 -3
  70. package/dist/types/pm-plugins/decorations/extractContributorTags.d.ts +9 -0
  71. package/dist/types/pm-plugins/main.d.ts +8 -2
  72. package/dist/types/pm-plugins/resolveDiffContributors.d.ts +7 -0
  73. package/dist/types/showDiffPluginType.d.ts +65 -2
  74. package/dist/types/ui/ContributorTag/ContributorTag.d.ts +37 -0
  75. package/dist/types/ui/ContributorTag/ContributorTagWidget.d.ts +22 -0
  76. package/dist/types/ui/ContributorTag/messages.d.ts +6 -0
  77. package/package.json +17 -8
@@ -4,10 +4,11 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.createLeftAnchorWidget = exports.createInlineIndicatorAnchorWidgets = exports.createDocMarginAnchorWidget = exports.createBlockIndicatorAnchorWidgets = void 0;
7
+ exports.createLeftAnchorWidget = exports.createInlineIndicatorAnchorWidgets = exports.createDocMarginAnchorWidget = exports.createBlockIndicatorAnchorWidgets = exports.createAnchorNameSpan = exports.clampAnchorPosIntoCell = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _utils = require("@atlaskit/editor-prosemirror/utils");
10
10
  var _view = require("@atlaskit/editor-prosemirror/view");
11
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
11
12
  var _decorationKeys = require("./decorationKeys");
12
13
  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
14
  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; }
@@ -322,7 +323,7 @@ var createBlockIndicatorAnchorWidgets = exports.createBlockIndicatorAnchorWidget
322
323
  * inward into the neighbouring cell (`direction: 1` forward, `-1` back). Positions
323
324
  * not on a row boundary are returned as-is.
324
325
  */
325
- var clampAnchorPosIntoCell = function clampAnchorPosIntoCell(doc, pos, direction) {
326
+ var clampAnchorPosIntoCell = exports.clampAnchorPosIntoCell = function clampAnchorPosIntoCell(doc, pos, direction) {
326
327
  var $pos = doc.resolve(pos);
327
328
  if ($pos.parent.type.name !== 'tableRow') {
328
329
  return pos;
@@ -336,15 +337,43 @@ var clampAnchorPosIntoCell = function clampAnchorPosIntoCell(doc, pos, direction
336
337
  return direction === 1 ? pos + 2 : pos - 2;
337
338
  };
338
339
 
340
+ /**
341
+ * A zero-size inline span carrying nothing but the `anchor-name` an overlay aligns against. A
342
+ * fragmented inline element reports the union of its line fragments, so aligning against one
343
+ * horizontally gives the enclosing block's content edge; a zero-size span is always a single
344
+ * fragment.
345
+ */
346
+ var createAnchorNameSpan = exports.createAnchorNameSpan = function createAnchorNameSpan(anchorKey) {
347
+ var span = document.createElement('span');
348
+ span.style.setProperty('anchor-name', "--".concat(anchorKey));
349
+ return span;
350
+ };
351
+ var createAnchorSpanWidget = function createAnchorSpanWidget(_ref3) {
352
+ var pos = _ref3.pos,
353
+ diffId = _ref3.diffId,
354
+ anchorType = _ref3.anchorType,
355
+ side = _ref3.side;
356
+ return _view.Decoration.widget(pos, function () {
357
+ return createAnchorNameSpan((0, _decorationKeys.buildAnchorDecorationKey)({
358
+ diffId: diffId,
359
+ anchorType: anchorType
360
+ }));
361
+ }, (0, _decorationKeys.buildAnchorDecorationSpec)({
362
+ diffId: diffId,
363
+ anchorType: anchorType,
364
+ side: side
365
+ }));
366
+ };
367
+
339
368
  /**
340
369
  * Invisible `from`/`to` (and optional `left`) anchor widgets for one inline diff
341
370
  * range, so the `IndicatorBar` can align itself via CSS anchor positioning.
342
371
  */
343
- var createInlineIndicatorAnchorWidgets = exports.createInlineIndicatorAnchorWidgets = function createInlineIndicatorAnchorWidgets(_ref3) {
344
- var doc = _ref3.doc,
345
- from = _ref3.from,
346
- to = _ref3.to,
347
- diffId = _ref3.diffId;
372
+ var createInlineIndicatorAnchorWidgets = exports.createInlineIndicatorAnchorWidgets = function createInlineIndicatorAnchorWidgets(_ref4) {
373
+ var doc = _ref4.doc,
374
+ from = _ref4.from,
375
+ to = _ref4.to,
376
+ diffId = _ref4.diffId;
348
377
  var leftAnchor = createLeftAnchorWidget({
349
378
  doc: doc,
350
379
  from: from,
@@ -361,6 +390,22 @@ var createInlineIndicatorAnchorWidgets = exports.createInlineIndicatorAnchorWidg
361
390
  * IndicatorBar can determine top/bottom even if
362
391
  * the inline decoration is broken up by marks / between blocks.
363
392
  */
393
+ // Gated purely so the `createAnchorSpanWidget` rewrite can be rolled back independently of the
394
+ // contributor-tag anchors it was extracted for: both branches build the same two widgets at the
395
+ // same positions. Drop the fallback with the gate.
396
+ if ((0, _fg.fg)('confluence_ncs_step_diffing_version_history')) {
397
+ return [createAnchorSpanWidget({
398
+ pos: fromPos,
399
+ diffId: diffId,
400
+ anchorType: _decorationKeys.AnchorTypeKey.from,
401
+ side: 1
402
+ }), createAnchorSpanWidget({
403
+ pos: toPos,
404
+ diffId: diffId,
405
+ anchorType: _decorationKeys.AnchorTypeKey.to,
406
+ side: -1
407
+ })].concat(maybeLeftAnchor);
408
+ }
364
409
  var fromAnchorKey = (0, _decorationKeys.buildAnchorDecorationKey)({
365
410
  diffId: diffId,
366
411
  anchorType: _decorationKeys.AnchorTypeKey.from
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.unmountContributorTag = exports.mountContributorTag = exports.createContributorTagWidget = exports.createContributorTagHost = exports.CONTRIBUTOR_TAG_HOST_ATTRIBUTE = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _react = require("react");
10
+ var _view = require("@atlaskit/editor-prosemirror/view");
11
+ var _fg = require("@atlaskit/platform-feature-flags/fg");
12
+ var _ContributorTagWidget = require("../../ui/ContributorTag/ContributorTagWidget");
13
+ var _createAnchorDecorationWidgets = require("./createAnchorDecorationWidgets");
14
+ var _decorationKeys = require("./decorationKeys");
15
+ 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; }
16
+ 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; }
17
+ /** Marks the host element of one tag, so a tag can be found in the document by its own diff. */
18
+ var CONTRIBUTOR_TAG_HOST_ATTRIBUTE = exports.CONTRIBUTOR_TAG_HOST_ATTRIBUTE = 'data-contributor-tag-host';
19
+
20
+ // Contributor tags only render behind this gate — see `areAttributionColorGatesEnabled`.
21
+ var isContributorTagWidgetEnabled = function isContributorTagWidgetEnabled() {
22
+ return (0, _fg.fg)('confluence_ncs_step_diffing_version_history');
23
+ };
24
+
25
+ /**
26
+ * Everything a tag needs to mount itself into the document, plumbed down from the plugin. Absent in
27
+ * unit tests that build decorations directly: the hosts are still emitted, they just stay empty.
28
+ */
29
+
30
+ /** A mounted tag, so whoever emitted the host can take it down again. */
31
+
32
+ /**
33
+ * Unique per mount rather than per diff, because ProseMirror draws a replacement widget before it
34
+ * destroys the widget being replaced: on a shared key the outgoing widget's `destroy` would
35
+ * unregister the incoming widget's portal.
36
+ */
37
+ var nextContributorTagPortalId = 0;
38
+
39
+ /**
40
+ * Renders the tag into `host` through the editor's portal provider, the way the rest of the editor
41
+ * mounts React into decorations. The tag resolves its own model from plugin state, so a redraw of
42
+ * the host re-parents the tag instead of stranding it, and `isActive` changes arrive as a re-render.
43
+ */
44
+ var mountContributorTag = exports.mountContributorTag = function mountContributorTag(_ref) {
45
+ var diffId = _ref.diffId,
46
+ host = _ref.host,
47
+ mountContext = _ref.mountContext;
48
+ if (!mountContext) {
49
+ return undefined;
50
+ }
51
+ var api = mountContext.api,
52
+ getEditorRoot = mountContext.getEditorRoot,
53
+ portalProviderAPI = mountContext.portalProviderAPI;
54
+ var key = "".concat(_decorationKeys.DecorationFamily.contributorTag, "-").concat(diffId, "-").concat(nextContributorTagPortalId++);
55
+ portalProviderAPI.render(function () {
56
+ return /*#__PURE__*/(0, _react.createElement)(_ContributorTagWidget.ContributorTagWidget, {
57
+ api: api,
58
+ diffId: diffId,
59
+ getEditorRoot: getEditorRoot
60
+ });
61
+ }, host, key);
62
+ return {
63
+ key: key,
64
+ portalProviderAPI: portalProviderAPI
65
+ };
66
+ };
67
+ var unmountContributorTag = exports.unmountContributorTag = function unmountContributorTag(mount) {
68
+ mount === null || mount === void 0 || mount.portalProviderAPI.remove(mount.key);
69
+ };
70
+
71
+ /**
72
+ * A zero-size inline host for one contributor tag. `position: relative` makes it the containing
73
+ * block of the absolutely positioned tag, so the tag sits on the change with no measurement.
74
+ */
75
+ var buildContributorTagHost = function buildContributorTagHost(diffId) {
76
+ var host = document.createElement('span');
77
+ host.setAttribute(CONTRIBUTOR_TAG_HOST_ATTRIBUTE, diffId);
78
+ host.style.setProperty('position', 'relative');
79
+ return host;
80
+ };
81
+
82
+ /**
83
+ * The host for a tag on deleted content, which renders inside its own widget decoration rather than
84
+ * needing one of its own. Unmount with `unmountContributorTag` from that widget's `destroy`.
85
+ */
86
+ var createContributorTagHost = exports.createContributorTagHost = function createContributorTagHost(diffId, mountContext) {
87
+ if (!isContributorTagWidgetEnabled()) {
88
+ return undefined;
89
+ }
90
+ var host = buildContributorTagHost(diffId);
91
+ return {
92
+ host: host,
93
+ mount: mountContributorTag({
94
+ diffId: diffId,
95
+ host: host,
96
+ mountContext: mountContext
97
+ })
98
+ };
99
+ };
100
+
101
+ /**
102
+ * The start of the inline content that `[from, to)` actually highlights.
103
+ *
104
+ * `from` is not sufficient: a range can begin at the tail of one paragraph and only cover text in a
105
+ * later block, and ProseMirror clips `Decoration.inline` to the content it can paint — so a host
106
+ * left at `from` would sit lines away from the highlight.
107
+ */
108
+ var resolveInlineContentStart = function resolveInlineContentStart(doc, from, to) {
109
+ var edge;
110
+ doc.nodesBetween(from, to, function (node, nodePos) {
111
+ if (!node.isTextblock) {
112
+ return edge === undefined;
113
+ }
114
+
115
+ // The slice of this block the range actually covers; empty means nothing paintable.
116
+ var contentFrom = Math.max(nodePos + 1, from);
117
+ var contentTo = Math.min(nodePos + 1 + node.content.size, to);
118
+ if (contentTo > contentFrom && edge === undefined) {
119
+ edge = contentFrom;
120
+ }
121
+
122
+ // Textblocks have no block children to descend into.
123
+ return false;
124
+ });
125
+ return edge !== null && edge !== void 0 ? edge : from;
126
+ };
127
+
128
+ /**
129
+ * A widget hosting the contributor tag of one inline diff range, placed on the first character the
130
+ * range highlights.
131
+ *
132
+ * The tag is mounted in `toDOM` and taken down in `destroy`, so it lives exactly as long as the host
133
+ * element ProseMirror drew it into — see `mountContributorTag`.
134
+ */
135
+ var createContributorTagWidget = exports.createContributorTagWidget = function createContributorTagWidget(_ref2) {
136
+ var doc = _ref2.doc,
137
+ from = _ref2.from,
138
+ to = _ref2.to,
139
+ diffId = _ref2.diffId,
140
+ mountContext = _ref2.mountContext;
141
+ if (!isContributorTagWidgetEnabled()) {
142
+ return undefined;
143
+ }
144
+
145
+ // Reassigned when ProseMirror redraws this decoration, which it may do more than once for the
146
+ // same `Decoration` instance.
147
+ var mount;
148
+ return _view.Decoration.widget(
149
+ // Keep the host out of the table row's grid (EDITOR-8442).
150
+ (0, _createAnchorDecorationWidgets.clampAnchorPosIntoCell)(doc, resolveInlineContentStart(doc, from, to), 1), function () {
151
+ var host = buildContributorTagHost(diffId);
152
+ mount = mountContributorTag({
153
+ diffId: diffId,
154
+ host: host,
155
+ mountContext: mountContext
156
+ });
157
+ return host;
158
+ }, _objectSpread(_objectSpread({}, (0, _decorationKeys.buildContributorTagDecorationSpec)(diffId)), {}, {
159
+ side: 1,
160
+ // The tag is chrome: it inherits no surrounding mark, and its own events are not the
161
+ // document's to handle.
162
+ marks: [],
163
+ ignoreSelection: true,
164
+ stopEvent: function stopEvent() {
165
+ return true;
166
+ },
167
+ destroy: function destroy() {
168
+ unmountContributorTag(mount);
169
+ mount = undefined;
170
+ }
171
+ }));
172
+ };
@@ -14,6 +14,7 @@ var _isExtendedEnabled = require("../isExtendedEnabled");
14
14
  var _factory = require("./colorSchemes/factory");
15
15
  var _schemes = require("./colorSchemes/schemes");
16
16
  var _createAnchorDecorationWidgets = require("./createAnchorDecorationWidgets");
17
+ var _createContributorTagWidget = require("./createContributorTagWidget");
17
18
  var _createInlineChangedDecorationStyles = require("./createInlineChangedDecoration.styles.legacy");
18
19
  var _decorationKeys = require("./decorationKeys");
19
20
  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; }
@@ -109,7 +110,8 @@ var getAtomicInlineChangedAttrs = exports.getAtomicInlineChangedAttrs = function
109
110
  */
110
111
 
111
112
  var createInlineChangedDecoration = exports.createInlineChangedDecoration = function createInlineChangedDecoration(_ref2) {
112
- var change = _ref2.change,
113
+ var attributionKey = _ref2.attributionKey,
114
+ change = _ref2.change,
113
115
  colorScheme = _ref2.colorScheme,
114
116
  _ref2$isActive = _ref2.isActive,
115
117
  isActive = _ref2$isActive === void 0 ? false : _ref2$isActive,
@@ -119,6 +121,8 @@ var createInlineChangedDecoration = exports.createInlineChangedDecoration = func
119
121
  isAtomicInlineNode = _ref2$isAtomicInlineN === void 0 ? false : _ref2$isAtomicInlineN,
120
122
  _ref2$shouldHideDelet = _ref2.shouldHideDeleted,
121
123
  shouldHideDeleted = _ref2$shouldHideDelet === void 0 ? false : _ref2$shouldHideDelet,
124
+ _ref2$showContributor = _ref2.showContributorTags,
125
+ showContributorTags = _ref2$showContributor === void 0 ? false : _ref2$showContributor,
122
126
  _ref2$showIndicators = _ref2.showIndicators,
123
127
  showIndicators = _ref2$showIndicators === void 0 ? false : _ref2$showIndicators,
124
128
  doc = _ref2.doc,
@@ -129,15 +133,23 @@ var createInlineChangedDecoration = exports.createInlineChangedDecoration = func
129
133
  _ref2$hasDeletedWidge = _ref2.hasDeletedWidget,
130
134
  hasDeletedWidget = _ref2$hasDeletedWidge === void 0 ? false : _ref2$hasDeletedWidge,
131
135
  _ref2$isDeletedWidget = _ref2.isDeletedWidgetBelow,
132
- isDeletedWidgetBelow = _ref2$isDeletedWidget === void 0 ? false : _ref2$isDeletedWidget;
133
- var diffId = crypto.randomUUID();
136
+ isDeletedWidgetBelow = _ref2$isDeletedWidget === void 0 ? false : _ref2$isDeletedWidget,
137
+ tagMountContext = _ref2.tagMountContext;
138
+ // Derived from the range so it survives a recalculation: stepping to the next/previous change
139
+ // rebuilds decorations without touching the doc, and a fresh id would change the React key and the
140
+ // tag host's key, remounting every tag mid-step. Random ids are kept when tags are off.
141
+ var diffId = showContributorTags ? "inline-".concat(change.fromB, "-").concat(change.toB) : crypto.randomUUID();
134
142
  if (shouldHideDeleted) {
135
143
  return [_view.Decoration.inline(change.fromB, change.toB, {
136
144
  style: displayNoneStyle
137
145
  }, (0, _decorationKeys.buildDiffDecorationSpec)({
146
+ // No attribution: this decoration paints nothing and emits no tag host, so a tag
147
+ // resolved from it would have nowhere to render.
148
+ colorScheme: colorScheme,
138
149
  decorationType: 'inline',
139
150
  diffId: diffId,
140
- isActive: isActive
151
+ isActive: isActive,
152
+ isInserted: isInserted
141
153
  }))];
142
154
  }
143
155
  var colors = getColorScheme(colorScheme);
@@ -157,10 +169,15 @@ var createInlineChangedDecoration = exports.createInlineChangedDecoration = func
157
169
  class: atomicInlineAttrs.className
158
170
  }), {}, {
159
171
  'data-testid': 'show-diff-changed-decoration'
172
+ }, showContributorTags && {
173
+ 'data-diff-id': diffId
160
174
  }), (0, _decorationKeys.buildDiffDecorationSpec)({
175
+ attributionKey: attributionKey,
176
+ colorScheme: colorScheme,
161
177
  decorationType: 'inline',
162
178
  diffId: diffId,
163
- isActive: isActive
179
+ isActive: isActive,
180
+ isInserted: isInserted
164
181
  }))];
165
182
  if (showIndicators && doc && (0, _isExtendedEnabled.isExtendedEnabled)(diffType)) {
166
183
  // For paragraphs, fromB/toB land on the outer block
@@ -197,5 +214,20 @@ var createInlineChangedDecoration = exports.createInlineChangedDecoration = func
197
214
  diffId: diffId
198
215
  })));
199
216
  }
217
+
218
+ // Built from the raw change range, not the anchors above: a tag lines up with the changed text,
219
+ // while the bar's anchors are held on a block boundary when a deleted widget renders beside them.
220
+ if (showContributorTags && doc && (0, _isExtendedEnabled.isExtendedEnabled)(diffType)) {
221
+ var tagWidget = (0, _createContributorTagWidget.createContributorTagWidget)({
222
+ doc: doc,
223
+ from: change.fromB,
224
+ to: change.toB,
225
+ diffId: diffId,
226
+ mountContext: tagMountContext
227
+ });
228
+ if (tagWidget) {
229
+ decorations.push(tagWidget);
230
+ }
231
+ }
200
232
  return decorations;
201
233
  };
@@ -11,6 +11,7 @@ var _fg = require("@atlaskit/platform-feature-flags/fg");
11
11
  var _isExtendedEnabled = require("../isExtendedEnabled");
12
12
  var _createAnchorDecorationWidgets = require("./createAnchorDecorationWidgets");
13
13
  var _createChangedRowDecorationWidgets = require("./createChangedRowDecorationWidgets");
14
+ var _createContributorTagWidget = require("./createContributorTagWidget");
14
15
  var _decorationKeys = require("./decorationKeys");
15
16
  var _findSafeInsertPos = require("./utils/findSafeInsertPos");
16
17
  var _wrapBlockNodeView = require("./utils/wrapBlockNodeView");
@@ -98,7 +99,8 @@ var createTableCellContentWidgets = function createTableCellContentWidgets(_ref)
98
99
  */
99
100
  var createNodeChangedDecorationWidget = exports.createNodeChangedDecorationWidget = function createNodeChangedDecorationWidget(_ref2) {
100
101
  var _slice$content, _slice$content2, _slice$content3, _$safeInsertPos$nodeB, _slice$content$firstC, _newDoc$firstChild, _slice$content$firstC2;
101
- var change = _ref2.change,
102
+ var attributionKey = _ref2.attributionKey,
103
+ change = _ref2.change,
102
104
  doc = _ref2.doc,
103
105
  nodeViewSerializer = _ref2.nodeViewSerializer,
104
106
  colorScheme = _ref2.colorScheme,
@@ -107,13 +109,16 @@ var createNodeChangedDecorationWidget = exports.createNodeChangedDecorationWidge
107
109
  activeIndexPos = _ref2.activeIndexPos,
108
110
  _ref2$isInserted = _ref2.isInserted,
109
111
  isInserted = _ref2$isInserted === void 0 ? false : _ref2$isInserted,
112
+ _ref2$showContributor = _ref2.showContributorTags,
113
+ showContributorTags = _ref2$showContributor === void 0 ? false : _ref2$showContributor,
110
114
  _ref2$showIndicators = _ref2.showIndicators,
111
115
  showIndicators = _ref2$showIndicators === void 0 ? false : _ref2$showIndicators,
112
116
  _ref2$placeBelow = _ref2.placeBelow,
113
117
  placeBelow = _ref2$placeBelow === void 0 ? false : _ref2$placeBelow,
114
118
  diffType = _ref2.diffType,
115
119
  _ref2$hideAddedDiffsU = _ref2.hideAddedDiffsUnderline,
116
- hideAddedDiffsUnderline = _ref2$hideAddedDiffsU === void 0 ? false : _ref2$hideAddedDiffsU;
120
+ hideAddedDiffsUnderline = _ref2$hideAddedDiffsU === void 0 ? false : _ref2$hideAddedDiffsU,
121
+ tagMountContext = _ref2.tagMountContext;
117
122
  var slice = doc.slice(change.fromA, change.toA);
118
123
  var shouldSkipDeletedEmptyParagraphDecoration = !isInserted && (slice === null || slice === void 0 || (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.childCount) === 1 && (slice === null || slice === void 0 || (_slice$content2 = slice.content) === null || _slice$content2 === void 0 || (_slice$content2 = _slice$content2.firstChild) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.type.name) === 'paragraph' && (slice === null || slice === void 0 || (_slice$content3 = slice.content) === null || _slice$content3 === void 0 || (_slice$content3 = _slice$content3.firstChild) === null || _slice$content3 === void 0 ? void 0 : _slice$content3.content.size) === 0;
119
124
  // Widget decoration used for deletions as the content is not in the document
@@ -211,7 +216,9 @@ var createNodeChangedDecorationWidget = exports.createNodeChangedDecorationWidge
211
216
  subtree: true
212
217
  });
213
218
  }
214
- var diffId = crypto.randomUUID();
219
+ // Derived from the deleted range so it survives a recalculation — see the same reasoning in
220
+ // `createInlineChangedDecoration`.
221
+ var diffId = showContributorTags ? "widget-".concat(change.fromA, "-").concat(change.toA) : crypto.randomUUID();
215
222
  var decorations = [];
216
223
  var replacementNode = newDoc.nodeAt(change.fromB);
217
224
  var firstReplacedNode = slice.content.firstChild;
@@ -334,23 +341,47 @@ var createNodeChangedDecorationWidget = exports.createNodeChangedDecorationWidge
334
341
  }
335
342
  });
336
343
  dom.setAttribute('data-testid', 'show-diff-deleted-decoration');
344
+
345
+ // Needed even when the indicator bar is off, because a contributor tag also anchors against the
346
+ // widget.
347
+ if ((showIndicators || showContributorTags) && (0, _isExtendedEnabled.isExtendedEnabled)(diffType)) {
348
+ dom.style.setProperty('anchor-name', "--".concat((0, _decorationKeys.buildAnchorDecorationKey)({
349
+ diffId: diffId
350
+ })));
351
+ }
352
+
353
+ // Taken down in the widget's `destroy` below: `dom` is rebuilt on every recalculation, so the tag
354
+ // mounted into it must not outlive the copy ProseMirror is drawing.
355
+ var tagMount;
356
+ if (showContributorTags) {
357
+ // Lets the contributor tag find the deleted content on hover.
358
+ dom.setAttribute('data-diff-id', diffId);
359
+
360
+ // Hosted at the start of the deleted run rather than on `dom` itself: `dom` is inline, so once
361
+ // the deleted content wraps its box is the union of its line fragments.
362
+ var tagHost = (0, _createContributorTagWidget.createContributorTagHost)(diffId, tagMountContext);
363
+ if (tagHost) {
364
+ dom.prepend(tagHost.host);
365
+ tagMount = tagHost.mount;
366
+ }
367
+ }
337
368
  if (showIndicators && (0, _isExtendedEnabled.isExtendedEnabled)(diffType)) {
338
369
  var leftAnchor = (0, _createAnchorDecorationWidgets.createLeftAnchorWidget)({
339
370
  doc: newDoc,
340
371
  from: safeInsertPos,
341
372
  diffId: diffId
342
373
  });
343
- dom.style.setProperty('anchor-name', "--".concat((0, _decorationKeys.buildAnchorDecorationKey)({
344
- diffId: diffId
345
- })));
346
374
  if (leftAnchor) {
347
375
  decorations.push(leftAnchor);
348
376
  }
349
377
  }
350
378
  decorations.push(_view.Decoration.widget(safeInsertPos, dom, _objectSpread(_objectSpread(_objectSpread({}, (0, _decorationKeys.buildDiffDecorationSpec)(_objectSpread({
379
+ attributionKey: attributionKey,
380
+ colorScheme: colorScheme,
351
381
  decorationType: 'widget',
352
382
  diffId: diffId,
353
383
  isActive: isActive,
384
+ isInserted: isInserted,
354
385
  diffType: diffType
355
386
  }, (0, _isExtendedEnabled.isExtendedEnabled)(diffType) && {
356
387
  // placeBelow anchors at the end of the new content, so render on the
@@ -361,7 +392,9 @@ var createNodeChangedDecorationWidget = exports.createNodeChangedDecorationWidge
361
392
  }), {}, {
362
393
  destroy: function destroy() {
363
394
  var _constrainMediaObserv2;
364
- return (_constrainMediaObserv2 = constrainMediaObserver) === null || _constrainMediaObserv2 === void 0 ? void 0 : _constrainMediaObserv2.disconnect();
395
+ (_constrainMediaObserv2 = constrainMediaObserver) === null || _constrainMediaObserv2 === void 0 || _constrainMediaObserv2.disconnect();
396
+ (0, _createContributorTagWidget.unmountContributorTag)(tagMount);
397
+ tagMount = undefined;
365
398
  }
366
399
  })));
367
400
 
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", {
6
6
  });
7
7
  exports.buildAnchorDecorationKey = exports.DiffDecorationKey = exports.DecorationFamily = exports.AnchorTypeKey = exports.AnchorDocMarginKey = void 0;
8
8
  exports.buildAnchorDecorationSpec = buildAnchorDecorationSpec;
9
- exports.isDiffDecorationSpec = exports.isDiffDecoration = exports.isAnchorDecorationSpec = exports.extractDiffDescriptors = exports.buildDiffDecorationSpec = exports.buildDiffDecorationKey = void 0;
9
+ exports.isDiffDecorationSpec = exports.isDiffDecoration = exports.isAnchorDecorationSpec = exports.extractDiffDescriptors = exports.buildDiffDecorationSpec = exports.buildDiffDecorationKey = exports.buildContributorTagDecorationSpec = void 0;
10
10
  var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
11
11
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
12
12
  var _isExtendedEnabled = require("../isExtendedEnabled");
@@ -18,7 +18,8 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
18
18
  */
19
19
  var DecorationFamily = exports.DecorationFamily = {
20
20
  diff: 'diff',
21
- anchor: 'anchor'
21
+ anchor: 'anchor',
22
+ contributorTag: 'contributor-tag'
22
23
  };
23
24
  var AnchorTypeKey = exports.AnchorTypeKey = {
24
25
  from: 'from',
@@ -26,6 +27,12 @@ var AnchorTypeKey = exports.AnchorTypeKey = {
26
27
  left: 'left',
27
28
  docMargin: 'doc-margin'
28
29
  };
30
+
31
+ /**
32
+ * The host widget one contributor tag renders into. Its own family, so the tag never reaches the
33
+ * consumers that read diff decorations — change counting, navigation and `getDeletedWidgets`.
34
+ */
35
+
29
36
  /**
30
37
  * The diff-decoration kinds produced by the show-diff plugin. Each value is
31
38
  * the leading segment of the generated key, so a diff decoration's kind can be
@@ -59,13 +66,16 @@ var buildDiffDecorationKey = exports.buildDiffDecorationKey = function buildDiff
59
66
  return isActive !== undefined ? "".concat(decorationKeyPrefix, "-").concat(isActive ? 'active' : 'inactive') : decorationKeyPrefix;
60
67
  };
61
68
  var buildDiffDecorationSpec = exports.buildDiffDecorationSpec = function buildDiffDecorationSpec(_ref3) {
62
- var decorationType = _ref3.decorationType,
69
+ var attributionKey = _ref3.attributionKey,
70
+ colorScheme = _ref3.colorScheme,
71
+ decorationType = _ref3.decorationType,
63
72
  diffId = _ref3.diffId,
64
73
  isActive = _ref3.isActive,
74
+ isInserted = _ref3.isInserted,
65
75
  nodeName = _ref3.nodeName,
66
76
  side = _ref3.side,
67
77
  diffType = _ref3.diffType;
68
- return _objectSpread(_objectSpread({
78
+ return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
69
79
  decorationFamily: DecorationFamily.diff,
70
80
  decorationType: decorationType,
71
81
  diffId: diffId,
@@ -75,7 +85,15 @@ var buildDiffDecorationSpec = exports.buildDiffDecorationSpec = function buildDi
75
85
  isActive: isActive,
76
86
  diffType: diffType
77
87
  })
78
- }, nodeName ? {
88
+ }, attributionKey ? {
89
+ attributionKey: attributionKey
90
+ } : {}), attributionKey && isActive !== undefined ? {
91
+ isActive: isActive
92
+ } : {}), attributionKey && isInserted !== undefined ? {
93
+ isInserted: isInserted
94
+ } : {}), attributionKey && colorScheme ? {
95
+ colorScheme: colorScheme
96
+ } : {}), nodeName ? {
79
97
  nodeName: nodeName
80
98
  } : {}), side !== undefined ? {
81
99
  side: side
@@ -109,6 +127,14 @@ function buildAnchorDecorationSpec(_ref4) {
109
127
  side: side
110
128
  } : {});
111
129
  }
130
+ var buildContributorTagDecorationSpec = exports.buildContributorTagDecorationSpec = function buildContributorTagDecorationSpec(diffId) {
131
+ return {
132
+ decorationFamily: DecorationFamily.contributorTag,
133
+ diffId: diffId,
134
+ // Stable across recalculations, so ProseMirror keeps the host element the tag is portalled into.
135
+ key: "".concat(DecorationFamily.contributorTag, "-").concat(diffId)
136
+ };
137
+ };
112
138
  var isDiffDecorationSpec = exports.isDiffDecorationSpec = function isDiffDecorationSpec(spec) {
113
139
  return Boolean(spec && (0, _typeof2.default)(spec) === 'object' && 'decorationFamily' in spec && spec.decorationFamily === DecorationFamily.diff);
114
140
  };