@atlaskit/editor-plugin-show-diff 4.0.14 → 4.1.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.
@@ -1,8 +1,9 @@
1
1
  import { processRawValue } from '@atlaskit/editor-common/process-raw-value';
2
2
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
3
- import { PluginKey } from '@atlaskit/editor-prosemirror/state';
3
+ import { PluginKey, NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
4
4
  import { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
5
5
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
6
+ import { fg } from '@atlaskit/platform-feature-flags';
6
7
  import { calculateDiffDecorations } from './calculateDiffDecorations';
7
8
  import { NodeViewSerializer } from './NodeViewSerializer';
8
9
  export const showDiffPluginKey = new PluginKey('showDiffPlugin');
@@ -15,6 +16,42 @@ export const createPlugin = (config, getIntl) => {
15
16
  };
16
17
  return new SafePlugin({
17
18
  key: showDiffPluginKey,
19
+ appendTransaction(transactions, oldState, newState) {
20
+ var _pluginState$activeIn;
21
+ if (!fg('platform_editor_show_diff_scroll_navigation')) {
22
+ return;
23
+ }
24
+ // Check if any transaction contains scroll actions
25
+ const scrollTransaction = transactions.find(tr => {
26
+ var _tr$getMeta, _tr$getMeta2;
27
+ return ((_tr$getMeta = tr.getMeta(showDiffPluginKey)) === null || _tr$getMeta === void 0 ? void 0 : _tr$getMeta.action) === 'SCROLL_TO_NEXT' || ((_tr$getMeta2 = tr.getMeta(showDiffPluginKey)) === null || _tr$getMeta2 === void 0 ? void 0 : _tr$getMeta2.action) === 'SCROLL_TO_PREVIOUS';
28
+ });
29
+ if (!scrollTransaction) {
30
+ return;
31
+ }
32
+ const pluginState = showDiffPluginKey.getState(newState);
33
+ if (!pluginState || pluginState.decorations.find().length === 0) {
34
+ return;
35
+ }
36
+ const decorations = pluginState.decorations.find();
37
+ const decoration = decorations[(_pluginState$activeIn = pluginState.activeIndex) !== null && _pluginState$activeIn !== void 0 ? _pluginState$activeIn : 0];
38
+ if (!decoration) {
39
+ return;
40
+ }
41
+ const {
42
+ from,
43
+ to
44
+ } = decoration;
45
+ const $pos = newState.doc.resolve(from);
46
+ const isNodeSelection = $pos.nodeAfter && $pos.nodeAfter.nodeSize === to - from && !$pos.nodeAfter.isInline;
47
+ const tr = newState.tr;
48
+ if (isNodeSelection) {
49
+ tr.setSelection(NodeSelection.create(newState.doc, from));
50
+ } else {
51
+ tr.setSelection(TextSelection.create(newState.doc, from));
52
+ }
53
+ return tr.scrollIntoView();
54
+ },
18
55
  state: {
19
56
  init(_, _state) {
20
57
  // We do initial setup after we setup the editor view
@@ -34,7 +71,8 @@ export const createPlugin = (config, getIntl) => {
34
71
  newPluginState = {
35
72
  ...currentPluginState,
36
73
  ...meta,
37
- isDisplayingChanges: true
74
+ isDisplayingChanges: true,
75
+ activeIndex: 0
38
76
  };
39
77
  // Calculate and store decorations in state
40
78
  const decorations = calculateDiffDecorations({
@@ -42,7 +80,8 @@ export const createPlugin = (config, getIntl) => {
42
80
  pluginState: newPluginState,
43
81
  nodeViewSerializer,
44
82
  colourScheme: config === null || config === void 0 ? void 0 : config.colourScheme,
45
- intl: getIntl()
83
+ intl: getIntl(),
84
+ activeIndexPos: fg('platform_editor_show_diff_scroll_navigation') ? newPluginState.activeIndexPos : undefined
46
85
  });
47
86
  // Update the decorations
48
87
  newPluginState.decorations = decorations;
@@ -51,8 +90,40 @@ export const createPlugin = (config, getIntl) => {
51
90
  ...currentPluginState,
52
91
  ...meta,
53
92
  decorations: DecorationSet.empty,
54
- isDisplayingChanges: false
93
+ isDisplayingChanges: false,
94
+ activeIndex: undefined
55
95
  };
96
+ } else if (((meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_NEXT' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_PREVIOUS') && fg('platform_editor_show_diff_scroll_navigation')) {
97
+ // Update the active index in plugin state and recalculate decorations
98
+ const decorations = currentPluginState.decorations.find();
99
+ if (decorations.length > 0) {
100
+ var _currentPluginState$a;
101
+ let nextIndex = (_currentPluginState$a = currentPluginState.activeIndex) !== null && _currentPluginState$a !== void 0 ? _currentPluginState$a : 0;
102
+ if (meta.action === 'SCROLL_TO_NEXT') {
103
+ nextIndex = (nextIndex + 1) % decorations.length;
104
+ } else {
105
+ nextIndex = (nextIndex - 1 + decorations.length) % decorations.length;
106
+ }
107
+ const activeDecoration = decorations[nextIndex];
108
+ newPluginState = {
109
+ ...currentPluginState,
110
+ activeIndex: nextIndex,
111
+ activeIndexPos: activeDecoration ? {
112
+ from: activeDecoration.from,
113
+ to: activeDecoration.to
114
+ } : undefined
115
+ };
116
+ // Recalculate decorations with the new active index
117
+ const updatedDecorations = calculateDiffDecorations({
118
+ state: newState,
119
+ pluginState: newPluginState,
120
+ nodeViewSerializer,
121
+ colourScheme: config === null || config === void 0 ? void 0 : config.colourScheme,
122
+ intl: getIntl(),
123
+ activeIndexPos: newPluginState.activeIndexPos
124
+ });
125
+ newPluginState.decorations = updatedDecorations;
126
+ }
56
127
  } else {
57
128
  newPluginState = {
58
129
  ...currentPluginState,
@@ -20,6 +20,20 @@ export const showDiffPlugin = ({
20
20
  steps: [],
21
21
  action: 'HIDE_DIFF'
22
22
  });
23
+ },
24
+ scrollToNext: ({
25
+ tr
26
+ }) => {
27
+ return tr.setMeta(showDiffPluginKey, {
28
+ action: 'SCROLL_TO_NEXT'
29
+ });
30
+ },
31
+ scrollToPrevious: ({
32
+ tr
33
+ }) => {
34
+ return tr.setMeta(showDiffPluginKey, {
35
+ action: 'SCROLL_TO_PREVIOUS'
36
+ });
23
37
  }
24
38
  },
25
39
  pmPlugins() {
@@ -34,13 +48,16 @@ export const showDiffPlugin = ({
34
48
  var _pluginState$decorati;
35
49
  if (!editorState) {
36
50
  return {
37
- isDisplayingChanges: false
51
+ isDisplayingChanges: false,
52
+ activeIndex: undefined
38
53
  };
39
54
  }
40
55
  const pluginState = showDiffPluginKey.getState(editorState);
41
56
  const decorationCount = (pluginState === null || pluginState === void 0 ? void 0 : (_pluginState$decorati = pluginState.decorations) === null || _pluginState$decorati === void 0 ? void 0 : _pluginState$decorati.find()) || [];
42
57
  return {
43
- isDisplayingChanges: decorationCount.length > 0
58
+ isDisplayingChanges: decorationCount.length > 0,
59
+ activeIndex: pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex,
60
+ numberOfChanges: decorationCount.length
44
61
  };
45
62
  }
46
63
  });
@@ -68,7 +68,8 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref)
68
68
  pluginState = _ref.pluginState,
69
69
  nodeViewSerializer = _ref.nodeViewSerializer,
70
70
  colourScheme = _ref.colourScheme,
71
- intl = _ref.intl;
71
+ intl = _ref.intl,
72
+ activeIndexPos = _ref.activeIndexPos;
72
73
  var originalDoc = pluginState.originalDoc,
73
74
  steps = pluginState.steps;
74
75
  if (!originalDoc || !pluginState.isDisplayingChanges) {
@@ -109,18 +110,21 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref)
109
110
  var optimizedChanges = optimizeChanges(changes);
110
111
  var decorations = [];
111
112
  optimizedChanges.forEach(function (change) {
113
+ var isActive = activeIndexPos && change.fromB >= activeIndexPos.from && change.toB <= activeIndexPos.to;
112
114
  if (change.inserted.length > 0) {
113
- decorations.push(createInlineChangedDecoration(change, colourScheme));
115
+ decorations.push(createInlineChangedDecoration(change, colourScheme, isActive));
114
116
  decorations.push.apply(decorations, _toConsumableArray(calculateNodesForBlockDecoration(tr.doc, change.fromB, change.toB, colourScheme)));
115
117
  }
116
118
  if (change.deleted.length > 0) {
119
+ var _isActive = activeIndexPos && change.fromB >= activeIndexPos.from && change.toB <= activeIndexPos.to;
117
120
  var decoration = createDeletedContentDecoration({
118
121
  change: change,
119
122
  doc: originalDoc,
120
123
  nodeViewSerializer: nodeViewSerializer,
121
124
  colourScheme: colourScheme,
122
125
  newDoc: tr.doc,
123
- intl: intl
126
+ intl: intl,
127
+ isActive: _isActive
124
128
  });
125
129
  if (decoration) {
126
130
  decorations.push.apply(decorations, _toConsumableArray(decoration));
@@ -128,7 +132,8 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref)
128
132
  }
129
133
  });
130
134
  getMarkChangeRanges(steps).forEach(function (change) {
131
- decorations.push(createInlineChangedDecoration(change, colourScheme));
135
+ var isActive = activeIndexPos && change.fromB >= activeIndexPos.from && change.toB <= activeIndexPos.to;
136
+ decorations.push(createInlineChangedDecoration(change, colourScheme, isActive));
132
137
  });
133
138
  getAttrChangeRanges(tr.doc, attrSteps).forEach(function (change) {
134
139
  decorations.push.apply(decorations, _toConsumableArray(calculateNodesForBlockDecoration(tr.doc, change.fromB, change.toB, colourScheme)));
@@ -144,13 +149,15 @@ function (_ref2, _ref3) {
144
149
  pluginState = _ref4$.pluginState,
145
150
  state = _ref4$.state,
146
151
  colourScheme = _ref4$.colourScheme,
147
- intl = _ref4$.intl;
152
+ intl = _ref4$.intl,
153
+ activeIndexPos = _ref4$.activeIndexPos;
148
154
  var _ref5 = _slicedToArray(_ref3, 1),
149
155
  _ref5$ = _ref5[0],
150
156
  lastPluginState = _ref5$.pluginState,
151
157
  lastState = _ref5$.state,
152
158
  lastColourScheme = _ref5$.colourScheme,
153
- lastIntl = _ref5$.intl;
159
+ lastIntl = _ref5$.intl,
160
+ lastActiveIndexPos = _ref5$.activeIndexPos;
154
161
  var originalDocIsSame = lastPluginState.originalDoc && pluginState.originalDoc && pluginState.originalDoc.eq(lastPluginState.originalDoc);
155
- return (_ref6 = originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && colourScheme === lastColourScheme && intl.locale === lastIntl.locale) !== null && _ref6 !== void 0 ? _ref6 : false;
162
+ return (_ref6 = originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && colourScheme === lastColourScheme && intl.locale === lastIntl.locale && isEqual(activeIndexPos, lastActiveIndexPos)) !== null && _ref6 !== void 0 ? _ref6 : false;
156
163
  });
@@ -12,6 +12,13 @@ var editingStyle = convertToInlineCss({
12
12
  textDecorationThickness: "var(--ds-space-025, 2px)",
13
13
  textDecorationColor: "var(--ds-border-accent-purple, #AF59E1)"
14
14
  });
15
+ var editingStyleActive = convertToInlineCss({
16
+ background: "var(--ds-background-accent-purple-subtler, #EED7FC)",
17
+ textDecoration: 'underline',
18
+ textDecorationStyle: 'dotted',
19
+ textDecorationThickness: "var(--ds-space-025, 2px)",
20
+ textDecorationColor: "var(--ds-text-accent-purple, #803FA5)"
21
+ });
15
22
  var traditionalInsertStyle = convertToInlineCss({
16
23
  background: "var(--ds-background-accent-green-subtlest, #DCFFF1)",
17
24
  textDecoration: 'underline',
@@ -19,6 +26,13 @@ var traditionalInsertStyle = convertToInlineCss({
19
26
  textDecorationThickness: "var(--ds-space-025, 2px)",
20
27
  textDecorationColor: "var(--ds-border-accent-green, #22A06B)"
21
28
  });
29
+ var traditionalInsertStyleActive = convertToInlineCss({
30
+ background: "var(--ds-background-accent-green-subtler, #BAF3DB)",
31
+ textDecoration: 'underline',
32
+ textDecorationStyle: 'solid',
33
+ textDecorationThickness: "var(--ds-space-025, 2px)",
34
+ textDecorationColor: "var(--ds-text-accent-green, #216E4E)"
35
+ });
22
36
 
23
37
  /**
24
38
  * Inline decoration used for insertions as the content already exists in the document
@@ -27,8 +41,15 @@ var traditionalInsertStyle = convertToInlineCss({
27
41
  * @returns Prosemirror inline decoration
28
42
  */
29
43
  export var createInlineChangedDecoration = function createInlineChangedDecoration(change, colourScheme) {
44
+ var isActive = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
45
+ var style;
46
+ if (colourScheme === 'traditional') {
47
+ style = isActive ? traditionalInsertStyleActive : traditionalInsertStyle;
48
+ } else {
49
+ style = isActive ? editingStyleActive : editingStyle;
50
+ }
30
51
  return Decoration.inline(change.fromB, change.toB, {
31
- style: colourScheme === 'traditional' ? traditionalInsertStyle : editingStyle,
52
+ style: style,
32
53
  'data-testid': 'show-diff-changed-decoration'
33
54
  }, {});
34
55
  };
@@ -106,12 +127,26 @@ var deletedContentStyle = convertToInlineCss({
106
127
  position: 'relative',
107
128
  opacity: 0.6
108
129
  });
130
+ var deletedContentStyleActive = convertToInlineCss({
131
+ color: "var(--ds-text, #292A2E)",
132
+ textDecoration: 'line-through',
133
+ textDecorationColor: "var(--ds-text-accent-gray, #505258)",
134
+ position: 'relative',
135
+ opacity: 1
136
+ });
109
137
  var deletedContentStyleNew = convertToInlineCss({
110
138
  color: "var(--ds-text-accent-gray, #505258)",
111
139
  textDecoration: 'line-through',
112
140
  position: 'relative',
113
141
  opacity: 0.8
114
142
  });
143
+ var deletedContentStyleNewActive = convertToInlineCss({
144
+ color: "var(--ds-text, #292A2E)",
145
+ textDecoration: 'line-through',
146
+ textDecorationColor: "var(--ds-text-accent-gray, #505258)",
147
+ position: 'relative',
148
+ opacity: 1
149
+ });
115
150
  var deletedContentStyleUnbounded = convertToInlineCss({
116
151
  position: 'absolute',
117
152
  top: '50%',
@@ -140,7 +175,14 @@ export var getDeletedContentStyleUnbounded = function getDeletedContentStyleUnbo
140
175
  return colourScheme === 'traditional' ? deletedTraditionalContentStyleUnbounded : deletedContentStyleUnbounded;
141
176
  };
142
177
  export var getDeletedContentStyle = function getDeletedContentStyle(colourScheme) {
143
- return colourScheme === 'traditional' ? deletedTraditionalContentStyle : expValEquals('platform_editor_enghealth_a11y_jan_fixes', 'isEnabled', true) ? deletedContentStyleNew : deletedContentStyle;
178
+ var isActive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
179
+ if (colourScheme === 'traditional') {
180
+ return deletedTraditionalContentStyle;
181
+ }
182
+ if (isActive) {
183
+ return expValEquals('platform_editor_enghealth_a11y_jan_fixes', 'isEnabled', true) ? deletedContentStyleNewActive : deletedContentStyleActive;
184
+ }
185
+ return expValEquals('platform_editor_enghealth_a11y_jan_fixes', 'isEnabled', true) ? deletedContentStyleNew : deletedContentStyle;
144
186
  };
145
187
  var getNodeClass = function getNodeClass(name) {
146
188
  switch (name) {
@@ -170,7 +212,9 @@ export var createDeletedContentDecoration = function createDeletedContentDecorat
170
212
  nodeViewSerializer = _ref.nodeViewSerializer,
171
213
  colourScheme = _ref.colourScheme,
172
214
  newDoc = _ref.newDoc,
173
- intl = _ref.intl;
215
+ intl = _ref.intl,
216
+ _ref$isActive = _ref.isActive,
217
+ isActive = _ref$isActive === void 0 ? false : _ref$isActive;
174
218
  var slice = doc.slice(change.fromA, change.toA);
175
219
  if (slice.content.content.length === 0) {
176
220
  return;
@@ -206,7 +250,6 @@ export var createDeletedContentDecoration = function createDeletedContentDecorat
206
250
  * and if it's the first or last content, we go in however many the sliced Open
207
251
  * or sliced End depth is and match only the entire node.
208
252
  */
209
-
210
253
  slice.content.forEach(function (node) {
211
254
  // Create a wrapper for each node with strikethrough
212
255
  var createWrapperWithStrikethrough = function createWrapperWithStrikethrough() {
@@ -215,7 +258,7 @@ export var createDeletedContentDecoration = function createDeletedContentDecorat
215
258
  position: 'relative',
216
259
  width: 'fit-content'
217
260
  });
218
- wrapper.setAttribute('style', "".concat(baseStyle).concat(getDeletedContentStyle(colourScheme)));
261
+ wrapper.setAttribute('style', "".concat(baseStyle).concat(getDeletedContentStyle(colourScheme, isActive)));
219
262
  var strikethrough = document.createElement('span');
220
263
  strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colourScheme));
221
264
  wrapper.append(strikethrough);
@@ -306,7 +349,7 @@ export var createDeletedContentDecoration = function createDeletedContentDecorat
306
349
  } else {
307
350
  var fallbackNode = fallbackSerialization();
308
351
  if (fallbackNode) {
309
- var _wrapper2 = createDeletedStyleWrapperWithoutOpacity(colourScheme);
352
+ var _wrapper2 = createDeletedStyleWrapperWithoutOpacity(colourScheme, isActive);
310
353
  _wrapper2.append(fallbackNode);
311
354
  dom.append(_wrapper2);
312
355
  }
@@ -156,9 +156,9 @@ export var createBlockNodeWrapper = function createBlockNodeWrapper() {
156
156
  /**
157
157
  * Wraps content with deleted styling without opacity (for use when content is a direct child of dom)
158
158
  */
159
- export var createDeletedStyleWrapperWithoutOpacity = function createDeletedStyleWrapperWithoutOpacity(colourScheme) {
159
+ export var createDeletedStyleWrapperWithoutOpacity = function createDeletedStyleWrapperWithoutOpacity(colourScheme, isActive) {
160
160
  var wrapper = document.createElement('span');
161
- wrapper.setAttribute('style', getDeletedContentStyle(colourScheme));
161
+ wrapper.setAttribute('style', getDeletedContentStyle(colourScheme, isActive));
162
162
  return wrapper;
163
163
  };
164
164
 
@@ -3,9 +3,10 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
3
3
  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) { _defineProperty(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; }
4
4
  import { processRawValue } from '@atlaskit/editor-common/process-raw-value';
5
5
  import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
6
- import { PluginKey } from '@atlaskit/editor-prosemirror/state';
6
+ import { PluginKey, NodeSelection, TextSelection } from '@atlaskit/editor-prosemirror/state';
7
7
  import { Step as ProseMirrorStep } from '@atlaskit/editor-prosemirror/transform';
8
8
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
9
+ import { fg } from '@atlaskit/platform-feature-flags';
9
10
  import { calculateDiffDecorations } from './calculateDiffDecorations';
10
11
  import { NodeViewSerializer } from './NodeViewSerializer';
11
12
  export var showDiffPluginKey = new PluginKey('showDiffPlugin');
@@ -18,6 +19,40 @@ export var createPlugin = function createPlugin(config, getIntl) {
18
19
  };
19
20
  return new SafePlugin({
20
21
  key: showDiffPluginKey,
22
+ appendTransaction: function appendTransaction(transactions, oldState, newState) {
23
+ var _pluginState$activeIn;
24
+ if (!fg('platform_editor_show_diff_scroll_navigation')) {
25
+ return;
26
+ }
27
+ // Check if any transaction contains scroll actions
28
+ var scrollTransaction = transactions.find(function (tr) {
29
+ var _tr$getMeta, _tr$getMeta2;
30
+ return ((_tr$getMeta = tr.getMeta(showDiffPluginKey)) === null || _tr$getMeta === void 0 ? void 0 : _tr$getMeta.action) === 'SCROLL_TO_NEXT' || ((_tr$getMeta2 = tr.getMeta(showDiffPluginKey)) === null || _tr$getMeta2 === void 0 ? void 0 : _tr$getMeta2.action) === 'SCROLL_TO_PREVIOUS';
31
+ });
32
+ if (!scrollTransaction) {
33
+ return;
34
+ }
35
+ var pluginState = showDiffPluginKey.getState(newState);
36
+ if (!pluginState || pluginState.decorations.find().length === 0) {
37
+ return;
38
+ }
39
+ var decorations = pluginState.decorations.find();
40
+ var decoration = decorations[(_pluginState$activeIn = pluginState.activeIndex) !== null && _pluginState$activeIn !== void 0 ? _pluginState$activeIn : 0];
41
+ if (!decoration) {
42
+ return;
43
+ }
44
+ var from = decoration.from,
45
+ to = decoration.to;
46
+ var $pos = newState.doc.resolve(from);
47
+ var isNodeSelection = $pos.nodeAfter && $pos.nodeAfter.nodeSize === to - from && !$pos.nodeAfter.isInline;
48
+ var tr = newState.tr;
49
+ if (isNodeSelection) {
50
+ tr.setSelection(NodeSelection.create(newState.doc, from));
51
+ } else {
52
+ tr.setSelection(TextSelection.create(newState.doc, from));
53
+ }
54
+ return tr.scrollIntoView();
55
+ },
21
56
  state: {
22
57
  init: function init(_, _state) {
23
58
  // We do initial setup after we setup the editor view
@@ -35,7 +70,8 @@ export var createPlugin = function createPlugin(config, getIntl) {
35
70
  if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'SHOW_DIFF') {
36
71
  // Update the plugin state with the new metadata
37
72
  newPluginState = _objectSpread(_objectSpread(_objectSpread({}, currentPluginState), meta), {}, {
38
- isDisplayingChanges: true
73
+ isDisplayingChanges: true,
74
+ activeIndex: 0
39
75
  });
40
76
  // Calculate and store decorations in state
41
77
  var decorations = calculateDiffDecorations({
@@ -43,15 +79,47 @@ export var createPlugin = function createPlugin(config, getIntl) {
43
79
  pluginState: newPluginState,
44
80
  nodeViewSerializer: nodeViewSerializer,
45
81
  colourScheme: config === null || config === void 0 ? void 0 : config.colourScheme,
46
- intl: getIntl()
82
+ intl: getIntl(),
83
+ activeIndexPos: fg('platform_editor_show_diff_scroll_navigation') ? newPluginState.activeIndexPos : undefined
47
84
  });
48
85
  // Update the decorations
49
86
  newPluginState.decorations = decorations;
50
87
  } else if ((meta === null || meta === void 0 ? void 0 : meta.action) === 'HIDE_DIFF') {
51
88
  newPluginState = _objectSpread(_objectSpread(_objectSpread({}, currentPluginState), meta), {}, {
52
89
  decorations: DecorationSet.empty,
53
- isDisplayingChanges: false
90
+ isDisplayingChanges: false,
91
+ activeIndex: undefined
54
92
  });
93
+ } else if (((meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_NEXT' || (meta === null || meta === void 0 ? void 0 : meta.action) === 'SCROLL_TO_PREVIOUS') && fg('platform_editor_show_diff_scroll_navigation')) {
94
+ // Update the active index in plugin state and recalculate decorations
95
+ var _decorations = currentPluginState.decorations.find();
96
+ if (_decorations.length > 0) {
97
+ var _currentPluginState$a;
98
+ var nextIndex = (_currentPluginState$a = currentPluginState.activeIndex) !== null && _currentPluginState$a !== void 0 ? _currentPluginState$a : 0;
99
+ if (meta.action === 'SCROLL_TO_NEXT') {
100
+ nextIndex = (nextIndex + 1) % _decorations.length;
101
+ } else {
102
+ nextIndex = (nextIndex - 1 + _decorations.length) % _decorations.length;
103
+ }
104
+ var activeDecoration = _decorations[nextIndex];
105
+ newPluginState = _objectSpread(_objectSpread({}, currentPluginState), {}, {
106
+ activeIndex: nextIndex,
107
+ activeIndexPos: activeDecoration ? {
108
+ from: activeDecoration.from,
109
+ to: activeDecoration.to
110
+ } : undefined
111
+ });
112
+ // Recalculate decorations with the new active index
113
+ var updatedDecorations = calculateDiffDecorations({
114
+ state: newState,
115
+ pluginState: newPluginState,
116
+ nodeViewSerializer: nodeViewSerializer,
117
+ colourScheme: config === null || config === void 0 ? void 0 : config.colourScheme,
118
+ intl: getIntl(),
119
+ activeIndexPos: newPluginState.activeIndexPos
120
+ });
121
+ newPluginState.decorations = updatedDecorations;
122
+ }
55
123
  } else {
56
124
  newPluginState = _objectSpread(_objectSpread({}, currentPluginState), meta);
57
125
  }
@@ -22,13 +22,25 @@ export var showDiffPlugin = function showDiffPlugin(_ref) {
22
22
  steps: [],
23
23
  action: 'HIDE_DIFF'
24
24
  });
25
+ },
26
+ scrollToNext: function scrollToNext(_ref4) {
27
+ var tr = _ref4.tr;
28
+ return tr.setMeta(showDiffPluginKey, {
29
+ action: 'SCROLL_TO_NEXT'
30
+ });
31
+ },
32
+ scrollToPrevious: function scrollToPrevious(_ref5) {
33
+ var tr = _ref5.tr;
34
+ return tr.setMeta(showDiffPluginKey, {
35
+ action: 'SCROLL_TO_PREVIOUS'
36
+ });
25
37
  }
26
38
  },
27
39
  pmPlugins: function pmPlugins() {
28
40
  return [{
29
41
  name: 'showDiffPlugin',
30
- plugin: function plugin(_ref4) {
31
- var getIntl = _ref4.getIntl;
42
+ plugin: function plugin(_ref6) {
43
+ var getIntl = _ref6.getIntl;
32
44
  return createPlugin(config, getIntl);
33
45
  }
34
46
  }];
@@ -37,13 +49,16 @@ export var showDiffPlugin = function showDiffPlugin(_ref) {
37
49
  var _pluginState$decorati;
38
50
  if (!editorState) {
39
51
  return {
40
- isDisplayingChanges: false
52
+ isDisplayingChanges: false,
53
+ activeIndex: undefined
41
54
  };
42
55
  }
43
56
  var pluginState = showDiffPluginKey.getState(editorState);
44
57
  var decorationCount = (pluginState === null || pluginState === void 0 || (_pluginState$decorati = pluginState.decorations) === null || _pluginState$decorati === void 0 ? void 0 : _pluginState$decorati.find()) || [];
45
58
  return {
46
- isDisplayingChanges: decorationCount.length > 0
59
+ isDisplayingChanges: decorationCount.length > 0,
60
+ activeIndex: pluginState === null || pluginState === void 0 ? void 0 : pluginState.activeIndex,
61
+ numberOfChanges: decorationCount.length
47
62
  };
48
63
  }
49
64
  };
@@ -3,7 +3,11 @@ import { type EditorState } from '@atlaskit/editor-prosemirror/state';
3
3
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
4
  import type { ShowDiffPluginState } from './main';
5
5
  import type { NodeViewSerializer } from './NodeViewSerializer';
6
- export declare const calculateDiffDecorations: import("memoize-one").MemoizedFn<({ state, pluginState, nodeViewSerializer, colourScheme, intl, }: {
6
+ export declare const calculateDiffDecorations: import("memoize-one").MemoizedFn<({ state, pluginState, nodeViewSerializer, colourScheme, intl, activeIndexPos, }: {
7
+ activeIndexPos?: {
8
+ from: number;
9
+ to: number;
10
+ };
7
11
  colourScheme?: "standard" | "traditional";
8
12
  intl: IntlShape;
9
13
  nodeViewSerializer: NodeViewSerializer;
@@ -12,9 +12,9 @@ import type { NodeViewSerializer } from './NodeViewSerializer';
12
12
  export declare const createInlineChangedDecoration: (change: {
13
13
  fromB: number;
14
14
  toB: number;
15
- }, colourScheme?: "standard" | "traditional") => Decoration;
15
+ }, colourScheme?: "standard" | "traditional", isActive?: boolean) => Decoration;
16
16
  export declare const getDeletedContentStyleUnbounded: (colourScheme?: "standard" | "traditional") => string;
17
- export declare const getDeletedContentStyle: (colourScheme?: "standard" | "traditional") => string;
17
+ export declare const getDeletedContentStyle: (colourScheme?: "standard" | "traditional", isActive?: boolean) => string;
18
18
  /**
19
19
  * Inline decoration used for insertions as the content already exists in the document
20
20
  *
@@ -31,8 +31,9 @@ interface DeletedContentDecorationProps {
31
31
  colourScheme?: 'standard' | 'traditional';
32
32
  doc: PMNode;
33
33
  intl: IntlShape;
34
+ isActive?: boolean;
34
35
  newDoc: PMNode;
35
36
  nodeViewSerializer: NodeViewSerializer;
36
37
  }
37
- export declare const createDeletedContentDecoration: ({ change, doc, nodeViewSerializer, colourScheme, newDoc, intl, }: DeletedContentDecorationProps) => Decoration[] | undefined;
38
+ export declare const createDeletedContentDecoration: ({ change, doc, nodeViewSerializer, colourScheme, newDoc, intl, isActive, }: DeletedContentDecorationProps) => Decoration[] | undefined;
38
39
  export {};
@@ -26,7 +26,7 @@ export declare const createBlockNodeWrapper: () => HTMLDivElement;
26
26
  /**
27
27
  * Wraps content with deleted styling without opacity (for use when content is a direct child of dom)
28
28
  */
29
- export declare const createDeletedStyleWrapperWithoutOpacity: (colourScheme?: "standard" | "traditional") => HTMLSpanElement;
29
+ export declare const createDeletedStyleWrapperWithoutOpacity: (colourScheme?: "standard" | "traditional", isActive?: boolean) => HTMLSpanElement;
30
30
  /**
31
31
  * Applies deleted styles directly to an HTML element by merging with existing styles
32
32
  */
@@ -7,6 +7,11 @@ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
7
7
  import { type DiffParams } from '../showDiffPluginType';
8
8
  export declare const showDiffPluginKey: PluginKey<ShowDiffPluginState>;
9
9
  export type ShowDiffPluginState = {
10
+ activeIndex?: number;
11
+ activeIndexPos?: {
12
+ from: number;
13
+ to: number;
14
+ };
10
15
  decorations: DecorationSet;
11
16
  isDisplayingChanges: boolean;
12
17
  originalDoc: PMNode | undefined;
@@ -23,18 +23,28 @@ export type PMDiffParams = {
23
23
  */
24
24
  steps: Step[];
25
25
  };
26
- export type ACTION = 'SHOW_DIFF' | 'HIDE_DIFF';
26
+ export type ACTION = 'SHOW_DIFF' | 'HIDE_DIFF' | 'SCROLL_TO_NEXT' | 'SCROLL_TO_PREVIOUS';
27
27
  export type ShowDiffPlugin = NextEditorPlugin<'showDiff', {
28
28
  commands: {
29
29
  hideDiff: EditorCommand;
30
+ scrollToNext: EditorCommand;
31
+ scrollToPrevious: EditorCommand;
30
32
  showDiff: (config: PMDiffParams) => EditorCommand;
31
33
  };
32
34
  pluginConfiguration: DiffParams | undefined;
33
35
  sharedState: {
36
+ /**
37
+ * The index of the current diff being viewed.
38
+ */
39
+ activeIndex?: number;
34
40
  /**
35
41
  * Whether the show diff feature is currently displaying changes.
36
42
  * Defaults to false.
37
43
  */
38
44
  isDisplayingChanges: boolean;
45
+ /**
46
+ * The number of changes being displayed
47
+ */
48
+ numberOfChanges?: number;
39
49
  };
40
50
  }>;
@@ -3,7 +3,11 @@ import { type EditorState } from '@atlaskit/editor-prosemirror/state';
3
3
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
4
4
  import type { ShowDiffPluginState } from './main';
5
5
  import type { NodeViewSerializer } from './NodeViewSerializer';
6
- export declare const calculateDiffDecorations: import("memoize-one").MemoizedFn<({ state, pluginState, nodeViewSerializer, colourScheme, intl, }: {
6
+ export declare const calculateDiffDecorations: import("memoize-one").MemoizedFn<({ state, pluginState, nodeViewSerializer, colourScheme, intl, activeIndexPos, }: {
7
+ activeIndexPos?: {
8
+ from: number;
9
+ to: number;
10
+ };
7
11
  colourScheme?: "standard" | "traditional";
8
12
  intl: IntlShape;
9
13
  nodeViewSerializer: NodeViewSerializer;
@@ -12,9 +12,9 @@ import type { NodeViewSerializer } from './NodeViewSerializer';
12
12
  export declare const createInlineChangedDecoration: (change: {
13
13
  fromB: number;
14
14
  toB: number;
15
- }, colourScheme?: "standard" | "traditional") => Decoration;
15
+ }, colourScheme?: "standard" | "traditional", isActive?: boolean) => Decoration;
16
16
  export declare const getDeletedContentStyleUnbounded: (colourScheme?: "standard" | "traditional") => string;
17
- export declare const getDeletedContentStyle: (colourScheme?: "standard" | "traditional") => string;
17
+ export declare const getDeletedContentStyle: (colourScheme?: "standard" | "traditional", isActive?: boolean) => string;
18
18
  /**
19
19
  * Inline decoration used for insertions as the content already exists in the document
20
20
  *
@@ -31,8 +31,9 @@ interface DeletedContentDecorationProps {
31
31
  colourScheme?: 'standard' | 'traditional';
32
32
  doc: PMNode;
33
33
  intl: IntlShape;
34
+ isActive?: boolean;
34
35
  newDoc: PMNode;
35
36
  nodeViewSerializer: NodeViewSerializer;
36
37
  }
37
- export declare const createDeletedContentDecoration: ({ change, doc, nodeViewSerializer, colourScheme, newDoc, intl, }: DeletedContentDecorationProps) => Decoration[] | undefined;
38
+ export declare const createDeletedContentDecoration: ({ change, doc, nodeViewSerializer, colourScheme, newDoc, intl, isActive, }: DeletedContentDecorationProps) => Decoration[] | undefined;
38
39
  export {};
@@ -26,7 +26,7 @@ export declare const createBlockNodeWrapper: () => HTMLDivElement;
26
26
  /**
27
27
  * Wraps content with deleted styling without opacity (for use when content is a direct child of dom)
28
28
  */
29
- export declare const createDeletedStyleWrapperWithoutOpacity: (colourScheme?: "standard" | "traditional") => HTMLSpanElement;
29
+ export declare const createDeletedStyleWrapperWithoutOpacity: (colourScheme?: "standard" | "traditional", isActive?: boolean) => HTMLSpanElement;
30
30
  /**
31
31
  * Applies deleted styles directly to an HTML element by merging with existing styles
32
32
  */