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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/afm-products/tsconfig.json +3 -0
  3. package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +91 -51
  4. package/dist/cjs/pm-plugins/decorations/createContributorTagWidget.js +20 -1
  5. package/dist/cjs/pm-plugins/decorations/extractContributorTags.js +121 -21
  6. package/dist/cjs/pm-plugins/decorations/utils/getAttrChangeRanges.js +19 -8
  7. package/dist/cjs/pm-plugins/decorations/utils/getMarkChangeRanges.js +18 -4
  8. package/dist/cjs/pm-plugins/decorations/utils/mapStepRangeToFinal.js +34 -0
  9. package/dist/cjs/pm-plugins/main.js +18 -0
  10. package/dist/cjs/ui/ContributorTag/buildContributorTagDom.js +51 -5
  11. package/dist/cjs/ui/ContributorTag/contributorLabel.js +55 -0
  12. package/dist/cjs/ui/ContributorTag/contributorTagController.js +40 -43
  13. package/dist/cjs/ui/ContributorTag/messages.js +5 -0
  14. package/dist/cjs/ui/DiffNavigation/announceActiveDiff.js +54 -0
  15. package/dist/cjs/ui/DiffNavigation/messages.js +19 -0
  16. package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +48 -13
  17. package/dist/es2019/pm-plugins/decorations/createContributorTagWidget.js +18 -1
  18. package/dist/es2019/pm-plugins/decorations/extractContributorTags.js +70 -10
  19. package/dist/es2019/pm-plugins/decorations/utils/getAttrChangeRanges.js +16 -0
  20. package/dist/es2019/pm-plugins/decorations/utils/getMarkChangeRanges.js +12 -4
  21. package/dist/es2019/pm-plugins/decorations/utils/mapStepRangeToFinal.js +28 -0
  22. package/dist/es2019/pm-plugins/main.js +18 -0
  23. package/dist/es2019/ui/ContributorTag/buildContributorTagDom.js +48 -4
  24. package/dist/es2019/ui/ContributorTag/contributorLabel.js +49 -0
  25. package/dist/es2019/ui/ContributorTag/contributorTagController.js +39 -44
  26. package/dist/es2019/ui/ContributorTag/messages.js +5 -0
  27. package/dist/es2019/ui/DiffNavigation/announceActiveDiff.js +49 -0
  28. package/dist/es2019/ui/DiffNavigation/messages.js +13 -0
  29. package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +91 -51
  30. package/dist/esm/pm-plugins/decorations/createContributorTagWidget.js +20 -1
  31. package/dist/esm/pm-plugins/decorations/extractContributorTags.js +121 -21
  32. package/dist/esm/pm-plugins/decorations/utils/getAttrChangeRanges.js +19 -8
  33. package/dist/esm/pm-plugins/decorations/utils/getMarkChangeRanges.js +17 -4
  34. package/dist/esm/pm-plugins/decorations/utils/mapStepRangeToFinal.js +28 -0
  35. package/dist/esm/pm-plugins/main.js +18 -0
  36. package/dist/esm/ui/ContributorTag/buildContributorTagDom.js +50 -4
  37. package/dist/esm/ui/ContributorTag/contributorLabel.js +49 -0
  38. package/dist/esm/ui/ContributorTag/contributorTagController.js +41 -44
  39. package/dist/esm/ui/ContributorTag/messages.js +5 -0
  40. package/dist/esm/ui/DiffNavigation/announceActiveDiff.js +48 -0
  41. package/dist/esm/ui/DiffNavigation/messages.js +13 -0
  42. package/dist/types/pm-plugins/decorations/extractContributorTags.d.ts +14 -1
  43. package/dist/types/pm-plugins/decorations/utils/getAttrChangeRanges.d.ts +3 -0
  44. package/dist/types/pm-plugins/decorations/utils/getMarkChangeRanges.d.ts +4 -1
  45. package/dist/types/pm-plugins/decorations/utils/mapStepRangeToFinal.d.ts +8 -0
  46. package/dist/types/showDiffPluginType.d.ts +7 -1
  47. package/dist/types/ui/ContributorTag/buildContributorTagDom.d.ts +12 -2
  48. package/dist/types/ui/ContributorTag/contributorLabel.d.ts +13 -0
  49. package/dist/types/ui/ContributorTag/contributorTagController.d.ts +11 -0
  50. package/dist/types/ui/ContributorTag/messages.d.ts +1 -0
  51. package/dist/types/ui/DiffNavigation/announceActiveDiff.d.ts +18 -0
  52. package/dist/types/ui/DiffNavigation/messages.d.ts +5 -0
  53. package/package.json +5 -4
@@ -25,6 +25,7 @@ import { extractDiffDescriptors } from '../decorations/decorationKeys';
25
25
  import { extractContributorTags } from '../decorations/extractContributorTags';
26
26
  import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
27
27
  import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
28
+ import { getScrollableDecorations } from '../getScrollableDecorations';
28
29
  import { getDefaultDiffType, isExtendedEnabled } from '../isExtendedEnabled';
29
30
  import { diffBySteps } from './diffBySteps';
30
31
  import { groupChangesByBlock } from './groupChangesByBlock';
@@ -337,15 +338,18 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
337
338
  }
338
339
  var pendingAttrSteps = [];
339
340
  var stepMaps = [];
