@atlaskit/editor-plugin-show-diff 10.1.23 → 10.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +132 -31
  3. package/dist/cjs/pm-plugins/calculateDiff/groupChangesByBlock.js +4 -2
  4. package/dist/cjs/pm-plugins/calculateDiff/smart/classifySmartChanges.js +841 -0
  5. package/dist/cjs/pm-plugins/calculateDiff/smart/helpers.js +135 -0
  6. package/dist/cjs/pm-plugins/calculateDiff/smart/segmentText.js +331 -0
  7. package/dist/cjs/pm-plugins/calculateDiff/smart/thresholds.js +46 -0
  8. package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +24 -18
  9. package/dist/cjs/pm-plugins/decorations/createChangedRowDecorationWidgets.js +18 -12
  10. package/dist/cjs/pm-plugins/decorations/createInlineChangedDecoration.js +6 -5
  11. package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +30 -17
  12. package/dist/cjs/pm-plugins/decorations/decorationKeys.js +8 -5
  13. package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +52 -30
  14. package/dist/cjs/pm-plugins/getScrollableDecorations.js +6 -6
  15. package/dist/cjs/pm-plugins/isExtendedEnabled.js +20 -0
  16. package/dist/cjs/pm-plugins/main.js +21 -16
  17. package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +119 -29
  18. package/dist/es2019/pm-plugins/calculateDiff/groupChangesByBlock.js +4 -3
  19. package/dist/es2019/pm-plugins/calculateDiff/smart/classifySmartChanges.js +689 -0
  20. package/dist/es2019/pm-plugins/calculateDiff/smart/helpers.js +106 -0
  21. package/dist/es2019/pm-plugins/calculateDiff/smart/segmentText.js +283 -0
  22. package/dist/es2019/pm-plugins/calculateDiff/smart/thresholds.js +45 -0
  23. package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +24 -18
  24. package/dist/es2019/pm-plugins/decorations/createChangedRowDecorationWidgets.js +18 -12
  25. package/dist/es2019/pm-plugins/decorations/createInlineChangedDecoration.js +6 -5
  26. package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +31 -16
  27. package/dist/es2019/pm-plugins/decorations/decorationKeys.js +9 -5
  28. package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +52 -34
  29. package/dist/es2019/pm-plugins/getScrollableDecorations.js +6 -6
  30. package/dist/es2019/pm-plugins/isExtendedEnabled.js +12 -0
  31. package/dist/es2019/pm-plugins/main.js +21 -16
  32. package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +132 -31
  33. package/dist/esm/pm-plugins/calculateDiff/groupChangesByBlock.js +4 -3
  34. package/dist/esm/pm-plugins/calculateDiff/smart/classifySmartChanges.js +834 -0
  35. package/dist/esm/pm-plugins/calculateDiff/smart/helpers.js +128 -0
  36. package/dist/esm/pm-plugins/calculateDiff/smart/segmentText.js +325 -0
  37. package/dist/esm/pm-plugins/calculateDiff/smart/thresholds.js +39 -0
  38. package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +24 -18
  39. package/dist/esm/pm-plugins/decorations/createChangedRowDecorationWidgets.js +18 -12
  40. package/dist/esm/pm-plugins/decorations/createInlineChangedDecoration.js +6 -5
  41. package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +30 -17
  42. package/dist/esm/pm-plugins/decorations/decorationKeys.js +9 -5
  43. package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +52 -30
  44. package/dist/esm/pm-plugins/getScrollableDecorations.js +6 -6
  45. package/dist/esm/pm-plugins/isExtendedEnabled.js +14 -0
  46. package/dist/esm/pm-plugins/main.js +21 -16
  47. package/dist/types/entry-points/show-diff-plugin-type.d.ts +1 -1
  48. package/dist/types/pm-plugins/calculateDiff/calculateDiffDecorations.d.ts +3 -1
  49. package/dist/types/pm-plugins/calculateDiff/groupChangesByBlock.d.ts +9 -0
  50. package/dist/types/pm-plugins/calculateDiff/smart/classifySmartChanges.d.ts +26 -0
  51. package/dist/types/pm-plugins/calculateDiff/smart/helpers.d.ts +44 -0
  52. package/dist/types/pm-plugins/calculateDiff/smart/segmentText.d.ts +32 -0
  53. package/dist/types/pm-plugins/calculateDiff/smart/thresholds.d.ts +44 -0
  54. package/dist/types/pm-plugins/decorations/createBlockChangedDecoration.d.ts +3 -2
  55. package/dist/types/pm-plugins/decorations/createChangedRowDecorationWidgets.d.ts +3 -2
  56. package/dist/types/pm-plugins/decorations/createInlineChangedDecoration.d.ts +3 -2
  57. package/dist/types/pm-plugins/decorations/createNodeChangedDecorationWidget.d.ts +4 -2
  58. package/dist/types/pm-plugins/decorations/decorationKeys.d.ts +5 -3
  59. package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeView.d.ts +6 -4
  60. package/dist/types/pm-plugins/getScrollableDecorations.d.ts +2 -1
  61. package/dist/types/pm-plugins/isExtendedEnabled.d.ts +11 -0
  62. package/dist/types/pm-plugins/main.d.ts +11 -1
  63. package/dist/types/showDiffPluginType.d.ts +20 -1
  64. package/docs/smart-diff-design.md +240 -0
  65. package/package.json +7 -2
