@atlaskit/editor-plugin-show-diff 10.1.9 → 10.1.11

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 (20) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +118 -31
  3. package/dist/cjs/pm-plugins/calculateDiff/diffBySteps.js +131 -11
  4. package/dist/cjs/pm-plugins/decorations/createGranularBlockReferenceWidget.js +125 -0
  5. package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +17 -103
  6. package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +79 -1
  7. package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +91 -7
  8. package/dist/es2019/pm-plugins/calculateDiff/diffBySteps.js +112 -10
  9. package/dist/es2019/pm-plugins/decorations/createGranularBlockReferenceWidget.js +120 -0
  10. package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +1 -81
  11. package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +74 -2
  12. package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +119 -32
  13. package/dist/esm/pm-plugins/calculateDiff/diffBySteps.js +131 -10
  14. package/dist/esm/pm-plugins/decorations/createGranularBlockReferenceWidget.js +120 -0
  15. package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +13 -98
  16. package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +79 -2
  17. package/dist/types/pm-plugins/calculateDiff/diffBySteps.d.ts +20 -0
  18. package/dist/types/pm-plugins/decorations/createGranularBlockReferenceWidget.d.ts +36 -0
  19. package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeView.d.ts +15 -0
  20. package/package.json +10 -10
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/editor-plugin-show-diff
2
2
 
3
+ ## 10.1.11
4
+
5
+ ### Patch Changes
6
+
7
+ - [`0096393101f67`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0096393101f67) -
8
+ Render inverted granular step diffs as a hybrid (based on threshold): granular changed inline plus
9
+ a 'reference' block crossed out underneath
10
+ - Updated dependencies
11
+
12
+ ## 10.1.10
13
+
14
+ ### Patch Changes
15
+
16
+ - [`346f91cfe1997`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/346f91cfe1997) -
17
+ Clean up prefer static regex violations
18
+ - Updated dependencies
19
+
3
20
  ## 10.1.9
4
21
 
5
22
  ### Patch Changes
@@ -17,6 +17,7 @@ var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
17
17
  var _areDocsEqualByBlockStructureAndText = require("../areDocsEqualByBlockStructureAndText");
18
18
  var _createAnchorDecorationWidgets = require("../decorations/createAnchorDecorationWidgets");
19
19
  var _createBlockChangedDecoration = require("../decorations/createBlockChangedDecoration");
20
+ var _createGranularBlockReferenceWidget = require("../decorations/createGranularBlockReferenceWidget");
20
21
  var _createInlineChangedDecoration = require("../decorations/createInlineChangedDecoration");
21
22
  var _createNodeChangedDecorationWidget = require("../decorations/createNodeChangedDecorationWidget");
22
23
  var _decorationKeys = require("../decorations/decorationKeys");