340
- var _iterator = _createForOfIteratorHelper(simplifiedSteps),
341
+ var _iterator = _createForOfIteratorHelper(simplifiedSteps.entries()),
341
342
  _step;
342
343
  try {
343
344
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
344
- var step = _step.value;
345
+ var _step$value = _slicedToArray(_step.value, 2),
346
+ stepIndex = _step$value[0],
347
+ step = _step$value[1];
345
348
  var result = step.apply(steppedDoc);
346
349
  if (result.failed === null && result.doc) {
347
350
  if (stepIsValidAttrChange(step, steppedDoc, result.doc)) {
348
351
  pendingAttrSteps.push({
352
+ attributionKey: getAttributionKey(simplifiedStepAttributions[stepIndex]),
349
353
  afterNode: result.doc.nodeAt(step.pos),
350
354
  beforeNode: steppedDoc.nodeAt(step.pos),
351
355
  mapIndex: stepMaps.length,
@@ -365,6 +369,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
365
369
  }
366
370
  var attrStepContexts = fg('platform_editor_reduce_diff_attr_sensitivity') ? pendingAttrSteps.flatMap(function (_ref1) {
367
371
  var afterNode = _ref1.afterNode,
372
+ attributionKey = _ref1.attributionKey,
368
373
  beforeNode = _ref1.beforeNode,
369
374
  mapIndex = _ref1.mapIndex,
370
375
  step = _ref1.step;
@@ -374,6 +379,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
374
379
  }
375
380
  var originalPosition = new Mapping(stepMaps.slice(0, mapIndex)).invert().mapResult(step.pos);
376
381
  return [_objectSpread(_objectSpread({
382
+ attributionKey: attributionKey,
377
383
  afterNode: afterNode,
378
384
  beforeNode: beforeNode,
379
385
  finalPos: finalPosition.pos
@@ -383,8 +389,10 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
383
389
  step: step
384
390
  })];
385
391
  }) : pendingAttrSteps.map(function (_ref10) {
386
- var step = _ref10.step;
392
+ var attributionKey = _ref10.attributionKey,
393
+ step = _ref10.step;
387
394
  return {
395
+ attributionKey: attributionKey,
388
396
  afterNode: tr.doc.nodeAt(step.pos),
389
397
  beforeNode: originalDoc.nodeAt(step.pos),
390
398
  finalPos: step.pos,
@@ -649,34 +657,54 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
649
657
  // smart path. Only add the legacy step-range decoration when no equivalent changeset range was
650
658
  // produced; otherwise the same content receives two inline decorations (and two navigation
651
659
  // changes), usually one attribution colour and one default purple decoration.
652
- getMarkChangeRanges(steps).filter(function (_ref11) {
660
+ getMarkChangeRanges(simplifiedSteps, simplifiedStepAttributions, fg('confluence_ncs_step_diffing_version_history') ? stepMaps : undefined).filter(function (_ref11) {
653
661
  var fromB = _ref11.fromB,
654
662
  toB = _ref11.toB;
655
663
  return !fg('confluence_ncs_step_diffing_version_history') || !changes.some(function (change) {
656
664
  return change.fromB === fromB && change.toB === toB;
657
665
  });
658
666
  }).forEach(function (change) {
667
+ var _attributionColors$ge, _attributionColors;
668
+ var changeColorScheme = change.attributionKey ? (_attributionColors$ge = (_attributionColors = attributionColors) === null || _attributionColors === void 0 ? void 0 : _attributionColors.get(change.attributionKey)) !== null && _attributionColors$ge !== void 0 ? _attributionColors$ge : colorScheme : colorScheme;
669
+ var attributionKey = showContributorTags ? change.attributionKey : undefined;
659
670
  var isActive = isRangeActive(activeIndexPos, change.fromB, change.toB);
660
671
  decorations.push.apply(decorations, _toConsumableArray(createInlineChangedDecoration({
672
+ attributionKey: attributionKey,
661
673
  change: change,
662
- colorScheme: colorScheme,
674
+ colorScheme: changeColorScheme,
675
+ doc: tr.doc,
663
676
  diffType: diffType,
664
677
  isActive: isActive,
665
678
  isInserted: true,
666
- reveal: reveal
679
+ reveal: reveal,
680
+ showContributorTags: showContributorTags,
681
+ tagMountContext: tagMountContext
667
682
  })));
668
683
  });
669
- getAttrChangeRanges(tr.doc, attrStepContexts, originalDoc).forEach(function (change) {
684
+ getAttrChangeRanges(tr.doc, attrStepContexts, originalDoc).filter(function (_ref12) {
685
+ var fromB = _ref12.fromB,
686
+ toB = _ref12.toB;
687
+ return !fg('confluence_ncs_step_diffing_version_history') || !changes.some(function (change) {
688
+ return change.fromB === fromB && change.toB === toB;
689
+ });
690
+ }).forEach(function (change) {
691
+ var _attributionColors$ge2, _attributionColors2;
692
+ var changeColorScheme = change.attributionKey ? (_attributionColors$ge2 = (_attributionColors2 = attributionColors) === null || _attributionColors2 === void 0 ? void 0 : _attributionColors2.get(change.attributionKey)) !== null && _attributionColors$ge2 !== void 0 ? _attributionColors$ge2 : colorScheme : colorScheme;
693
+ var attributionKey = showContributorTags ? change.attributionKey : undefined;
670
694
  if (change.isInline) {
671
695
  // Inline nodes (e.g. date, emoji, mention, status) need an inline decoration rather than a block decoration
672
696
  var isActive = isRangeActive(activeIndexPos, change.fromB, change.toB);
673
697
  decorations.push.apply(decorations, _toConsumableArray(createInlineChangedDecoration({
698
+ attributionKey: attributionKey,
674
699
  change: change,
675
- colorScheme: colorScheme,
700
+ colorScheme: changeColorScheme,
701
+ doc: tr.doc,
676
702
  isActive: isActive,
677
703
  isInserted: true,
678
704
  isAtomicInlineNode: true,
679
705
  inlineNodeName: change.inlineNodeName,
706
+ showContributorTags: showContributorTags,
707
+ tagMountContext: tagMountContext,
680
708
  // Suppress the border-bottom underline for atomic inline nodeviews —
681
709
  // it doesn't render on custom nodeview DOM elements and is unnecessary noise.
682
710
  hideAddedDiffsUnderline: true,
@@ -694,12 +722,15 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
694
722
  deleted: []
695
723
  },
696
724
  doc: originalDoc,
725
+ attributionKey: attributionKey,
697
726
  nodeViewSerializer: nodeViewSerializer,
698
- colorScheme: colorScheme,
727
+ colorScheme: changeColorScheme,
699
728
  newDoc: tr.doc,
700
729
  intl: intl,
701
730
  activeIndexPos: activeIndexPos,
702
- isInserted: false
731
+ isInserted: false,
732
+ showContributorTags: showContributorTags,
733
+ tagMountContext: tagMountContext
703
734
  })));
704
735
  }
705
736
  } else {
@@ -707,11 +738,14 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
707
738
  doc: tr.doc,
708
739
  from: change.fromB,
709
740
  to: change.toB,
710
- colorScheme: colorScheme,
741
+ attributionKey: attributionKey,
742
+ colorScheme: changeColorScheme,
711
743
  isInserted: true,
712
744
  activeIndexPos: activeIndexPos,
713
745
  intl: intl,
714
- showIndicators: showIndicators
746
+ showContributorTags: showContributorTags,
747
+ showIndicators: showIndicators,
748
+ tagMountContext: tagMountContext
715
749
  })));
716
750
  // If the original node position is known (e.g. a panel type change), also render
717
751
  // the old block node as a "deleted" widget so the reviewer sees the before/after.
@@ -728,7 +762,8 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
728
762
  },
729
763
  doc: originalDoc,
730
764
  nodeViewSerializer: nodeViewSerializer,
731
- colorScheme: colorScheme,
765
+ attributionKey: attributionKey,
766
+ colorScheme: changeColorScheme,
732
767
  newDoc: tr.doc,
733
768
  intl: intl,
734
769
  activeIndexPos: activeIndexPos,
@@ -738,14 +773,19 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
738
773
  hideAddedDiffsUnderline: hideAddedDiffsUnderline,
739
774
  placeBelow: placeBelow
740
775
  }), {}, {
741
- showIndicators: showIndicators
776
+ showIndicators: showIndicators,
777
+ showContributorTags: showContributorTags,
778
+ tagMountContext: tagMountContext
742
779
  }))));
743
780
  }