@@ -1,5 +1,5 @@
1
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
4
4
  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; }
5
5
  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; }
@@ -12,6 +12,7 @@ import memoizeOne from 'memoize-one';
12
12
  import { ChangeSet, simplifyChanges } from 'prosemirror-changeset';
13
13
  import { areNodesEqualIgnoreAttrs } from '@atlaskit/editor-common/utils/document';
14
14
  import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
15
+ import { fg } from '@atlaskit/platform-feature-flags';
15
16
  import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
16
17
  import { areDocsEqualByBlockStructureAndText } from '../areDocsEqualByBlockStructureAndText';
17
18
  import { createDocMarginAnchorWidget } from '../decorations/createAnchorDecorationWidgets';
@@ -22,30 +23,71 @@ import { createNodeChangedDecorationWidget } from '../decorations/createNodeChan
22
23
  import { extractDiffDescriptors } from '../decorations/decorationKeys';
23
24
  import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
24
25
  import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
26
+ import { isExtendedEnabled } from '../isExtendedEnabled';
25
27
  import { diffBySteps, getStepChanges } from './diffBySteps';
26
28
  import { groupChangesByBlock } from './groupChangesByBlock';
27
29
  import { optimizeChanges } from './optimizeChanges';
28
30
  import { simplifySteps } from './simplifySteps';
31
+ import { classifySmartChanges } from './smart/classifySmartChanges';
32
+ import { smartChangeLevel } from './smart/helpers';
29
33
  var getChanges = function getChanges(_ref) {
30
34
  var changeset = _ref.changeset,
31
35
  originalDoc = _ref.originalDoc,
32
36
  steppedDoc = _ref.steppedDoc,
33
37
  diffType = _ref.diffType,
34
38
  tr = _ref.tr,
35
- steps = _ref.steps;
36
- if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
39
+ steps = _ref.steps,
40
+ intl = _ref.intl,
41
+ smartThresholds = _ref.smartThresholds;
42
+ if (isExtendedEnabled(diffType)) {
43
+ // The `smart` diff type is gated behind `platform_editor_ai_smart_diff`. When the gate is
44
+ // off, `smart` falls through to the default (`inline`) path below so behaviour degrades
45
+ // gracefully (see docs/smart-diff-design.md §3).
46
+ if (diffType === 'smart' && fg('platform_editor_ai_smart_diff')) {
47
+ var _changes = simplifyChanges(changeset.changes, tr.doc);
48
+ return classifySmartChanges({
49
+ changes: _changes,
50
+ originalDoc: originalDoc,
51
+ newDoc: tr.doc,
52
+ locale: intl.locale,
53
+ thresholds: smartThresholds
54
+ });
55
+ }
37
56
  if (diffType === 'step') {
38
57
  return diffBySteps(originalDoc, steps);
39
58
  }
40
59
  if (diffType === 'block') {
41
60
  return groupChangesByBlock(changeset.changes, originalDoc, steppedDoc);
42
61
  }
43
- var _changes = simplifyChanges(changeset.changes, tr.doc);
44
- return optimizeChanges(_changes);
62
+ var _changes2 = simplifyChanges(changeset.changes, tr.doc);
63
+ return optimizeChanges(_changes2);
45
64
  }
46
65
  var changes = simplifyChanges(changeset.changes, tr.doc);
47
66
  return optimizeChanges(changes);
48
67
  };