@@ -171,12 +172,16 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
171
172
  if (showIndicators && (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
172
173
  decorations.push((0, _createAnchorDecorationWidgets.createDocMarginAnchorWidget)());
173
174
  }
174
- changes.forEach(function (change) {
175
+
176
+ // Our default operations are insertions, so it should match the opposite of isInverted.
177
+ var isInserted = !isInverted;
178
+ var createDecorationsForChange = function createDecorationsForChange(change, showGranularWithBlock) {
175
179
  var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
176
- // Our default operations are insertions, so it should match the opposite of isInverted.
177
- var isInserted = !isInverted;
178
180
  if (change.inserted.length > 0) {
179
- var shouldHideDeleted = (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? isInverted && hideDeletedDiffs : false;
181
+ // shouldHideDeleted for block/node decorations: suppressed when isInverted + hideDeletedDiffs,
182
+ // or when showGranularWithBlock (block reference widget is shown instead).
183
+ // isInverted gates both — on an inverted diff the inserted side is visually the deleted side.
184
+ var shouldHideDeleted = (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? isInverted && (hideDeletedDiffs || showGranularWithBlock) && change.deleted.length > 0 : false;
180
185
  decorations.push.apply(decorations, (0, _toConsumableArray2.default)((0, _createInlineChangedDecoration.createInlineChangedDecoration)(_objectSpread({
181
186
  change: change,
182
187
  doc: tr.doc,
@@ -201,7 +206,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
201
206
  }))));
202
207
  }
203
208
  if (change.deleted.length > 0) {
204
- var _shouldHideDeleted = (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? !isInverted && hideDeletedDiffs : false;
209
+ var _shouldHideDeleted = (0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true) ? !isInverted && (hideDeletedDiffs || showGranularWithBlock) && change.inserted.length > 0 : false;
205
210
  if (!_shouldHideDeleted) {
206
211
  decorations.push.apply(decorations, (0, _toConsumableArray2.default)((0, _createNodeChangedDecorationWidget.createNodeChangedDecorationWidget)(_objectSpread(_objectSpread({
207
212
  change: change,
@@ -219,7 +224,89 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
219
224
  }))));
220
225
  }
221
226
  }
222
- });
227
+ };
228
+ if (diffType === 'step' && (0, _expValEquals.expValEquals)('platform_editor_diff_granular_extended', 'isEnabled', true)) {
229
+ // Uses getStepChanges instead of getChanges so that we have per-step granularity metadata.
230
+ // Specifically, we need to know how many granular changes each step produced in order to
231
+ // apply the shouldHideDeleted suppression threshold (> 3 granular changes per step).
232
+ // getChanges returns a flat Change[] with no per-step grouping, making this count impossible
233
+ // to derive after the fact without re-introducing per-change metadata.
234
+ var stepChanges = (0, _diffBySteps.getStepChanges)(originalDoc, steps);
235
+ stepChanges.forEach(function (_ref4) {
236
+ var isGranular = _ref4.isGranular,
237
+ stepChangeList = _ref4.changes;
238
+ var granularCount = isGranular ? stepChangeList.length : 0;
239
+
240
+ // Calculate the average ratio of changed content on both A (original) and B (new)
241
+ // sides of the diff. If 30% or more of the block has changed on average, we show
242
+ // the block reference widget even if the granular change count is below the threshold.
243
+ // Block length is derived from the enclosing text block boundaries rather than the
244
+ // first/last change positions, so unchanged words at the start/end are accounted for.
245
+ var avgChangedRatio = 0;
246
+ if (isGranular && stepChangeList.length > 0) {
247
+ var first = stepChangeList[0];
248
+ var last = stepChangeList[stepChangeList.length - 1];
249
+ var resolvedA = originalDoc.resolve(first.fromA);
250
+ var resolvedB = tr.doc.resolve(first.fromB);
251
+ var blockStartA = first.fromA;
252
+ var blockEndA = last.toA;
253
+ var blockStartB = first.fromB;
254
+ var blockEndB = last.toB;
255
+ for (var depth = resolvedA.depth; depth >= 0; depth--) {
256
+ var node = resolvedA.node(depth);
257
+ if (node.isTextblock) {
258
+ blockStartA = resolvedA.start(depth);
259
+ blockEndA = blockStartA + node.nodeSize - 2; // exclude open/close tokens
260
+ break;
261
+ }
262
+ }
263
+ for (var _depth = resolvedB.depth; _depth >= 0; _depth--) {
264
+ var _node = resolvedB.node(_depth);
265
+ if (_node.isTextblock) {
266
+ blockStartB = resolvedB.start(_depth);
267
+ blockEndB = blockStartB + _node.nodeSize - 2; // exclude open/close tokens
268
+ break;
269
+ }
270
+ }
271
+ var blockLengthA = blockEndA - blockStartA;
272
+ var blockLengthB = blockEndB - blockStartB;
273
+ var totalChangedA = stepChangeList.reduce(function (sum, c) {
274
+ return sum + (c.toA - c.fromA);
275
+ }, 0);
276
+ var totalChangedB = stepChangeList.reduce(function (sum, c) {
277
+ return sum + (c.toB - c.fromB);
278
+ }, 0);
279
+ var ratioA = blockLengthA > 0 ? totalChangedA / blockLengthA : 0;
280
+ var ratioB = blockLengthB > 0 ? totalChangedB / blockLengthB : 0;
281
+ avgChangedRatio = (ratioA + ratioB) / 2;
282
+ }
283
+ var showGranularWithBlock = isGranular && granularCount !== 1 && (granularCount > 3 || avgChangedRatio >= 0.3);
284
+ stepChangeList.forEach(function (change) {
285
+ createDecorationsForChange(change, showGranularWithBlock);
286
+ });
287
+ if (showGranularWithBlock && stepChangeList.length > 0) {
288
+ var lastChange = stepChangeList[stepChangeList.length - 1];
289
+ var granularBlockDiffId = crypto.randomUUID();
290
+ var blockWidgets = (0, _createGranularBlockReferenceWidget.createGranularBlockReferenceWidget)({
291
+ change: lastChange,
292
+ originalDoc: originalDoc,
293
+ newDoc: tr.doc,
294
+ isInverted: isInverted,
295
+ nodeViewSerializer: nodeViewSerializer,
296
+ colorScheme: colorScheme,
297
+ intl: intl,
298
+ activeIndexPos: activeIndexPos,
299
+ diffId: granularBlockDiffId,
300
+ showIndicators: showIndicators
301
+ });
302
+ decorations.push.apply(decorations, (0, _toConsumableArray2.default)(blockWidgets));
303
+ }
304
+ });
305
+ } else {
306
+ changes.forEach(function (change) {
307
+ createDecorationsForChange(change, /* showGranularWithBlock */false);
308
+ });
309
+ }
223
310
  (0, _getMarkChangeRanges.getMarkChangeRanges)(steps).forEach(function (change) {
224
311
  var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
225
312
  decorations.push.apply(decorations, (0, _toConsumableArray2.default)((0, _createInlineChangedDecoration.createInlineChangedDecoration)({
@@ -259,34 +346,34 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref3
259
346
  };
260
347
  var calculateDiffDecorations = exports.calculateDiffDecorations = (0, _memoizeOne.default)(calculateDiffDecorationsInner,
261
348
  // Cache results unless relevant inputs change
262
- function (_ref4, _ref5) {
263
- var _ref9;
264
- var _ref6 = (0, _slicedToArray2.default)(_ref4, 1),
265
- _ref6$ = _ref6[0],
266
- pluginState = _ref6$.pluginState,
267
- state = _ref6$.state,
268
- colorScheme = _ref6$.colorScheme,
269
- intl = _ref6$.intl,
270
- activeIndexPos = _ref6$.activeIndexPos,
271
- isInverted = _ref6$.isInverted,
272
- diffType = _ref6$.diffType,
273
- hideDeletedDiffs = _ref6$.hideDeletedDiffs,
274
- showIndicators = _ref6$.showIndicators;
349
+ function (_ref5, _ref6) {
350
+ var _ref0;
275
351
  var _ref7 = (0, _slicedToArray2.default)(_ref5, 1),
276
352
  _ref7$ = _ref7[0],
277
- lastPluginState = _ref7$.pluginState,
278
- lastState = _ref7$.state,
279
- lastColorScheme = _ref7$.colorScheme,
280
- lastIntl = _ref7$.intl,
281
- lastActiveIndexPos = _ref7$.activeIndexPos,
282
- lastIsInverted = _ref7$.isInverted,
283
- lastDiffType = _ref7$.diffType,
284
- lastHideDeletedDiffs = _ref7$.hideDeletedDiffs,
285
- lastShowIndicators = _ref7$.showIndicators;
353
+ pluginState = _ref7$.pluginState,
354
+ state = _ref7$.state,
355
+ colorScheme = _ref7$.colorScheme,
356
+ intl = _ref7$.intl,
357
+ activeIndexPos = _ref7$.activeIndexPos,
358
+ isInverted = _ref7$.isInverted,
359
+ diffType = _ref7$.diffType,
360
+ hideDeletedDiffs = _ref7$.hideDeletedDiffs,
361
+ showIndicators = _ref7$.showIndicators;
362
+ var _ref8 = (0, _slicedToArray2.default)(_ref6, 1),
363
+ _ref8$ = _ref8[0],
364
+ lastPluginState = _ref8$.pluginState,
365
+ lastState = _ref8$.state,
366
+ lastColorScheme = _ref8$.colorScheme,
367
+ lastIntl = _ref8$.intl,
368
+ lastActiveIndexPos = _ref8$.activeIndexPos,
369
+ lastIsInverted = _ref8$.isInverted,
370
+ lastDiffType = _ref8$.diffType,
371
+ lastHideDeletedDiffs = _ref8$.hideDeletedDiffs,
372
+ lastShowIndicators = _ref8$.showIndicators;
286
373
  var originalDocIsSame = lastPluginState.originalDoc && pluginState.originalDoc && pluginState.originalDoc.eq(lastPluginState.originalDoc);
287
374
  if ((0, _expValEquals.expValEquals)('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
288
- var _ref8;
289
- return (_ref8 = colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isInverted === lastIsInverted && diffType === lastDiffType && (0, _isEqual.default)(activeIndexPos, lastActiveIndexPos) && originalDocIsSame && (0, _isEqual.default)(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && hideDeletedDiffs === lastHideDeletedDiffs && showIndicators === lastShowIndicators) !== null && _ref8 !== void 0 ? _ref8 : false;
375
+ var _ref9;
376
+ return (_ref9 = colorScheme === lastColorScheme && intl.locale === lastIntl.locale && isInverted === lastIsInverted && diffType === lastDiffType && (0, _isEqual.default)(activeIndexPos, lastActiveIndexPos) && originalDocIsSame && (0, _isEqual.default)(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && hideDeletedDiffs === lastHideDeletedDiffs && showIndicators === lastShowIndicators) !== null && _ref9 !== void 0 ? _ref9 : false;
290
377
  }
291
- return (_ref9 = originalDocIsSame && (0, _isEqual.default)(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && colorScheme === lastColorScheme && intl.locale === lastIntl.locale && (0, _isEqual.default)(activeIndexPos, lastActiveIndexPos) && hideDeletedDiffs === lastHideDeletedDiffs) !== null && _ref9 !== void 0 ? _ref9 : false;
378
+ return (_ref0 = originalDocIsSame && (0, _isEqual.default)(pluginState.steps, lastPluginState.steps) && state.doc.eq(lastState.doc) && colorScheme === lastColorScheme && intl.locale === lastIntl.locale && (0, _isEqual.default)(activeIndexPos, lastActiveIndexPos) && hideDeletedDiffs === lastHideDeletedDiffs) !== null && _ref0 !== void 0 ? _ref0 : false;
292
379
  });
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.diffBySteps = void 0;
7
+ exports.getStepChanges = exports.diffBySteps = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
10
10
  var _prosemirrorChangeset = require("prosemirror-changeset");
@@ -16,6 +16,12 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
16
16
  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; } } }; }
17
17
  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; } }
18
18
  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; }
19
+ // @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
20
+ var WORD_CHAR_REGEX = /(?:[0-9A-Z_a-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088F\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5C\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDC-\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C8A\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7DC\uA7F1-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDDC0-\uDDF3\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD40-\uDD59\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDD40-\uDD65\uDD6F-\uDD85\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDEC2-\uDEC7\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE3F\uDE40\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61\uDF80-\uDF89\uDF8B\uDF8E\uDF90-\uDFB5\uDFB7\uDFD1\uDFD3]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDED0-\uDEE3\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8\uDFC0-\uDFE0\uDFF0-\uDFF9]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDDB0-\uDDDB\uDDE0-\uDDE9\uDEE0-\uDEF2\uDF02\uDF04-\uDF10\uDF12-\uDF33\uDF50-\uDF59\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD80E\uD80F\uD81C-\uD822\uD840-\uD868\uD86A-\uD86D\uD86F-\uD872\uD874-\uD879\uD880-\uD883\uD885-\uD88C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F\uDC41-\uDC46\uDC60-\uDFFF]|\uD810[\uDC00-\uDFFA]|\uD811[\uDC00-\uDE46]|\uD818[\uDD00-\uDD1D\uDD30-\uDD39]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDD40-\uDD6C\uDD70-\uDD79\uDE40-\uDE96\uDEA0-\uDEB8\uDEBB-\uDED3\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3\uDFF2-\uDFF6]|\uD823[\uDC00-\uDCD5\uDCFF-\uDD1E\uDD80-\uDDF2]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD32\uDD50-\uDD52\uDD55\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD833[\uDCF0-\uDCF9]|\uD834[\uDEC0-\uDED3\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E\uDF25-\uDF2A]|\uD838[\uDC30-\uDC6D\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDCD0-\uDCEB\uDCF0-\uDCF9\uDDD0-\uDDED\uDDF0-\uDDFA\uDEC0-\uDEDE\uDEE0-\uDEE2\uDEE4\uDEE5\uDEE7-\uDEED\uDEF0-\uDEF4\uDEFE\uDEFF\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEAD\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0\uDFF0-\uDFFF]|\uD87B[\uDC00-\uDE5D]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A\uDF50-\uDFFF]|\uD88D[\uDC00-\uDC79])/;
21
+ // @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
22
+ var PUNCTUATION_REGEX = /(?:[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B4E\u1B4F\u1B5A-\u1B60\u1B7D-\u1B7F\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDD6E\uDEAD\uDED0\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9\uDFD4\uDFD5\uDFD7\uDFD8]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09\uDFE1]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDD6D-\uDD6F\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD839\uDDFF|\uD83A[\uDD5E\uDD5F])/;
23
+ // @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
24
+ var WHITESPACE_REGEX = /[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/;
19
25
  var mapPosition = function mapPosition(mapping, pos) {
20
26
  return mapping.map(pos);
21
27
  };
@@ -113,16 +119,7 @@ var expandToWordBoundaries = function expandToWordBoundaries(doc, from, to) {
113
119
  }
114
120
  var prev = chars[idx - 1];
115
121
  var next = chars[idx + 1];
116
- return (
117
- // @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
118
- /(?:[0-9A-Z_a-z\xAA\xB2\xB3\xB5\xB9\xBA\xBC-\xBE\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u0660-\u0669\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07C0-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088F\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0966-\u096F\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09E6-\u09F1\u09F4-\u09F9\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A66-\u0A6F\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AE6-\u0AEF\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B66-\u0B6F\u0B71-\u0B77\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0BE6-\u0BF2\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5C\u0C5D\u0C60\u0C61\u0C66-\u0C6F\u0C78-\u0C7E\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDC-\u0CDE\u0CE0\u0CE1\u0CE6-\u0CEF\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D58-\u0D61\u0D66-\u0D78\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DE6-\u0DEF\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F20-\u0F33\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F-\u1049\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1090-\u1099\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1369-\u137C\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A16\u1A20-\u1A54\u1A80-\u1A89\u1A90-\u1A99\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B50-\u1B59\u1B83-\u1BA0\u1BAE-\u1BE5\u1C00-\u1C23\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C8A\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2070\u2071\u2074-\u2079\u207F-\u2089\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2150-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2CFD\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u3192-\u3195\u31A0-\u31BF\u31F0-\u31FF\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7DC\uA7F1-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA830-\uA835\uA840-\uA873\uA882-\uA8B3\uA8D0-\uA8D9\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA900-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF-\uA9D9\uA9E0-\uA9E4\uA9E6-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDE80-\uDE9C\uDEA0-\uDED0\uDEE1-\uDEFB\uDF00-\uDF23\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDDC0-\uDDF3\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC58-\uDC76\uDC79-\uDC9E\uDCA7-\uDCAF\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDD1B\uDD20-\uDD39\uDD40-\uDD59\uDD80-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE40-\uDE48\uDE60-\uDE7E\uDE80-\uDE9F\uDEC0-\uDEC7\uDEC9-\uDEE4\uDEEB-\uDEEF\uDF00-\uDF35\uDF40-\uDF55\uDF58-\uDF72\uDF78-\uDF91\uDFA9-\uDFAF]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDD23\uDD30-\uDD39\uDD40-\uDD65\uDD6F-\uDD85\uDE60-\uDE7E\uDE80-\uDEA9\uDEB0\uDEB1\uDEC2-\uDEC7\uDF00-\uDF27\uDF30-\uDF45\uDF51-\uDF54\uDF70-\uDF81\uDFB0-\uDFCB\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC52-\uDC6F\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD03-\uDD26\uDD36-\uDD3F\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDD0-\uDDDA\uDDDC\uDDE1-\uDDF4\uDE00-\uDE11\uDE13-\uDE2B\uDE3F\uDE40\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDEF0-\uDEF9\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61\uDF80-\uDF89\uDF8B\uDF8E\uDF90-\uDFB5\uDFB7\uDFD1\uDFD3]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC50-\uDC59\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE50-\uDE59\uDE80-\uDEAA\uDEB8\uDEC0-\uDEC9\uDED0-\uDEE3\uDF00-\uDF1A\uDF30-\uDF3B\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCF2\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8\uDFC0-\uDFE0\uDFF0-\uDFF9]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC50-\uDC6C\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDDA0-\uDDA9\uDDB0-\uDDDB\uDDE0-\uDDE9\uDEE0-\uDEF2\uDF02\uDF04-\uDF10\uDF12-\uDF33\uDF50-\uDF59\uDFB0\uDFC0-\uDFD4]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD80E\uD80F\uD81C-\uD822\uD840-\uD868\uD86A-\uD86D\uD86F-\uD872\uD874-\uD879\uD880-\uD883\uD885-\uD88C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F\uDC41-\uDC46\uDC60-\uDFFF]|\uD810[\uDC00-\uDFFA]|\uD811[\uDC00-\uDE46]|\uD818[\uDD00-\uDD1D\uDD30-\uDD39]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDD40-\uDD6C\uDD70-\uDD79\uDE40-\uDE96\uDEA0-\uDEB8\uDEBB-\uDED3\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3\uDFF2-\uDFF6]|\uD823[\uDC00-\uDCD5\uDCFF-\uDD1E\uDD80-\uDDF2]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD32\uDD50-\uDD52\uDD55\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD833[\uDCF0-\uDCF9]|\uD834[\uDEC0-\uDED3\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD837[\uDF00-\uDF1E\uDF25-\uDF2A]|\uD838[\uDC30-\uDC6D\uDD00-\uDD2C\uDD37-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB\uDEF0-\uDEF9]|\uD839[\uDCD0-\uDCEB\uDCF0-\uDCF9\uDDD0-\uDDED\uDDF0-\uDDFA\uDEC0-\uDEDE\uDEE0-\uDEE2\uDEE4\uDEE5\uDEE7-\uDEED\uDEF0-\uDEF4\uDEFE\uDEFF\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCC7-\uDCCF\uDD00-\uDD43\uDD4B\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEAD\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0\uDFF0-\uDFFF]|\uD87B[\uDC00-\uDE5D]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A\uDF50-\uDFFF]|\uD88D[\uDC00-\uDC79])/.test(ch) ||
119
- // @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
120
- /(?:[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B4E\u1B4F\u1B5A-\u1B60\u1B7D-\u1B7F\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDD6E\uDEAD\uDED0\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9\uDFD4\uDFD5\uDFD7\uDFD8]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09\uDFE1]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDD6D-\uDD6F\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD839\uDDFF|\uD83A[\uDD5E\uDD5F])/.test(ch) && typeof prev === 'string' && typeof next === 'string' &&
121
- // @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
122
- !/[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/.test(prev) &&
123
- // @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
124
- !/[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]/.test(next)
125
- );
122
+ return WORD_CHAR_REGEX.test(ch) || PUNCTUATION_REGEX.test(ch) && typeof prev === 'string' && typeof next === 'string' && !WHITESPACE_REGEX.test(prev) && !WHITESPACE_REGEX.test(next);
126
123
  };