744
781
  }
745
782
  });
746
783
  var decorationSet = DecorationSet.empty.add(tr.doc, decorations);
747
784
  return {
748
- contributorTags: showContributorTags ? extractContributorTags(decorationSet, contributors) : [],
785
+ contributorTags: showContributorTags ? extractContributorTags(decorationSet, contributors, activeIndexPos,
786
+ // The stops the step buttons walk, so a stop cannot hold a second tag for one
787
+ // contributor that navigation can never reach.
788
+ getScrollableDecorations(decorationSet, tr.doc, diffType)) : [],
749
789
  decorations: decorationSet,
750
790
  diffDescriptors: extractDiffDescriptors(decorationSet)
751
791
  };
@@ -753,49 +793,49 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
753
793
  export var calculateDiffDecorations = memoizeOne(calculateDiffDecorationsInner,
754
794
  // Cache results unless relevant inputs change. `tagMountContext` is deliberately absent: it is
755
795
  // built once per plugin instance, so it can never be the reason a diff needs recalculating.
756
- function (_ref12, _ref13) {
757
- var _ref17;
758
- var _ref14 = _slicedToArray(_ref12, 1),
759
- _ref14$ = _ref14[0],
760
- pluginState = _ref14$.pluginState,
761
- state = _ref14$.state,
762
- colorScheme = _ref14$.colorScheme,
763
- intl = _ref14$.intl,
764
- activeIndexPos = _ref14$.activeIndexPos,
765
- isInverted = _ref14$.isInverted,
766
- diffType = _ref14$.diffType,
767
- hideDeletedDiffs = _ref14$.hideDeletedDiffs,
768
- hideAddedDiffsUnderline = _ref14$.hideAddedDiffsUnderline,
769
- showIndicators = _ref14$.showIndicators,
770
- smartThresholds = _ref14$.smartThresholds,
771
- deletedDiffPlacement = _ref14$.deletedDiffPlacement,
772
- inlineDeletedDiffPlacement = _ref14$.inlineDeletedDiffPlacement,
773
- reveal = _ref14$.reveal;
796
+ function (_ref13, _ref14) {
797
+ var _ref18;
774
798
  var _ref15 = _slicedToArray(_ref13, 1),
775
799
  _ref15$ = _ref15[0],
776
- lastPluginState = _ref15$.pluginState,
777
- lastState = _ref15$.state,
778
- lastColorScheme = _ref15$.colorScheme,
779
- lastIntl = _ref15$.intl,
780
- lastActiveIndexPos = _ref15$.activeIndexPos,
781
- lastIsInverted = _ref15$.isInverted,
782
- lastDiffType = _ref15$.diffType,
783
- lastHideDeletedDiffs = _ref15$.hideDeletedDiffs,
784
- lastHideAddedDiffsUnderline = _ref15$.hideAddedDiffsUnderline,
785
- lastShowIndicators = _ref15$.showIndicators,
786
- lastSmartThresholds = _ref15$.smartThresholds,
787
- lastDeletedDiffPlacement = _ref15$.deletedDiffPlacement,
788
- lastInlineDeletedDiffPlacement = _ref15$.inlineDeletedDiffPlacement,
789
- lastReveal = _ref15$.reveal;
800
+ pluginState = _ref15$.pluginState,
801
+ state = _ref15$.state,
802
+ colorScheme = _ref15$.colorScheme,
803
+ intl = _ref15$.intl,
804
+ activeIndexPos = _ref15$.activeIndexPos,
805
+ isInverted = _ref15$.isInverted,
806
+ diffType = _ref15$.diffType,
807
+ hideDeletedDiffs = _ref15$.hideDeletedDiffs,
808
+ hideAddedDiffsUnderline = _ref15$.hideAddedDiffsUnderline,
809
+ showIndicators = _ref15$.showIndicators,
810
+ smartThresholds = _ref15$.smartThresholds,
811
+ deletedDiffPlacement = _ref15$.deletedDiffPlacement,
812
+ inlineDeletedDiffPlacement = _ref15$.inlineDeletedDiffPlacement,
813
+ reveal = _ref15$.reveal;
814
+ var _ref16 = _slicedToArray(_ref14, 1),
815
+ _ref16$ = _ref16[0],
816
+ lastPluginState = _ref16$.pluginState,
817
+ lastState = _ref16$.state,
818
+ lastColorScheme = _ref16$.colorScheme,
819
+ lastIntl = _ref16$.intl,
820
+ lastActiveIndexPos = _ref16$.activeIndexPos,
821
+ lastIsInverted = _ref16$.isInverted,
822
+ lastDiffType = _ref16$.diffType,
823
+ lastHideDeletedDiffs = _ref16$.hideDeletedDiffs,
824
+ lastHideAddedDiffsUnderline = _ref16$.hideAddedDiffsUnderline,
825
+ lastShowIndicators = _ref16$.showIndicators,
826
+ lastSmartThresholds = _ref16$.smartThresholds,
827
+ lastDeletedDiffPlacement = _ref16$.deletedDiffPlacement,
828
+ lastInlineDeletedDiffPlacement = _ref16$.inlineDeletedDiffPlacement,
829
+ lastReveal = _ref16$.reveal;
790
830
  var originalDocIsSame = lastPluginState.originalDoc && pluginState.originalDoc && pluginState.originalDoc.eq(lastPluginState.originalDoc);
791
831
  if (isExtendedEnabled(diffType)) {
792
- var _ref16;
793
- return (_ref16 = colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isInverted === lastIsInverted && diffType === lastDiffType && isEqual(activeIndexPos, lastActiveIndexPos) && originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && isEqual(pluginState.stepAttributions, lastPluginState.stepAttributions) &&
832
+ var _ref17;
833
+ return (_ref17 = colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isInverted === lastIsInverted && diffType === lastDiffType && isEqual(activeIndexPos, lastActiveIndexPos) && originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && isEqual(pluginState.stepAttributions, lastPluginState.stepAttributions) &&
794
834
  // Contributors can arrive after the first calculation; without this, tags never appear.
795
835
  isEqual(pluginState.contributors, lastPluginState.contributors) && state.doc.eq(lastState.doc) && hideDeletedDiffs === lastHideDeletedDiffs && hideAddedDiffsUnderline === lastHideAddedDiffsUnderline && showIndicators === lastShowIndicators && isEqual(smartThresholds, lastSmartThresholds) && deletedDiffPlacement === lastDeletedDiffPlacement && inlineDeletedDiffPlacement === lastInlineDeletedDiffPlacement &&
796
836
  // Turning the reveal on or off changes the emitted styles, so a cached result from the
797
837
  // other setting would leave the diff painted in the wrong resting state.
798
- isEqual(reveal, lastReveal)) !== null && _ref16 !== void 0 ? _ref16 : false;
838
+ isEqual(reveal, lastReveal)) !== null && _ref17 !== void 0 ? _ref17 : false;
799
839
  }
800
- return (_ref17 = originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && isEqual(pluginState.stepAttributions, lastPluginState.stepAttributions) && isEqual(pluginState.contributors, lastPluginState.contributors) && state.doc.eq(lastState.doc) && colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isEqual(activeIndexPos, lastActiveIndexPos) && hideDeletedDiffs === lastHideDeletedDiffs) !== null && _ref17 !== void 0 ? _ref17 : false;
840
+ return (_ref18 = originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && isEqual(pluginState.stepAttributions, lastPluginState.stepAttributions) && isEqual(pluginState.contributors, lastPluginState.contributors) && state.doc.eq(lastState.doc) && colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isEqual(activeIndexPos, lastActiveIndexPos) && hideDeletedDiffs === lastHideDeletedDiffs) !== null && _ref18 !== void 0 ? _ref18 : false;
801
841
  });
@@ -42,7 +42,26 @@ export var mountContributorTag = function mountContributorTag(_ref) {
42
42
  diffId: diffId
43
43
  }));