68
+
69
+ /**
70
+ * Collect the inline-content ranges of every leaf text-bearing block (paragraph, heading, …)
71
+ * whose content overlaps `[from, to)`. Used to clip a node-level `smart` insertion highlight to
72
+ * the actual added text, so the inserted background/underline never spans structural gaps
73
+ * (list markers, empty item slots, cell/column boundaries) which would render as phantom rows.
74
+ */
75
+ var leafTextblockRanges = function leafTextblockRanges(doc, from, to) {
76
+ var ranges = [];
77
+ doc.nodesBetween(from, to, function (node, pos) {
78
+ if (node.isTextblock && node.content.size > 0) {
79
+ var contentFrom = Math.max(pos + 1, from);
80
+ var contentTo = Math.min(pos + 1 + node.content.size, to);
81
+ if (contentTo > contentFrom) {
82
+ ranges.push([contentFrom, contentTo]);
83
+ }
84
+ // Textblocks have no block children to descend into.
85
+ return false;
86
+ }
87
+ return true;
88
+ });
89
+ return ranges;
90
+ };
49
91
  var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration(_ref2) {
50
92
  var doc = _ref2.doc,
51
93
  from = _ref2.from,
@@ -57,11 +99,12 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
57
99
  _ref2$shouldHideDelet = _ref2.shouldHideDeleted,
58
100
  shouldHideDeleted = _ref2$shouldHideDelet === void 0 ? false : _ref2$shouldHideDelet,
59
101
  _ref2$showIndicators = _ref2.showIndicators,
60
- showIndicators = _ref2$showIndicators === void 0 ? false : _ref2$showIndicators;
102
+ showIndicators = _ref2$showIndicators === void 0 ? false : _ref2$showIndicators,
103
+ diffType = _ref2.diffType;
61
104
  var decorations = [];
62
105
  // Iterate over the document nodes within the range
63
106
  doc.nodesBetween(from, to, function (node, pos) {
64
- if (node.isBlock && (!expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) || pos + node.nodeSize <= to)) {
107
+ if (node.isBlock && (!isExtendedEnabled(diffType) || pos + node.nodeSize <= to)) {
65
108
  var nodeEnd = pos + node.nodeSize;
66
109
  var isActive = activeIndexPos && pos === activeIndexPos.from && nodeEnd === activeIndexPos.to;
67
110
  decorations.push.apply(decorations, _toConsumableArray(createBlockChangedDecoration({
@@ -75,7 +118,8 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
75
118
  isActive: isActive,
76
119
  shouldHideDeleted: shouldHideDeleted,
77
120
  showIndicators: showIndicators,
78
- doc: doc
121
+ doc: doc,
122
+ diffType: diffType
79
123
  })));
80
124
  }
81
125
  });
@@ -96,7 +140,10 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
96
140
  _ref3$hideDeletedDiff = _ref3.hideDeletedDiffs,
97
141
  hideDeletedDiffs = _ref3$hideDeletedDiff === void 0 ? false : _ref3$hideDeletedDiff,
98
142
  _ref3$showIndicators = _ref3.showIndicators,
99
- showIndicators = _ref3$showIndicators === void 0 ? false : _ref3$showIndicators;
143
+ showIndicators = _ref3$showIndicators === void 0 ? false : _ref3$showIndicators,
144
+ smartThresholds = _ref3.smartThresholds,
145
+ _ref3$deletedDiffPlac = _ref3.deletedDiffPlacement,
146
+ deletedDiffPlacement = _ref3$deletedDiffPlac === void 0 ? 'top' : _ref3$deletedDiffPlac;
100
147
  var originalDoc = pluginState.originalDoc,
101
148
  steps = pluginState.steps,
102
149
  isDisplayingChanges = pluginState.isDisplayingChanges;
@@ -160,14 +207,16 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
160
207
  steppedDoc: steppedDoc,
161
208
  diffType: diffType,
162
209
  tr: tr,
163
- steps: steps
210
+ steps: steps,
211
+ intl: intl,
212
+ smartThresholds: smartThresholds
164
213
  });
165
214
  var decorations = [];
166
215
 
167
216
  /**
168
217
  * If showIndicators is on, we create an anchor widget here to mark the doc margin.
169
218
  */
