@atlaskit/editor-plugin-show-diff 12.1.2 → 12.1.4
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.
- package/CHANGELOG.md +42 -0
- package/compass.yml +3 -3
- package/dist/cjs/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +76 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +47 -124
- package/dist/cjs/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
- package/dist/cjs/pm-plugins/calculateDiff/diffBySteps.js +3 -125
- package/dist/cjs/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
- package/dist/cjs/pm-plugins/decorations/colorSchemes/factory.js +678 -0
- package/dist/cjs/pm-plugins/decorations/colorSchemes/schemes.js +39 -0
- package/dist/cjs/pm-plugins/decorations/colorSchemes/types.js +1 -0
- package/dist/es2019/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +64 -0
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +15 -89
- package/dist/es2019/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
- package/dist/es2019/pm-plugins/calculateDiff/diffBySteps.js +2 -105
- package/dist/es2019/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/factory.js +625 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/schemes.js +33 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/types.js +0 -0
- package/dist/esm/pm-plugins/calculateDiff/attrAwareTokenEncoder.js +70 -0
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +48 -125
- package/dist/esm/pm-plugins/calculateDiff/computeDiffChanges.js +8 -1
- package/dist/esm/pm-plugins/calculateDiff/diffBySteps.js +2 -124
- package/dist/esm/pm-plugins/calculateDiff/smart/classifySmartChanges.js +9 -0
- package/dist/esm/pm-plugins/decorations/colorSchemes/factory.js +622 -0
- package/dist/esm/pm-plugins/decorations/colorSchemes/schemes.js +33 -0
- package/dist/esm/pm-plugins/decorations/colorSchemes/types.js +0 -0
- package/dist/types/pm-plugins/calculateDiff/attrAwareTokenEncoder.d.ts +7 -0
- package/dist/types/pm-plugins/calculateDiff/diffBySteps.d.ts +0 -20
- package/dist/types/pm-plugins/decorations/colorSchemes/factory.d.ts +101 -0
- package/dist/types/pm-plugins/decorations/colorSchemes/schemes.d.ts +5 -0
- package/dist/types/pm-plugins/decorations/colorSchemes/types.d.ts +38 -0
- package/package.json +6 -6
- package/dist/cjs/pm-plugins/decorations/createGranularBlockReferenceWidget.js +0 -125
- package/dist/es2019/pm-plugins/decorations/createGranularBlockReferenceWidget.js +0 -120
- package/dist/esm/pm-plugins/decorations/createGranularBlockReferenceWidget.js +0 -120
- package/dist/types/pm-plugins/decorations/createGranularBlockReferenceWidget.d.ts +0 -36
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attribute-aware token encoder for `prosemirror-changeset`.
|
|
3
|
+
*
|
|
4
|
+
* The library's default encoder reduces a node's open token to `node.type.name`,
|
|
5
|
+
* ignoring attributes. An attribute-only change (e.g. recolouring a table cell's
|
|
6
|
+
* `background`) therefore tokenises identically on both sides and reports no
|
|
7
|
+
* change at all.
|
|
8
|
+
*
|
|
9
|
+
* This encoder folds an allow-listed set of attributes into the open token so
|
|
10
|
+
* such changes register. Everything else encodes exactly as the default. The
|
|
11
|
+
* allow-list is deliberately narrow — folding in ephemeral attrs like `localId`
|
|
12
|
+
* would produce phantom diffs.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
var DIFFED_ATTRS_BY_NODE_TYPE = {
|
|
16
|
+
tableCell: ['background', 'colspan', 'rowspan'],
|
|
17
|
+
tableHeader: ['background', 'colspan', 'rowspan']
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Builds a stable composite token. Iterates the allow-list rather than
|
|
22
|
+
* `Object.keys` so ordering is deterministic for string comparison.
|
|
23
|
+
*/
|
|
24
|
+
var encodeNodeWithAttrs = function encodeNodeWithAttrs(node, attrNames) {
|
|
25
|
+
var _node$attrs;
|
|
26
|
+
var attrs = (_node$attrs = node.attrs) !== null && _node$attrs !== void 0 ? _node$attrs : {};
|
|
27
|
+
// Deterministic order: iterate the allow-list, not `Object.keys(attrs)`.
|
|
28
|
+
var parts = attrNames.map(function (name) {
|
|
29
|
+
var _attrs$name;
|
|
30
|
+
return "".concat(name, "=").concat(JSON.stringify((_attrs$name = attrs[name]) !== null && _attrs$name !== void 0 ? _attrs$name : null));
|
|
31
|
+
});
|
|
32
|
+
return "".concat(node.type.name, "|").concat(parts.join('|'));
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Identical to the library default except that allow-listed node types encode
|
|
37
|
+
* their allow-listed attributes into the open token. Characters and node-end
|
|
38
|
+
* tokens are left as-is, hence the `string | number` token type.
|
|
39
|
+
*/
|
|
40
|
+
export var attrAwareTokenEncoder = {
|
|
41
|
+
encodeCharacter: function encodeCharacter(char, _marks) {
|
|
42
|
+
return char;
|
|
43
|
+
},
|
|
44
|
+
encodeNodeStart: function encodeNodeStart(node) {
|
|
45
|
+
var attrNames = DIFFED_ATTRS_BY_NODE_TYPE[node.type.name];
|
|
46
|
+
if (attrNames) {
|
|
47
|
+
return encodeNodeWithAttrs(node, attrNames);
|
|
48
|
+
}
|
|
49
|
+
return node.type.name;
|
|
50
|
+
},
|
|
51
|
+
encodeNodeEnd: function encodeNodeEnd(node) {
|
|
52
|
+
return -typeID(node.type);
|
|
53
|
+
},
|
|
54
|
+
compareTokens: function compareTokens(a, b) {
|
|
55
|
+
return a === b;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Mirrors the library's private `typeID` so node-end tokens match the default
|
|
61
|
+
* encoding exactly. Reimplemented here because it is not exported.
|
|
62
|
+
*/
|
|
63
|
+
function typeID(type) {
|
|
64
|
+
var cache = type.schema.cached.changeSetIDs || (type.schema.cached.changeSetIDs = Object.create(null));
|
|
65
|
+
var id = cache[type.name];
|
|
66
|
+
if (id == null) {
|
|
67
|
+
cache[type.name] = id = Object.keys(type.schema.nodes).indexOf(type.name) + 1;
|
|
68
|
+
}
|
|
69
|
+
return id;
|
|
70
|
+
}
|
|
@@ -18,14 +18,14 @@ import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
|
18
18
|
import { areDocsEqualByBlockStructureAndText } from '../areDocsEqualByBlockStructureAndText';
|
|
19
19
|
import { createDocMarginAnchorWidget } from '../decorations/createAnchorDecorationWidgets';
|
|
20
20
|
import { createBlockChangedDecoration } from '../decorations/createBlockChangedDecoration';
|
|
21
|
-
import { createGranularBlockReferenceWidget } from '../decorations/createGranularBlockReferenceWidget';
|
|
22
21
|
import { createInlineChangedDecoration } from '../decorations/createInlineChangedDecoration';
|
|
23
22
|
import { createNodeChangedDecorationWidget } from '../decorations/createNodeChangedDecorationWidget';
|
|
24
23
|
import { extractDiffDescriptors } from '../decorations/decorationKeys';
|
|
25
24
|
import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
|
|
26
25
|
import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
|
|
27
26
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
28
|
-
import {
|
|
27
|
+
import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
|
|
28
|
+
import { diffBySteps } from './diffBySteps';
|
|
29
29
|
import { groupChangesByBlock } from './groupChangesByBlock';
|
|
30
30
|
import { optimizeChanges } from './optimizeChanges';
|
|
31
31
|
import { simplifySteps } from './simplifySteps';
|
|
@@ -232,7 +232,11 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
232
232
|
};
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
|
-
|
|
235
|
+
// The attribute-aware encoder is only needed by the smart classifier and is
|
|
236
|
+
// gated with it; other diff types keep the library default so their output is
|
|
237
|
+
// unchanged.
|
|
238
|
+
var tokenEncoder = diffType === 'smart' && fg('platform_editor_ai_smart_diff') ? attrAwareTokenEncoder : undefined;
|
|
239
|
+
var changeset = ChangeSet.create(originalDoc, undefined, tokenEncoder).addSteps(steppedDoc, stepMaps, tr.doc);
|
|
236
240
|
var changes = getChanges({
|
|
237
241
|
changeset: changeset,
|
|
238
242
|
originalDoc: originalDoc,
|
|
@@ -254,7 +258,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
254
258
|
|
|
255
259
|
// Our default operations are insertions, so it should match the opposite of isInverted.
|
|
256
260
|
var isInserted = !isInverted;
|
|
257
|
-
var createDecorationsForChange = function createDecorationsForChange(change
|
|
261
|
+
var createDecorationsForChange = function createDecorationsForChange(change) {
|
|
258
262
|
var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
|
|
259
263
|
|
|
260
264
|
// Hoisted because it decides BOTH where the deleted widget is anchored and — since the
|
|
@@ -266,10 +270,8 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
266
270
|
inlineDeletedDiffPlacement: inlineDeletedDiffPlacement
|
|
267
271
|
});
|
|
268
272
|
if (change.inserted.length > 0) {
|
|
269
|
-
//
|
|
270
|
-
|
|
271
|
-
// isInverted gates both — on an inverted diff the inserted side is visually the deleted side.
|
|
272
|
-
var shouldHideDeleted = isExtendedEnabled(diffType) ? isInverted && (hideDeletedDiffs || showGranularWithBlock && change.deleted.length > 0) : false;
|
|
273
|
+
// On an inverted diff the inserted side is visually the deleted side.
|
|
274
|
+
var shouldHideDeleted = isExtendedEnabled(diffType) ? isInverted && hideDeletedDiffs : false;
|
|
273
275
|
|
|
274
276
|
// For `smart` NODE-level promotions the change range spans a whole container
|
|
275
277
|
// (e.g. an entire list/table/layout, using outer node bounds). Applying a SINGLE
|
|
@@ -286,7 +288,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
286
288
|
// change. Used to decide if indicator anchor positions should be adjusted
|
|
287
289
|
// inward — when the widget is present the anchor must stay at the block
|
|
288
290
|
// boundary to keep the indicator bar continuous with the deleted content.
|
|
289
|
-
var willRenderDeletedWidget = change.deleted.length > 0 && !(isExtendedEnabled(diffType) && !isInverted &&
|
|
291
|
+
var willRenderDeletedWidget = change.deleted.length > 0 && !(isExtendedEnabled(diffType) && !isInverted && hideDeletedDiffs && change.inserted.length > 0);
|
|
290
292
|
if (isSmartNodeLevel) {
|
|
291
293
|
var _iterator2 = _createForOfIteratorHelper(leafTextblockRanges(tr.doc, change.fromB, change.toB)),
|
|
292
294
|
_step2;
|
|
@@ -350,7 +352,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
350
352
|
}))));
|
|
351
353
|
}
|
|
352
354
|
if (change.deleted.length > 0) {
|
|
353
|
-
var _shouldHideDeleted = isExtendedEnabled(diffType) ? !isInverted &&
|
|
355
|
+
var _shouldHideDeleted = isExtendedEnabled(diffType) ? !isInverted && hideDeletedDiffs && change.inserted.length > 0 : false;
|
|
354
356
|
if (!_shouldHideDeleted) {
|
|
355
357
|
decorations.push.apply(decorations, _toConsumableArray(createNodeChangedDecorationWidget(_objectSpread(_objectSpread({
|
|
356
358
|
change: change,
|
|
@@ -371,88 +373,9 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
371
373
|
}
|
|
372
374
|
}
|
|
373
375
|
};
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
// apply the shouldHideDeleted suppression threshold (> 3 granular changes per step).
|
|
378
|
-
// getChanges returns a flat Change[] with no per-step grouping, making this count impossible
|
|
379
|
-
// to derive after the fact without re-introducing per-change metadata.
|
|
380
|
-
var stepChanges = getStepChanges(originalDoc, steps);
|
|
381
|
-
stepChanges.forEach(function (_ref5) {
|
|
382
|
-
var isGranular = _ref5.isGranular,
|
|
383
|
-
stepChangeList = _ref5.changes;
|
|
384
|
-
var granularCount = isGranular ? stepChangeList.length : 0;
|
|
385
|
-
|
|
386
|
-
// Calculate the average ratio of changed content on both A (original) and B (new)
|
|
387
|
-
// sides of the diff. If 30% or more of the block has changed on average, we show
|
|
388
|
-
// the block reference widget even if the granular change count is below the threshold.
|
|
389
|
-
// Block length is derived from the enclosing text block boundaries rather than the
|
|
390
|
-
// first/last change positions, so unchanged words at the start/end are accounted for.
|
|
391
|
-
var avgChangedRatio = 0;
|
|
392
|
-
if (isGranular && stepChangeList.length > 0) {
|
|
393
|
-
var first = stepChangeList[0];
|
|
394
|
-
var last = stepChangeList[stepChangeList.length - 1];
|
|
395
|
-
var resolvedA = originalDoc.resolve(first.fromA);
|
|
396
|
-
var resolvedB = tr.doc.resolve(first.fromB);
|
|
397
|
-
var blockStartA = first.fromA;
|
|
398
|
-
var blockEndA = last.toA;
|
|
399
|
-
var blockStartB = first.fromB;
|
|
400
|
-
var blockEndB = last.toB;
|
|
401
|
-
for (var depth = resolvedA.depth; depth >= 0; depth--) {
|
|
402
|
-
var node = resolvedA.node(depth);
|
|
403
|
-
if (node.isTextblock) {
|
|
404
|
-
blockStartA = resolvedA.start(depth);
|
|
405
|
-
blockEndA = blockStartA + node.nodeSize - 2; // exclude open/close tokens
|
|
406
|
-
break;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
for (var _depth = resolvedB.depth; _depth >= 0; _depth--) {
|
|
410
|
-
var _node = resolvedB.node(_depth);
|
|
411
|
-
if (_node.isTextblock) {
|
|
412
|
-
blockStartB = resolvedB.start(_depth);
|
|
413
|
-
blockEndB = blockStartB + _node.nodeSize - 2; // exclude open/close tokens
|
|
414
|
-
break;
|
|
415
|
-
}
|
|
416
|
-
}
|
|
417
|
-
var blockLengthA = blockEndA - blockStartA;
|
|
418
|
-
var blockLengthB = blockEndB - blockStartB;
|
|
419
|
-
var totalChangedA = stepChangeList.reduce(function (sum, c) {
|
|
420
|
-
return sum + (c.toA - c.fromA);
|
|
421
|
-
}, 0);
|
|
422
|
-
var totalChangedB = stepChangeList.reduce(function (sum, c) {
|
|
423
|
-
return sum + (c.toB - c.fromB);
|
|
424
|
-
}, 0);
|
|
425
|
-
var ratioA = blockLengthA > 0 ? totalChangedA / blockLengthA : 0;
|
|
426
|
-
var ratioB = blockLengthB > 0 ? totalChangedB / blockLengthB : 0;
|
|
427
|
-
avgChangedRatio = (ratioA + ratioB) / 2;
|
|
428
|
-
}
|
|
429
|
-
var showGranularWithBlock = isGranular && granularCount !== 1 && (granularCount > 3 || avgChangedRatio >= 0.3);
|
|
430
|
-
stepChangeList.forEach(function (change) {
|
|
431
|
-
createDecorationsForChange(change, showGranularWithBlock);
|
|
432
|
-
});
|
|
433
|
-
if (showGranularWithBlock && stepChangeList.length > 0 && !hideDeletedDiffs) {
|
|
434
|
-
var lastChange = stepChangeList[stepChangeList.length - 1];
|
|
435
|
-
var granularBlockDiffId = crypto.randomUUID();
|
|
436
|
-
var blockWidgets = createGranularBlockReferenceWidget({
|
|
437
|
-
change: lastChange,
|
|
438
|
-
originalDoc: originalDoc,
|
|
439
|
-
newDoc: tr.doc,
|
|
440
|
-
isInverted: isInverted,
|
|
441
|
-
nodeViewSerializer: nodeViewSerializer,
|
|
442
|
-
colorScheme: colorScheme,
|
|
443
|
-
intl: intl,
|
|
444
|
-
activeIndexPos: activeIndexPos,
|
|
445
|
-
diffId: granularBlockDiffId,
|
|
446
|
-
showIndicators: showIndicators
|
|
447
|
-
});
|
|
448
|
-
decorations.push.apply(decorations, _toConsumableArray(blockWidgets));
|
|
449
|
-
}
|
|
450
|
-
});
|
|
451
|
-
} else {
|
|
452
|
-
changes.forEach(function (change) {
|
|
453
|
-
createDecorationsForChange(change, /* showGranularWithBlock */false);
|
|
454
|
-
});
|
|
455
|
-
}
|
|
376
|
+
changes.forEach(function (change) {
|
|
377
|
+
createDecorationsForChange(change);
|
|
378
|
+
});
|
|
456
379
|
getMarkChangeRanges(steps).forEach(function (change) {
|
|
457
380
|
var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
|
|
458
381
|
decorations.push.apply(decorations, _toConsumableArray(createInlineChangedDecoration({
|
|
@@ -524,42 +447,42 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
524
447
|
};
|
|
525
448
|
export var calculateDiffDecorations = memoizeOne(calculateDiffDecorationsInner,
|
|
526
449
|
// Cache results unless relevant inputs change
|
|
527
|
-
function (
|
|
528
|
-
var
|
|
450
|
+
function (_ref5, _ref6) {
|
|
451
|
+
var _ref0;
|
|
452
|
+
var _ref7 = _slicedToArray(_ref5, 1),
|
|
453
|
+
_ref7$ = _ref7[0],
|
|
454
|
+
pluginState = _ref7$.pluginState,
|
|
455
|
+
state = _ref7$.state,
|
|
456
|
+
colorScheme = _ref7$.colorScheme,
|
|
457
|
+
intl = _ref7$.intl,
|
|
458
|
+
activeIndexPos = _ref7$.activeIndexPos,
|
|
459
|
+
isInverted = _ref7$.isInverted,
|
|
460
|
+
diffType = _ref7$.diffType,
|
|
461
|
+
hideDeletedDiffs = _ref7$.hideDeletedDiffs,
|
|
462
|
+
hideAddedDiffsUnderline = _ref7$.hideAddedDiffsUnderline,
|
|
463
|
+
showIndicators = _ref7$.showIndicators,
|
|
464
|
+
smartThresholds = _ref7$.smartThresholds,
|
|
465
|
+
deletedDiffPlacement = _ref7$.deletedDiffPlacement,
|
|
466
|
+
inlineDeletedDiffPlacement = _ref7$.inlineDeletedDiffPlacement;
|
|
529
467
|
var _ref8 = _slicedToArray(_ref6, 1),
|
|
530
468
|
_ref8$ = _ref8[0],
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
var _ref9 = _slicedToArray(_ref7, 1),
|
|
545
|
-
_ref9$ = _ref9[0],
|
|
546
|
-
lastPluginState = _ref9$.pluginState,
|
|
547
|
-
lastState = _ref9$.state,
|
|
548
|
-
lastColorScheme = _ref9$.colorScheme,
|
|
549
|
-
lastIntl = _ref9$.intl,
|
|
550
|
-
lastActiveIndexPos = _ref9$.activeIndexPos,
|
|
551
|
-
lastIsInverted = _ref9$.isInverted,
|
|
552
|
-
lastDiffType = _ref9$.diffType,
|
|
553
|
-
lastHideDeletedDiffs = _ref9$.hideDeletedDiffs,
|
|
554
|
-
lastHideAddedDiffsUnderline = _ref9$.hideAddedDiffsUnderline,
|
|
555
|
-
lastShowIndicators = _ref9$.showIndicators,
|
|
556
|
-
lastSmartThresholds = _ref9$.smartThresholds,
|
|
557
|
-
lastDeletedDiffPlacement = _ref9$.deletedDiffPlacement,
|
|
558
|
-
lastInlineDeletedDiffPlacement = _ref9$.inlineDeletedDiffPlacement;
|
|
469
|
+
lastPluginState = _ref8$.pluginState,
|
|
470
|
+
lastState = _ref8$.state,
|
|
471
|
+
lastColorScheme = _ref8$.colorScheme,
|
|
472
|
+
lastIntl = _ref8$.intl,
|
|
473
|
+
lastActiveIndexPos = _ref8$.activeIndexPos,
|
|
474
|
+
lastIsInverted = _ref8$.isInverted,
|
|
475
|
+
lastDiffType = _ref8$.diffType,
|
|
476
|
+
lastHideDeletedDiffs = _ref8$.hideDeletedDiffs,
|
|
477
|
+
lastHideAddedDiffsUnderline = _ref8$.hideAddedDiffsUnderline,
|
|
478
|
+
lastShowIndicators = _ref8$.showIndicators,
|
|
479
|
+
lastSmartThresholds = _ref8$.smartThresholds,
|
|
480
|
+
lastDeletedDiffPlacement = _ref8$.deletedDiffPlacement,
|
|
481
|
+
lastInlineDeletedDiffPlacement = _ref8$.inlineDeletedDiffPlacement;
|
|
559
482
|
var originalDocIsSame = lastPluginState.originalDoc && pluginState.originalDoc && pluginState.originalDoc.eq(lastPluginState.originalDoc);
|
|
560
483
|
if (isExtendedEnabled(diffType)) {
|
|
561
|
-
var
|
|
562
|
-
return (
|
|
484
|
+
var _ref9;
|
|
485
|
+
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 && hideAddedDiffsUnderline === lastHideAddedDiffsUnderline && showIndicators === lastShowIndicators && isEqual(smartThresholds, lastSmartThresholds) && deletedDiffPlacement === lastDeletedDiffPlacement && inlineDeletedDiffPlacement === lastInlineDeletedDiffPlacement) !== null && _ref9 !== void 0 ? _ref9 : false;
|
|
563
486
|
}
|
|
564
|
-
return (
|
|
487
|
+
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;
|
|
565
488
|
});
|
|
@@ -17,6 +17,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
17
17
|
* reconstructed by applying the (simplified) steps to `originalDoc`.
|
|
18
18
|
*/
|
|
19
19
|
import { ChangeSet, simplifyChanges } from 'prosemirror-changeset';
|
|
20
|
+
import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
|
|
20
21
|
import { diffBySteps } from './diffBySteps';
|
|
21
22
|
import { groupChangesByBlock } from './groupChangesByBlock';
|
|
22
23
|
import { optimizeChanges } from './optimizeChanges';
|
|
@@ -75,7 +76,13 @@ export var computeDiffChanges = function computeDiffChanges(_ref) {
|
|
|
75
76
|
newDoc: originalDoc
|
|
76
77
|
};
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
+
|
|
80
|
+
// The attribute-aware encoder only affects the `smart` classification, so it is
|
|
81
|
+
// applied only for that type. (This utility intentionally applies no feature
|
|
82
|
+
// gate — see the file docstring — but a caller requesting `smart` is already
|
|
83
|
+
// behind the smart-diff gate.)
|
|
84
|
+
var tokenEncoder = diffType === 'smart' ? attrAwareTokenEncoder : undefined;
|
|
85
|
+
var changeset = ChangeSet.create(originalDoc, undefined, tokenEncoder).addSteps(steppedDoc, stepMaps, steppedDoc);
|
|
79
86
|
if (diffType === 'smart') {
|
|
80
87
|
return {
|
|
81
88
|
changes: classifySmartChanges({
|
|
@@ -8,6 +8,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
8
8
|
import { simplifyChanges, ChangeSet } from 'prosemirror-changeset';
|
|
9
9
|
import { Mark } from '@atlaskit/editor-prosemirror/model';
|
|
10
10
|
import { Mapping, ReplaceStep } from '@atlaskit/editor-prosemirror/transform';
|
|
11
|
+
import { attrAwareTokenEncoder } from './attrAwareTokenEncoder';
|
|
11
12
|
import { optimizeChanges } from './optimizeChanges';
|
|
12
13
|
|
|
13
14
|
// @ts-ignore TS1501: This regular expression flag is only available when targeting 'es6' or later.
|
|
@@ -322,7 +323,7 @@ export var diffBySteps = function diffBySteps(originalDoc, steps) {
|
|
|
322
323
|
var fromB = mapPosition(afterStepToFinal, fromAfterStep);
|
|
323
324
|
var toB = mapPosition(afterStepToFinal, toAfterStep);
|
|
324
325
|
if (shouldCheckGranularDiff(rangedStep.step, rangedStep.before, rangedStep.from, rangedStep.to)) {
|
|
325
|
-
var granularStepChanges = ChangeSet.create(rangedStep.before).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
|
|
326
|
+
var granularStepChanges = ChangeSet.create(rangedStep.before, undefined, attrAwareTokenEncoder).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
|
|
326
327
|
|
|
327
328
|
// `simplifyChanges` reads text using `Change.fromB`/`toB`, which are
|
|
328
329
|
// positions in the post-step doc (the "B" doc). Passing the pre-step
|
|
@@ -401,127 +402,4 @@ export var diffBySteps = function diffBySteps(originalDoc, steps) {
|
|
|
401
402
|
});
|
|
402
403
|
}
|
|
403
404
|
return mergeOverlappingByNewDocRange(changes);
|
|
404
|
-
};
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* A fork of `diffBySteps` that returns changes grouped per step, rather than as a flat list.
|
|
408
|
-
*
|
|
409
|
-
* Why forked rather than refactoring `diffBySteps`:
|
|
410
|
-
* - `diffBySteps` returns a flat `Change[]` and is consumed by the existing decoration path.
|
|
411
|
-
* Changing its return shape would require threading per-step metadata through all callers,
|
|
412
|
-
* adding complexity to a stable code path.
|
|
413
|
-
* - The per-step grouping is only needed for the `platform_editor_diff_granular_extended` gate,
|
|
414
|
-
* where we need to know how many granular changes a single step produced in order to decide
|
|
415
|
-
* whether to suppress deleted decorations (threshold: > 3 granular changes per step).
|
|
416
|
-
* - Keeping the two functions separate means each has a clear, focused contract and neither
|
|
417
|
-
* accumulates the other's concerns. Shared logic (mapping helpers, `mergeOverlappingByNewDocRange`,
|
|
418
|
-
* `shouldCheckGranularDiff`, etc.) is already extracted and reused by both.
|
|
419
|
-
*/
|
|
420
|
-
export var getStepChanges = function getStepChanges(originalDoc, steps) {
|
|
421
|
-
var result = [];
|
|
422
|
-
var currentDoc = originalDoc;
|
|
423
|
-
var successfulStepMaps = [];
|
|
424
|
-
var rangedSteps = [];
|
|
425
|
-
var _iterator4 = _createForOfIteratorHelper(steps),
|
|
426
|
-
_step4;
|
|
427
|
-
try {
|
|
428
|
-
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
429
|
-
var step = _step4.value;
|
|
430
|
-
var before = currentDoc;
|
|
431
|
-
var stepResult = step.apply(currentDoc);
|
|
432
|
-
if (stepResult.failed !== null || !stepResult.doc) {
|
|
433
|
-
continue;
|
|
434
|
-
}
|
|
435
|
-
var stepMap = step.getMap();
|
|
436
|
-
var rangeStep = step;
|
|
437
|
-
if (typeof rangeStep.from === 'number' && typeof rangeStep.to === 'number') {
|
|
438
|
-
rangedSteps.push({
|
|
439
|
-
before: before,
|
|
440
|
-
doc: stepResult.doc,
|
|
441
|
-
from: rangeStep.from,
|
|
442
|
-
to: rangeStep.to,
|
|
443
|
-
mapIndex: successfulStepMaps.length,
|
|
444
|
-
step: step,
|
|
445
|
-
stepMap: stepMap
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
successfulStepMaps.push(stepMap);
|
|
449
|
-
currentDoc = stepResult.doc;
|
|
450
|
-
}
|
|
451
|
-
} catch (err) {
|
|
452
|
-
_iterator4.e(err);
|
|
453
|
-
} finally {
|
|
454
|
-
_iterator4.f();
|
|
455
|
-
}
|
|
456
|
-
for (var _i2 = 0, _rangedSteps2 = rangedSteps; _i2 < _rangedSteps2.length; _i2++) {
|
|
457
|
-
var rangedStep = _rangedSteps2[_i2];
|
|
458
|
-
var originalToBeforeStep = createMapping(successfulStepMaps.slice(0, rangedStep.mapIndex));
|
|
459
|
-
var beforeStepToOriginal = originalToBeforeStep.invert();
|
|
460
|
-
var fromA = mapPosition(beforeStepToOriginal, rangedStep.from);
|
|
461
|
-
var toA = mapPosition(beforeStepToOriginal, rangedStep.to);
|
|
462
|
-
var fromAfterStep = rangedStep.stepMap.map(rangedStep.from, -1);
|
|
463
|
-
var toAfterStep = rangedStep.stepMap.map(rangedStep.to, 1);
|
|
464
|
-
var afterStepToFinal = createMapping(successfulStepMaps.slice(rangedStep.mapIndex + 1));
|
|
465
|
-
var fromB = mapPosition(afterStepToFinal, fromAfterStep);
|
|
466
|
-
var toB = mapPosition(afterStepToFinal, toAfterStep);
|
|
467
|
-
if (shouldCheckGranularDiff(rangedStep.step, rangedStep.before, rangedStep.from, rangedStep.to)) {
|
|
468
|
-
var granularStepChanges = ChangeSet.create(rangedStep.before).addSteps(rangedStep.doc, [rangedStep.stepMap], null);
|
|
469
|
-
var optimizedGranularStepChanges = optimizeChanges(simplifyChanges(granularStepChanges.changes, rangedStep.doc));
|
|
470
|
-
var stepChanges = [];
|
|
471
|
-
var _iterator5 = _createForOfIteratorHelper(optimizedGranularStepChanges),
|
|
472
|
-
_step5;
|
|
473
|
-
try {
|
|
474
|
-
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
475
|
-
var granularChange = _step5.value;
|
|
476
|
-
var expandedA = expandToWordBoundaries(rangedStep.before, granularChange.fromA, granularChange.toA);
|
|
477
|
-
var expandedB = expandToWordBoundaries(rangedStep.doc, granularChange.fromB, granularChange.toB);
|
|
478
|
-
var aLeftDelta = granularChange.fromA - expandedA.from;
|
|
479
|
-
var aRightDelta = expandedA.to - granularChange.toA;
|
|
480
|
-
var bLeftDelta = granularChange.fromB - expandedB.from;
|
|
481
|
-
var bRightDelta = expandedB.to - granularChange.toB;
|
|
482
|
-
var finalA = expandedA;
|
|
483
|
-
var finalB = expandedB;
|
|
484
|
-
if (aLeftDelta > bLeftDelta || aRightDelta > bRightDelta) {
|
|
485
|
-
var extraLeft = Math.max(0, aLeftDelta - bLeftDelta);
|
|
486
|
-
var extraRight = Math.max(0, aRightDelta - bRightDelta);
|
|
487
|
-
finalB = expandToWordBoundaries(rangedStep.doc, Math.max(expandedB.from - extraLeft, 0), expandedB.to + extraRight);
|
|
488
|
-
}
|
|
489
|
-
if (bLeftDelta > aLeftDelta || bRightDelta > aRightDelta) {
|
|
490
|
-
var _extraLeft2 = Math.max(0, bLeftDelta - aLeftDelta);
|
|
491
|
-
var _extraRight2 = Math.max(0, bRightDelta - aRightDelta);
|
|
492
|
-
finalA = expandToWordBoundaries(rangedStep.before, Math.max(expandedA.from - _extraLeft2, 0), expandedA.to + _extraRight2);
|
|
493
|
-
}
|
|
494
|
-
stepChanges.push({
|
|
495
|
-
fromA: mapPosition(beforeStepToOriginal, finalA.from),
|
|
496
|
-
toA: mapPosition(beforeStepToOriginal, finalA.to),
|
|
497
|
-
fromB: mapPosition(afterStepToFinal, finalB.from),
|
|
498
|
-
toB: mapPosition(afterStepToFinal, finalB.to),
|
|
499
|
-
deleted: createSpans(Math.max(0, finalA.to - finalA.from)),
|
|
500
|
-
inserted: createSpans(Math.max(0, finalB.to - finalB.from))
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
} catch (err) {
|
|
504
|
-
_iterator5.e(err);
|
|
505
|
-
} finally {
|
|
506
|
-
_iterator5.f();
|
|
507
|
-
}
|
|
508
|
-
result.push({
|
|
509
|
-
isGranular: true,
|
|
510
|
-
changes: mergeOverlappingByNewDocRange(stepChanges)
|
|
511
|
-
});
|
|
512
|
-
continue;
|
|
513
|
-
}
|
|
514
|
-
result.push({
|
|
515
|
-
isGranular: false,
|
|
516
|
-
changes: [{
|
|
517
|
-
fromA: fromA,
|
|
518
|
-
toA: toA,
|
|
519
|
-
fromB: fromB,
|
|
520
|
-
toB: toB,
|
|
521
|
-
deleted: createSpans(Math.max(0, toA - fromA)),
|
|
522
|
-
inserted: createSpans(Math.max(0, toB - fromB))
|
|
523
|
-
}]
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
return result;
|
|
527
405
|
};
|
|
@@ -765,6 +765,15 @@ var _classifyChild = function classifyChild(childA, childB, changes, originalDoc
|
|
|
765
765
|
var childrenB = childRefs(blockB);
|
|
766
766
|
var childrenA = wrapperA ? childRefs(wrapperA) : [];
|
|
767
767
|
var out = [];
|
|
768
|
+
|
|
769
|
+
// An attribute-only change on the wrapper itself (e.g. a table cell's
|
|
770
|
+
// `background`) sits on the node boundary, not inside any inner child, so the
|
|
771
|
+
// recursion below would emit nothing and the change would be dropped. Emit a
|
|
772
|
+
// whole-wrapper change instead, which also subsumes any inner content change.
|
|
773
|
+
if (wrapperA && !wrapperA.node.sameMarkup(blockB.node)) {
|
|
774
|
+
out.push(makePromotedChange(wrapperA.from, wrapperA.to, blockB.from, blockB.to, 'node'));
|
|
775
|
+
return out;
|
|
776
|
+
}
|
|
768
777
|
// LCS-align inner children (mirrors classifyContainer) so a paragraph inserted/deleted
|
|
769
778
|
// inside the cell/column does not mis-pair every subsequent inner child by index. We never
|
|
770
779
|
// promote the wrapper itself here — we only classify each inner child.
|