44
44
  controller.mount(host);
45
- return controller;
45
+
46
+ /**
47
+ * Kept alive when ProseMirror only rebuilt the widget desc around this same host: a document
48
+ * change remaps the decoration and fires `destroy`, but an element `toDOM` is reused verbatim
49
+ * and runs no mount callback, so tearing down here left an active change with no tag
50
+ * (EDITOR-8971).
51
+ *
52
+ * Deferred, because the host is still attached while that update is in flight. A host outside a
53
+ * live editor root is a real removal — including the view being destroyed, which drops the root.
54
+ */
55
+ return {
56
+ destroy: function destroy() {
57
+ return queueMicrotask(function () {
58
+ var _mountContext$getEdit;
59
+ if (!host.isConnected || !((_mountContext$getEdit = mountContext.getEditorRoot()) !== null && _mountContext$getEdit !== void 0 && _mountContext$getEdit.contains(host))) {
60
+ controller.destroy();
61
+ }
62
+ });
63
+ }
64
+ };
46
65
  };
47
66
  export var unmountContributorTag = function unmountContributorTag(mount) {
48
67
  mount === null || mount === void 0 || mount.destroy();
@@ -1,3 +1,4 @@
1
+ import _toArray from "@babel/runtime/helpers/toArray";
1
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
3
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
3
4
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
@@ -50,12 +51,48 @@ var isSameBlockChange = function isSameBlockChange(inner, block) {
50
51
  return inner.spec.attributionKey === block.spec.attributionKey && (block.from <= inner.from && inner.to <= block.to || inner.from <= block.from && block.to <= inner.to);
51
52
  };
52
53
 
54
+ /**
55
+ * Which of two changes in the same range leads, and so is the one a tag captions. Position first,
56
+ * then `side`, since deleted content shares its `from` with the content that replaced it and paints
57
+ * above; then the narrower range, so a change nested in another captions itself.
58
+ */
59
+ var byLeadingPosition = function byLeadingPosition(a, b) {
60
+ var _a$decoration$spec$si, _b$decoration$spec$si;
61
+ return a.decoration.from - b.decoration.from || ((_a$decoration$spec$si = a.decoration.spec.side) !== null && _a$decoration$spec$si !== void 0 ? _a$decoration$spec$si : 0) - ((_b$decoration$spec$si = b.decoration.spec.side) !== null && _b$decoration$spec$si !== void 0 ? _b$decoration$spec$si : 0) || a.decoration.to - a.decoration.from - (b.decoration.to - b.decoration.from);
62
+ };
63
+
64
+ /** The targets a navigation range wholly covers, leader first. */
65
+ var containedBy = function containedBy(targets, _ref2) {
66
+ var from = _ref2.from,
67
+ to = _ref2.to;
68
+ return targets.filter(function (_ref3) {
69
+ var decoration = _ref3.decoration;
70
+ return from <= decoration.from && decoration.to <= to;
71
+ }).sort(byLeadingPosition);
72
+ };
73
+
74
+ /**
75
+ * The one tag a navigation step reveals. `spec.isActive` is no use here: it covers everything the
76
+ * group's union range touches, so several tags revealed over each other (EDITOR-8971). Hence
77
+ * containment, and the leading change of what it covers.
78
+ */
79
+ var resolveActiveTarget = function resolveActiveTarget(surviving, activeIndexPos) {
80
+ return containedBy(surviving, activeIndexPos)[0];
81
+ };
82
+
53
83
  /**
54
84
  * One model per diff decoration whose attribution resolves to a supplied contributor; anything
55
85
  * unattributed, untaggable or unresolved is skipped. A replacement's two decorations are collapsed
56
86
  * into a single tag, on whichever half renders first — see `isSameChange` and `leadsReplacement`.
87
+ *
88
+ * `activeIndexPos`, when given, reveals exactly one of the tags — see `resolveActiveTarget`.
89
+ * Absent, each tag keeps the active state its own decoration was drawn with.
90
+ *
91
+ * `stops`, when given, is the navigation stop list the step buttons walk
92
+ * (`getScrollableDecorations`). One contributor cannot hold two tags in one stop, since only the
93
+ * leading one would ever be reachable. Absent, every decoration keeps its own tag.
57
94
  */
58
- export var extractContributorTags = function extractContributorTags(decorations, contributors) {
95
+ export var extractContributorTags = function extractContributorTags(decorations, contributors, activeIndexPos, stops) {
59
96
  if (!contributors) {
60
97
  return [];
61
98
  }
@@ -88,25 +125,30 @@ export var extractContributorTags = function extractContributorTags(decorations,
88
125
  } finally {
89
126
  _iterator.f();
90
127
  }
91
- var inlineTargets = targets.filter(function (_ref2) {
92
- var decoration = _ref2.decoration;
128
+ var inlineTargets = targets.filter(function (_ref4) {
129
+ var decoration = _ref4.decoration;
93
130
  return decoration.spec.decorationType === 'inline';
94
131
  });
95
- var blockTargets = targets.filter(function (_ref3) {
96
- var decoration = _ref3.decoration;
132
+ var blockTargets = targets.filter(function (_ref5) {
133
+ var decoration = _ref5.decoration;
97
134
  return decoration.spec.decorationType === 'block';
98
135
  });
99
- var widgetTargets = targets.filter(function (_ref4) {
100
- var decoration = _ref4.decoration;
136
+ var widgetTargets = targets.filter(function (_ref6) {
137
+ var decoration = _ref6.decoration;
101
138
  return decoration.spec.decorationType === 'widget';
102
139
  });
103
140
  var linkedDiffIds = new Map();
104
141
  var folded = new Set();
105
142
  var fold = function fold(host, target) {
106
- var _linkedDiffIds$get;
143
+ var _linkedDiffIds$get, _linkedDiffIds$get2;
107
144
  folded.add(target);
108
145
  var hostDiffId = host.decoration.spec.diffId;
109
- linkedDiffIds.set(hostDiffId, [].concat(_toConsumableArray((_linkedDiffIds$get = linkedDiffIds.get(hostDiffId)) !== null && _linkedDiffIds$get !== void 0 ? _linkedDiffIds$get : []), [target.decoration.spec.diffId]));
146
+ var targetDiffId = target.decoration.spec.diffId;
147
+ // A target that already hosts folded tags hands them up, so no hover target is orphaned when
148
+ // one host folds into another.
149
+ var inherited = (_linkedDiffIds$get = linkedDiffIds.get(targetDiffId)) !== null && _linkedDiffIds$get !== void 0 ? _linkedDiffIds$get : [];
150
+ linkedDiffIds.delete(targetDiffId);
151
+ linkedDiffIds.set(hostDiffId, [].concat(_toConsumableArray((_linkedDiffIds$get2 = linkedDiffIds.get(hostDiffId)) !== null && _linkedDiffIds$get2 !== void 0 ? _linkedDiffIds$get2 : []), [targetDiffId], _toConsumableArray(inherited)));
110
152
  };
111
153
  var _loop = function _loop() {
112
154
  var target = _targets[_i];
@@ -116,8 +158,8 @@ export var extractContributorTags = function extractContributorTags(decorations,
116
158
  }
117
159
 
118
160
  // A block outranks both other kinds, so it is tried first.
119
- var block = blockTargets.find(function (_ref5) {
120
- var decoration = _ref5.decoration;
161
+ var block = blockTargets.find(function (_ref7) {
162
+ var decoration = _ref7.decoration;
121
163
  return isSameBlockChange(target.decoration, decoration);
122
164
  });
123
165
  if (block) {
@@ -126,8 +168,8 @@ export var extractContributorTags = function extractContributorTags(decorations,
126
168
  }
127
169
  if (decorationType === 'inline') {
128
170
  // The deleted half renders in front of this one, so that half captions the change.
129
- var leadingWidget = widgetTargets.find(function (_ref6) {
130
- var decoration = _ref6.decoration;
171
+ var leadingWidget = widgetTargets.find(function (_ref8) {
172
+ var decoration = _ref8.decoration;
131
173
  return leadsReplacement(decoration) && isSameChange(decoration, target.decoration);
132
174
  });
133
175
  if (leadingWidget) {
@@ -140,8 +182,8 @@ export var extractContributorTags = function extractContributorTags(decorations,
140
182
  if (leadsReplacement(target.decoration)) {
141
183
  return 0; // continue
142
184
  }
143
- var host = inlineTargets.find(function (_ref7) {
144
- var decoration = _ref7.decoration;
185
+ var host = inlineTargets.find(function (_ref9) {
186
+ var decoration = _ref9.decoration;
145
187
  return isSameChange(target.decoration, decoration);
146
188
  });
147
189
  if (host) {
@@ -153,14 +195,72 @@ export var extractContributorTags = function extractContributorTags(decorations,
153
195
  _ret = _loop();
154
196
  if (_ret === 0) continue;
155
197
  }
156
- return targets.filter(function (target) {
198
+
199
+ // One tag per contributor per navigation stop. The folds above only catch a replacement's two
200
+ // halves and a block's own highlights; two of one contributor's changes that merely touch are a
201
+ // single stop (`groupTouchingDecorations`) yet kept a tag each, so the stop's trailing tag was
202
+ // drawn but could never be stepped to (EDITOR-8971). It folds into the leading tag of its
203
+ // contributor, staying a hover target. Contributors are kept apart: a stop spanning two of them
204
+ // still captions each, rather than crediting one for the other's change.
205
+ var _iterator2 = _createForOfIteratorHelper(stops !== null && stops !== void 0 ? stops : []),
206
+ _step2;
207
+ try {
208
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
209
+ var stop = _step2.value;
210
+ var byContributor = new Map();
211
+ var _iterator3 = _createForOfIteratorHelper(containedBy(targets.filter(function (target) {
212
+ return !folded.has(target);
213
+ }), stop)),
214
+ _step3;
215
+ try {
216
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
217
+ var _target$decoration$sp, _byContributor$get;
218
+ var target = _step3.value;
219
+ var key = (_target$decoration$sp = target.decoration.spec.attributionKey) !== null && _target$decoration$sp !== void 0 ? _target$decoration$sp : '';
220
+ byContributor.set(key, [].concat(_toConsumableArray((_byContributor$get = byContributor.get(key)) !== null && _byContributor$get !== void 0 ? _byContributor$get : []), [target]));
221
+ }
222
+ } catch (err) {
223
+ _iterator3.e(err);
224
+ } finally {
225
+ _iterator3.f();
226
+ }
227
+ var _iterator4 = _createForOfIteratorHelper(byContributor.values()),
228
+ _step4;
229
+ try {
230
+ var _loop2 = function _loop2() {
231
+ var _step4$value = _toArray(_step4.value),
232
+ leader = _step4$value[0],
233
+ trailing = _arrayLikeToArray(_step4$value).slice(1);
234
+ trailing.forEach(function (target) {
235
+ return fold(leader, target);
236
+ });
237
+ };
238
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
239
+ _loop2();
240
+ }
241
+ } catch (err) {
242
+ _iterator4.e(err);
243
+ } finally {
244
+ _iterator4.f();
245
+ }
246
+ }
247
+ } catch (err) {
248
+ _iterator2.e(err);
249
+ } finally {
250
+ _iterator2.f();
251
+ }
252
+ var surviving = targets.filter(function (target) {
157
253
  return !folded.has(target);
158
- }).map(function (_ref8) {
159
- var contributor = _ref8.contributor,
160
- spec = _ref8.decoration.spec;
254
+ });
255
+ var activeTarget = activeIndexPos === undefined ? undefined : resolveActiveTarget(surviving, activeIndexPos);
256
+ return surviving.map(function (target) {
257
+ var contributor = target.contributor,
258
+ spec = target.decoration.spec;
161
259
  var connected = contributor.connectedToKey ? contributors[contributor.connectedToKey] : undefined;
162
260
  var connectedContributor = connected ? toTagContributor(connected) : undefined;
163
261
  var linked = linkedDiffIds.get(spec.diffId);
262
+ // Only the navigated tag reveals; with no active range, the decoration's own state stands.
263
+ var isActive = activeIndexPos === undefined ? spec.isActive : target === activeTarget;
164
264
  return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
165
265
  contributor: toTagContributor(contributor),
166
266
  diffId: spec.diffId
@@ -168,8 +268,8 @@ export var extractContributorTags = function extractContributorTags(decorations,
168
268
  connectedContributor: connectedContributor
169
269
  } : {}), spec.colorScheme ? {
170
270
  colorScheme: spec.colorScheme
171
- } : {}), spec.isActive !== undefined ? {
172
- isActive: spec.isActive
271
+ } : {}), isActive !== undefined ? {
272
+ isActive: isActive
173
273
  } : {}), spec.isInserted !== undefined ? {
174
274
  isInserted: spec.isInserted
175
275
  } : {}), linked ? {
@@ -59,6 +59,7 @@ var getStepAttrs = function getStepAttrs(step) {
59
59
  export var getAttrChangeRanges = function getAttrChangeRanges(doc, attrStepContexts, originalDoc) {
60
60
  return attrStepContexts.map(function (attrStepContext) {
61
61
  var afterNode = attrStepContext.afterNode,
62
+ attributionKey = attrStepContext.attributionKey,
62
63
  beforeNode = attrStepContext.beforeNode,
63
64
  finalPos = attrStepContext.finalPos,
64
65
  originalPos = attrStepContext.originalPos,
@@ -86,7 +87,9 @@ export var getAttrChangeRanges = function getAttrChangeRanges(doc, attrStepConte
86
87
  if (attrsToCheck.some(function (v) {
87
88
  return watchedAttrs.includes(v);
88
89
  })) {
89
- return _objectSpread({
90
+ return _objectSpread(_objectSpread({}, attributionKey ? {
91
+ attributionKey: attributionKey
92
+ } : {}), {}, {
90
93
  fromB: finalPos,
91
94
  toB: finalPos + nodeAtPos.nodeSize,
92
95
  isInline: true,
@@ -103,10 +106,12 @@ export var getAttrChangeRanges = function getAttrChangeRanges(doc, attrStepConte
103
106
  if (attrsToCheck.some(function (v) {
104
107
  return taskItemAttrs.includes(v);
105
108
  }) && (nodeAtPos === null || nodeAtPos === void 0 ? void 0 : nodeAtPos.type.name) === 'taskItem') {
106
- return {
109
+ return _objectSpread(_objectSpread({}, attributionKey ? {
110
+ attributionKey: attributionKey
111
+ } : {}), {}, {
107
112
  fromB: finalPos,
108
113
  toB: finalPos + nodeAtPos.nodeSize
109
- };
114
+ });
110
115
  }
111
116
 
112
117
  // panel node (incl. variants like panel_c1): type/colour/icon attribute change
@@ -116,7 +121,9 @@ export var getAttrChangeRanges = function getAttrChangeRanges(doc, attrStepConte
116
121
  if (attrsToCheck.some(function (v) {
117
122
  return panelAttrs.includes(v);
118
123
  }) && nodeAtPos && getBaseNodeTypeName(nodeAtPos.type) === 'panel') {
119
- return _objectSpread({
124
+ return _objectSpread(_objectSpread({}, attributionKey ? {
125
+ attributionKey: attributionKey
126
+ } : {}), {}, {
120
127
  fromB: finalPos,
121
128
  toB: finalPos + nodeAtPos.nodeSize
122
129
  }, originalPos !== undefined && originalNodeAtPos && {
@@ -134,11 +141,13 @@ export var getAttrChangeRanges = function getAttrChangeRanges(doc, attrStepConte
134
141
  return undefined;
135
142
  }
136
143
  var isInline = nodeAtPos.type.name === 'inlineExtension';
137
- return {
144
+ return _objectSpread(_objectSpread({}, attributionKey ? {
145
+ attributionKey: attributionKey
146
+ } : {}), {}, {
138
147
  fromB: finalPos,
139
148
  toB: finalPos + nodeAtPos.nodeSize,
140
149
  isInline: isInline
141
- };
150
+ });
142
151
  }
143
152
 
144
153
  // media node: id/collection/url attribute change — highlight the mediaSingle parent
@@ -146,10 +155,12 @@ export var getAttrChangeRanges = function getAttrChangeRanges(doc, attrStepConte
146
155
  return mediaAttrs.includes(v);
147
156
  }) && $pos.parent.type === doc.type.schema.nodes.mediaSingle) {
148
157
  var startPos = $pos.pos + $pos.parentOffset;
149
- return {
158
+ return _objectSpread(_objectSpread({}, attributionKey ? {
159
+ attributionKey: attributionKey
160
+ } : {}), {}, {
150
161
  fromB: startPos,
151
162
  toB: startPos + $pos.parent.nodeSize - 1
152
- };
163
+ });
153
164
  }
154
165
  return undefined;
155
166
  }).filter(filterUndefined)
@@ -1,7 +1,10 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
1
2
  function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
2
3
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
3
4
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
4
5
  import { AddMarkStep, RemoveMarkStep } from '@atlaskit/editor-prosemirror/transform';
6
+ import { getAttributionKey } from '../colorSchemes/attributions';
7
+ import { mapStepRangeToFinal } from './mapStepRangeToFinal';
5
8
  var extractMarkStep = function extractMarkStep(step) {
6
9
  if (step instanceof AddMarkStep) {
7
10
  return {
@@ -22,13 +25,17 @@ var extractMarkStep = function extractMarkStep(step) {
22
25
  return undefined;
23
26
  };
24
27
  export var getMarkChangeRanges = function getMarkChangeRanges(steps) {
28
+ var stepAttributions = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
29
+ var stepMaps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
25
30
  var resultRanges = [];
26
31
  var lastOp;
27
- var _iterator = _createForOfIteratorHelper(steps),
32
+ var _iterator = _createForOfIteratorHelper(steps.entries()),
28
33
  _step;
29
34
  try {
30
35
  for (_iterator.s(); !(_step = _iterator.n()).done;) {
31
- var step = _step.value;
36
+ var _step$value = _slicedToArray(_step.value, 2),
37
+ stepIndex = _step$value[0],
38
+ step = _step$value[1];
32
39
  var op = extractMarkStep(step);
33
40
  if (!op) {
34
41
  continue;
@@ -38,9 +45,15 @@ export var getMarkChangeRanges = function getMarkChangeRanges(steps) {
38
45
  if (lastOp && lastOp.from === op.from && lastOp.to === op.to && lastOp.markName === op.markName && lastOp.type !== op.type) {
39
46
  resultRanges.pop();
40
47
  } else {
48
+ var finalRange = mapStepRangeToFinal(op.from, op.to, stepIndex, stepMaps);
49
+ if (!finalRange) {
50
+ lastOp = op;
51
+ continue;
52
+ }
41
53
  resultRanges.push({
42
- fromB: op.from,
43
- toB: op.to
54
+ attributionKey: getAttributionKey(stepAttributions[stepIndex]),
55
+ fromB: finalRange.fromB,
56
+ toB: finalRange.toB
44
57
  });
45
58
  }
46
59
  lastOp = op;
@@ -0,0 +1,28 @@
1
+ import { Mapping } from '@atlaskit/editor-prosemirror/transform';
2
+ // ProseMirror's assoc value chooses which side of an insertion a mapped boundary stays on.
3
+ var FROM_ASSOC = -1;
4
+ var TO_ASSOC = 1;
5
+
6
+ /** Maps a step's range into final-document coordinates when the rollout path supplies step maps. */
7
+ export var mapStepRangeToFinal = function mapStepRangeToFinal(from, to, stepIndex, stepMaps) {
8
+ if (!stepMaps) {
9
+ return {
10
+ fromB: from,
11
+ toB: to
12
+ };
13
+ }
14
+
15
+ // The range is already in the document immediately after this step, so skip its own map and
16
+ // apply only the maps from subsequent steps.
17
+ var firstSubsequentStepIndex = stepIndex + 1;
18
+ var finalRange = new Mapping(stepMaps.slice(firstSubsequentStepIndex));
19
+ var fromB = finalRange.mapResult(from, FROM_ASSOC);
20
+ var toB = finalRange.mapResult(to, TO_ASSOC);
21
+ if (fromB.deleted && toB.deleted) {
22
+ return undefined;
23
+ }
24
+ return {
25
+ fromB: fromB.pos,
26
+ toB: toB.pos
27
+ };
28
+ };