170
- if (showIndicators && expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
219
+ if (showIndicators && isExtendedEnabled(diffType)) {
171
220
  decorations.push(createDocMarginAnchorWidget());
172
221
  }
173
222
 
@@ -179,33 +228,77 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
179
228
  // shouldHideDeleted for block/node decorations: suppressed when isInverted + hideDeletedDiffs,
180
229
  // or when showGranularWithBlock (block reference widget is shown instead).
181
230
  // isInverted gates both — on an inverted diff the inserted side is visually the deleted side.
182
- var shouldHideDeleted = expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? isInverted && (hideDeletedDiffs || showGranularWithBlock) && change.deleted.length > 0 : false;
183
- decorations.push.apply(decorations, _toConsumableArray(createInlineChangedDecoration(_objectSpread({
184
- change: change,
185
- doc: tr.doc,
186
- colorScheme: colorScheme,
187
- isActive: isActive
188
- }, expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) && {
189
- isInserted: isInserted,
190
- shouldHideDeleted: shouldHideDeleted,
191
- showIndicators: showIndicators
192
- }))));
231
+ var shouldHideDeleted = isExtendedEnabled(diffType) ? isInverted && (hideDeletedDiffs || showGranularWithBlock) && change.deleted.length > 0 : false;
232
+
233
+ // For `smart` NODE-level promotions the change range spans a whole container
234
+ // (e.g. an entire list/table/layout, using outer node bounds). Applying a SINGLE
235
+ // inline decoration across that whole range would paint the inserted style across
236
+ // block boundaries and structural gaps (list markers, empty item slots), producing
237
+ // phantom "empty" rows above the real content. But skipping the inline highlight
238
+ // entirely leaves added text-bearing blocks (paragraphs/headings inside the added
239
+ // container) without the inserted background+underline, because block decorations
240
+ // return no style for paragraph/heading. So for node-level smart changes we instead
241
+ // emit ONE inline decoration per leaf text-bearing block within the range — the text
242
+ // gets highlighted, and structural gaps never do.
243
+ var isSmartNodeLevel = diffType === 'smart' && fg('platform_editor_ai_smart_diff') && smartChangeLevel(change) === 'node';
244
+ if (isSmartNodeLevel) {
245
+ var _iterator2 = _createForOfIteratorHelper(leafTextblockRanges(tr.doc, change.fromB, change.toB)),
246
+ _step2;
247
+ try {
248
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
249
+ var _step2$value = _slicedToArray(_step2.value, 2),
250
+ from = _step2$value[0],
251
+ to = _step2$value[1];
252
+ decorations.push.apply(decorations, _toConsumableArray(createInlineChangedDecoration(_objectSpread({
253
+ change: {
254
+ fromB: from,
255
+ toB: to
256
+ },
257
+ doc: tr.doc,
258
+ colorScheme: colorScheme,
259
+ isActive: isActive,
260
+ diffType: diffType
261
+ }, isExtendedEnabled(diffType) && {
262
+ isInserted: isInserted,
263
+ shouldHideDeleted: shouldHideDeleted,
264
+ showIndicators: showIndicators
265
+ }))));
266
+ }
267
+ } catch (err) {
268
+ _iterator2.e(err);
269
+ } finally {
270
+ _iterator2.f();
271
+ }
272
+ } else {
273
+ decorations.push.apply(decorations, _toConsumableArray(createInlineChangedDecoration(_objectSpread({
274
+ change: change,
275
+ doc: tr.doc,
276
+ colorScheme: colorScheme,
277
+ isActive: isActive,
278
+ diffType: diffType
279
+ }, isExtendedEnabled(diffType) && {
280
+ isInserted: isInserted,
281
+ shouldHideDeleted: shouldHideDeleted,
282
+ showIndicators: showIndicators
283
+ }))));
284
+ }
193
285
  decorations.push.apply(decorations, _toConsumableArray(calculateNodesForBlockDecoration(_objectSpread(_objectSpread({
194
286
  doc: tr.doc,
195
287
  from: change.fromB,
196
288
  to: change.toB,
197
289
  colorScheme: colorScheme
198
- }, expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) && {
290
+ }, isExtendedEnabled(diffType) && {
199
291
  isInserted: isInserted,
200
292
  shouldHideDeleted: shouldHideDeleted,
201
293
  showIndicators: showIndicators
202
294
  }), {}, {
203
295
  activeIndexPos: activeIndexPos,
204
- intl: intl
296
+ intl: intl,
297
+ diffType: diffType
205
298
  }))));
206
299
  }