127
124
 
128
125
  // Detect whether the position sits mid-word: there is a word character
@@ -410,4 +407,127 @@ var diffBySteps = exports.diffBySteps = function diffBySteps(originalDoc, steps)
410
407
  });
411
408
  }
412
409
  return mergeOverlappingByNewDocRange(changes);
410
+ };
411
+
412
+ /**
413
+ * A fork of `diffBySteps` that returns changes grouped per step, rather than as a flat list.
414
+ *
415
+ * Why forked rather than refactoring `diffBySteps`:
416
+ * - `diffBySteps` returns a flat `Change[]` and is consumed by the existing decoration path.
417
+ * Changing its return shape would require threading per-step metadata through all callers,
418
+ * adding complexity to a stable code path.
419
+ * - The per-step grouping is only needed for the `platform_editor_diff_granular_extended` gate,
420
+ * where we need to know how many granular changes a single step produced in order to decide
421
+ * whether to suppress deleted decorations (threshold: > 3 granular changes per step).
422
+ * - Keeping the two functions separate means each has a clear, focused contract and neither
423
+ * accumulates the other's concerns. Shared logic (mapping helpers, `mergeOverlappingByNewDocRange`,
424
+ * `shouldCheckGranularDiff`, etc.) is already extracted and reused by both.
425
+ */
426
+ var getStepChanges = exports.getStepChanges = function getStepChanges(originalDoc, steps) {
427
+ var result = [];
428
+ var currentDoc = originalDoc;
429
+ var successfulStepMaps = [];
430
+ var rangedSteps = [];
431
+ var _iterator4 = _createForOfIteratorHelper(steps),
432
+ _step4;
433
+ try {
434
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
435
+ var step = _step4.value;
436
+ var before = currentDoc;
437
+ var stepResult = step.apply(currentDoc);
438
+ if (stepResult.failed !== null || !stepResult.doc) {
439
+ continue;
440
+ }
441
+ var stepMap = step.getMap();
442
+ var rangeStep = step;
443
+ if (typeof rangeStep.from === 'number' && typeof rangeStep.to === 'number') {
444
+ rangedSteps.push({
445
+ before: before,
446
+ doc: stepResult.doc,
447
+ from: rangeStep.from,
448
+ to: rangeStep.to,
449
+ mapIndex: successfulStepMaps.length,
450
+ step: step,
451
+ stepMap: stepMap
452
+ });
453
+ }
454
+ successfulStepMaps.push(stepMap);
455
+ currentDoc = stepResult.doc;
456
+ }
457
+ } catch (err) {
458
+ _iterator4.e(err);
459
+ } finally {
460
+ _iterator4.f();
461
+ }
462
+ for (var _i2 = 0, _rangedSteps2 = rangedSteps; _i2 < _rangedSteps2.length; _i2++) {
463
+ var rangedStep = _rangedSteps2[_i2];
464
+ var originalToBeforeStep = createMapping(successfulStepMaps.slice(0, rangedStep.mapIndex));
465
+ var beforeStepToOriginal = originalToBeforeStep.invert();
466
+ var fromA = mapPosition(beforeStepToOriginal, rangedStep.from);
467
+ var toA = mapPosition(beforeStepToOriginal, rangedStep.to);
468
+ var fromAfterStep = rangedStep.stepMap.map(rangedStep.from, -1);
469
+ var toAfterStep = rangedStep.stepMap.map(rangedStep.to, 1);
470
+ var afterStepToFinal = createMapping(successfulStepMaps.slice(rangedStep.mapIndex + 1));
471
+ var fromB = mapPosition(afterStepToFinal, fromAfterStep);
472
+ var toB = mapPosition(afterStepToFinal, toAfterStep);
473
+ if (shouldCheckGranularDiff(rangedStep.step, rangedStep.before, rangedStep.from, rangedStep.to)) {
474
+ var granularStepChanges = _prosemirrorChangeset.ChangeSet.create(rangedStep.before).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
475
+ var optimizedGranularStepChanges = (0, _optimizeChanges.optimizeChanges)((0, _prosemirrorChangeset.simplifyChanges)(granularStepChanges.changes, rangedStep.doc));
476
+ var stepChanges = [];
477
+ var _iterator5 = _createForOfIteratorHelper(optimizedGranularStepChanges),
478
+ _step5;
479
+ try {
480
+ for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
481
+ var granularChange = _step5.value;
482
+ var expandedA = expandToWordBoundaries(rangedStep.before, granularChange.fromA, granularChange.toA);
483
+ var expandedB = expandToWordBoundaries(rangedStep.doc, granularChange.fromB, granularChange.toB);
484
+ var aLeftDelta = granularChange.fromA - expandedA.from;
485
+ var aRightDelta = expandedA.to - granularChange.toA;
486
+ var bLeftDelta = granularChange.fromB - expandedB.from;
487
+ var bRightDelta = expandedB.to - granularChange.toB;
488
+ var finalA = expandedA;
489
+ var finalB = expandedB;
490
+ if (aLeftDelta > bLeftDelta || aRightDelta > bRightDelta) {
491
+ var extraLeft = Math.max(0, aLeftDelta - bLeftDelta);
492
+ var extraRight = Math.max(0, aRightDelta - bRightDelta);
493
+ finalB = expandToWordBoundaries(rangedStep.doc, Math.max(expandedB.from - extraLeft, 0), expandedB.to + extraRight);
494
+ }
495
+ if (bLeftDelta > aLeftDelta || bRightDelta > aRightDelta) {
496
+ var _extraLeft2 = Math.max(0, bLeftDelta - aLeftDelta);
497
+ var _extraRight2 = Math.max(0, bRightDelta - aRightDelta);
498
+ finalA = expandToWordBoundaries(rangedStep.before, Math.max(expandedA.from - _extraLeft2, 0), expandedA.to + _extraRight2);
499
+ }
500
+ stepChanges.push({
501
+ fromA: mapPosition(beforeStepToOriginal, finalA.from),
502
+ toA: mapPosition(beforeStepToOriginal, finalA.to),
503
+ fromB: mapPosition(afterStepToFinal, finalB.from),
504
+ toB: mapPosition(afterStepToFinal, finalB.to),
505
+ deleted: createSpans(Math.max(0, finalA.to - finalA.from)),
506
+ inserted: createSpans(Math.max(0, finalB.to - finalB.from))
507
+ });
508
+ }
509
+ } catch (err) {
510
+ _iterator5.e(err);
511
+ } finally {
512
+ _iterator5.f();
513
+ }
514
+ result.push({
515
+ isGranular: true,
516
+ changes: mergeOverlappingByNewDocRange(stepChanges)
517
+ });
518
+ continue;
519
+ }
520
+ result.push({
521
+ isGranular: false,
522
+ changes: [{
523
+ fromA: fromA,
524
+ toA: toA,
525
+ fromB: fromB,
526
+ toB: toB,
527
+ deleted: createSpans(Math.max(0, toA - fromA)),
528
+ inserted: createSpans(Math.max(0, toB - fromB))
529
+ }]
530
+ });
531
+ }
532
+ return result;
413
533
  };
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.createGranularBlockReferenceWidget = void 0;
7
+ var _view = require("@atlaskit/editor-prosemirror/view");
8
+ var _createAnchorDecorationWidgets = require("./createAnchorDecorationWidgets");
9
+ var _decorationKeys = require("./decorationKeys");
10
+ var _wrapBlockNodeView = require("./utils/wrapBlockNodeView");
11
+ /**
12
+ * Creates a single block widget that renders a reference text block content
13
+ * beneath a granular diff set, for reference when deleted content is hidden.
14
+ *
15
+ * Since granular diffing only applies to singular isTextBlock=true nodes, this
16
+ * widget always renders exactly one block node and does not need the slice/fragment
17
+ * complexity of createNodeChangedDecorationWidget.
18
+ *
19
+ * Resolves which doc and positions to render based on isInverted:
20
+ * - !isInverted: renders originalDoc at A-side positions (what was there before)
21
+ * - isInverted: renders newDoc at B-side positions (the current/new content)
22
+ *
23
+ * The widget is always inserted at the B-side block boundary in newDoc since
24
+ * ProseMirror decorations are always anchored against the live (new) document.
25
+ */
26
+ var createGranularBlockReferenceWidget = exports.createGranularBlockReferenceWidget = function createGranularBlockReferenceWidget(_ref) {
27
+ var change = _ref.change,
28
+ originalDoc = _ref.originalDoc,
29
+ newDoc = _ref.newDoc,
30
+ isInverted = _ref.isInverted,
31
+ nodeViewSerializer = _ref.nodeViewSerializer,
32
+ colorScheme = _ref.colorScheme,
33
+ intl = _ref.intl,
34
+ activeIndexPos = _ref.activeIndexPos,
35
+ diffId = _ref.diffId,
36
+ _ref$showIndicators = _ref.showIndicators,
37
+ showIndicators = _ref$showIndicators === void 0 ? false : _ref$showIndicators;
38
+ // Determine which doc and positions to use for rendering the reference block.
39
+ var renderDoc = isInverted ? newDoc : originalDoc;
40
+ var renderTo = isInverted ? change.toB : change.toA;
41
+
42
+ // The insertion point is always in newDoc — ProseMirror decorates against the live document.
43
+ // Walk up from toB to find the enclosing text block boundary for widget placement.
44
+ var insertResolvedPos = newDoc.resolve(change.toB);
45
+ var blockEnd = change.toB;
46
+ for (var depth = insertResolvedPos.depth; depth >= 0; depth--) {
47
+ var node = insertResolvedPos.node(depth);
48
+ if (node.isTextblock) {
49
+ blockEnd = insertResolvedPos.start(depth) + node.nodeSize - 1;
50
+ break;
51
+ }
52
+ }
53
+
54
+ // Find the block node to render from the render doc at the render positions.
55
+ var renderResolvedPos = renderDoc.resolve(renderTo);
56
+ var renderBlockNode = null;
57
+ for (var _depth = renderResolvedPos.depth; _depth >= 0; _depth--) {
58
+ var _node = renderResolvedPos.node(_depth);
59
+ if (_node.isTextblock) {
60
+ renderBlockNode = _node;
61
+ break;
62
+ }
63
+ }
64
+ if (!renderBlockNode) {
65
+ return [];
66
+ }
67
+ var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
68
+
69
+ /**
70
+ * This will always be a block node as it's a textBlock-like node.
71
+ * We use div instead of span so we can add margins.
72
+ */
73
+ var dom = document.createElement('div');
74
+ dom.setAttribute('data-testid', 'show-diff-granular-block-reference');
75
+ dom.style.setProperty('margin-top', "var(--ds-space-200, 16px)");
76
+ var nodeView = nodeViewSerializer.tryCreateNodeView(renderBlockNode);
77
+ if (nodeView) {
78
+ (0, _wrapBlockNodeView.wrapBlockNodeView)({
79
+ dom: dom,
80
+ nodeView: nodeView,
81
+ targetNode: renderBlockNode,
82
+ colorScheme: colorScheme,
83
+ intl: intl,
84
+ isActive: !!isActive,
85
+ isInserted: false
86
+ });
87
+ } else {
88
+ var serialized = nodeViewSerializer.serializeNode(renderBlockNode);
89
+ if (serialized && serialized instanceof HTMLElement) {
90
+ (0, _wrapBlockNodeView.injectInnerWrapper)({
91
+ node: serialized,
92
+ colorScheme: colorScheme,
93
+ isActive: !!isActive,
94
+ isInserted: false
95
+ });
96
+ dom.append(serialized);
97
+ } else if (serialized) {
98
+ dom.append(serialized);
99
+ }
100
+ }
101
+ if (dom.childNodes.length === 0) {
102
+ return [];
103
+ }
104
+ var decorations = [];
105
+ if (showIndicators) {
106
+ var leftAnchor = (0, _createAnchorDecorationWidgets.createLeftAnchorWidget)({
107
+ doc: newDoc,
108
+ from: blockEnd,
109
+ diffId: diffId
110
+ });
111
+ dom.style.setProperty('anchor-name', "--".concat((0, _decorationKeys.buildAnchorDecorationKey)({
112
+ diffId: diffId
113
+ })));
114
+ if (leftAnchor) {
115
+ decorations.push(leftAnchor);
116
+ }
117
+ }
118
+ decorations.push(_view.Decoration.widget(blockEnd, dom, (0, _decorationKeys.buildDiffDecorationSpec)({
119
+ decorationType: 'widget',
120
+ diffId: diffId,
121
+ // We want it to be as close to the granular diff as possible
122
+ side: -999
123
+ })));
124
+ return decorations;
125
+ };