207
300
  if (change.deleted.length > 0) {
208
- var _shouldHideDeleted = expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? !isInverted && (hideDeletedDiffs || showGranularWithBlock) && change.inserted.length > 0 : false;
301
+ var _shouldHideDeleted = isExtendedEnabled(diffType) ? !isInverted && (hideDeletedDiffs || showGranularWithBlock) && change.inserted.length > 0 : false;
209
302
  if (!_shouldHideDeleted) {
210
303
  decorations.push.apply(decorations, _toConsumableArray(createNodeChangedDecorationWidget(_objectSpread(_objectSpread({
211
304
  change: change,
@@ -215,9 +308,13 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
215
308
  newDoc: tr.doc,
216
309
  intl: intl,
217
310
  activeIndexPos: activeIndexPos
218
- }, expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) && {
311
+ }, isExtendedEnabled(diffType) && {
219
312
  isInserted: !isInserted,
220
- diffType: diffType
313
+ diffType: diffType,
314
+ // For `smart` node- and paragraph-level changes, optionally render the
315
+ // deleted content below the new content (gray + strikethrough) instead
316
+ // of above it. Controlled by `deletedDiffPlacement` (default `'top'`).
317
+ placeBelow: deletedDiffPlacement === 'bottom' && diffType === 'smart' && fg('platform_editor_ai_smart_diff') && (smartChangeLevel(change) === 'node' || smartChangeLevel(change) === 'paragraph')
221
318
  }), {}, {
222
319
  showIndicators: showIndicators
223
320
  }))));
@@ -358,7 +455,9 @@ function (_ref5, _ref6) {
358
455
  isInverted = _ref7$.isInverted,
359
456
  diffType = _ref7$.diffType,
360
457
  hideDeletedDiffs = _ref7$.hideDeletedDiffs,
361
- showIndicators = _ref7$.showIndicators;
458
+ showIndicators = _ref7$.showIndicators,
459
+ smartThresholds = _ref7$.smartThresholds,
460
+ deletedDiffPlacement = _ref7$.deletedDiffPlacement;
362
461
  var _ref8 = _slicedToArray(_ref6, 1),
363
462
  _ref8$ = _ref8[0],
364
463
  lastPluginState = _ref8$.pluginState,
@@ -369,11 +468,13 @@ function (_ref5, _ref6) {
369
468
  lastIsInverted = _ref8$.isInverted,
370
469
  lastDiffType = _ref8$.diffType,
371
470
  lastHideDeletedDiffs = _ref8$.hideDeletedDiffs,
372
- lastShowIndicators = _ref8$.showIndicators;
471
+ lastShowIndicators = _ref8$.showIndicators,
472
+ lastSmartThresholds = _ref8$.smartThresholds,
473
+ lastDeletedDiffPlacement = _ref8$.deletedDiffPlacement;
373
474
  var originalDocIsSame = lastPluginState.originalDoc && pluginState.originalDoc && pluginState.originalDoc.eq(lastPluginState.originalDoc);
374
- if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
475
+ if (isExtendedEnabled(diffType)) {
375
476
  var _ref9;
376
- return (_ref9 = colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isInverted === lastIsInverted && diffType === lastDiffType && isEqual(activeIndexPos, lastActiveIndexPos) && originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && hideDeletedDiffs === lastHideDeletedDiffs && showIndicators === lastShowIndicators) !== null && _ref9 !== void 0 ? _ref9 : false;
477
+ return (_ref9 = colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isInverted === lastIsInverted && diffType === lastDiffType && isEqual(activeIndexPos, lastActiveIndexPos) && originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && hideDeletedDiffs === lastHideDeletedDiffs && showIndicators === lastShowIndicators && isEqual(smartThresholds, lastSmartThresholds) && deletedDiffPlacement === lastDeletedDiffPlacement) !== null && _ref9 !== void 0 ? _ref9 : false;
377
478
  }
378
479
  return (_ref0 = originalDocIsSame && isEqual(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isEqual(activeIndexPos, lastActiveIndexPos) && hideDeletedDiffs === lastHideDeletedDiffs) !== null && _ref0 !== void 0 ? _ref0 : false;
379
480
  });
@@ -3,10 +3,11 @@ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol
3
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; } }
4
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; }
5
5
  /**
6
- * Finds the position range of the top-level block (direct child of doc) that contains `pos`.
7
- * Returns null if `pos` is at the doc boundary or outside the doc content.
6
+ * Finds the position range (outer bounds) of the top-level block (direct child of doc) that
7
+ * contains the range [from, to]. Shared with the `smart` diff type so its block grouping is
8
+ * identical to the `block` diff type by construction.
8
9
  */
9
- function getTopLevelBlockAt(doc, from, to) {
10
+ export function getTopLevelBlockAt(doc, from, to) {
10
11
  return {
11
12
  from: doc.resolve(from).before(1),
12
13
  to: doc.resolve(to).after(1)