@atlaskit/editor-plugin-show-diff 10.1.10 → 10.1.12
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 +17 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +118 -31
- package/dist/cjs/pm-plugins/calculateDiff/diffBySteps.js +124 -1
- package/dist/cjs/pm-plugins/decorations/colorSchemes/standard.js +6 -1
- package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +17 -0
- package/dist/cjs/pm-plugins/decorations/createGranularBlockReferenceWidget.js +125 -0
- package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +50 -105
- package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +79 -1
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +91 -7
- package/dist/es2019/pm-plugins/calculateDiff/diffBySteps.js +104 -0
- package/dist/es2019/pm-plugins/decorations/colorSchemes/standard.js +5 -0
- package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +18 -1
- package/dist/es2019/pm-plugins/decorations/createGranularBlockReferenceWidget.js +120 -0
- package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +41 -89
- package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +74 -2
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +119 -32
- package/dist/esm/pm-plugins/calculateDiff/diffBySteps.js +123 -0
- package/dist/esm/pm-plugins/decorations/colorSchemes/standard.js +5 -0
- package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +18 -1
- package/dist/esm/pm-plugins/decorations/createGranularBlockReferenceWidget.js +120 -0
- package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +46 -100
- package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +79 -2
- package/dist/types/pm-plugins/calculateDiff/diffBySteps.d.ts +20 -0
- package/dist/types/pm-plugins/decorations/colorSchemes/standard.d.ts +1 -0
- package/dist/types/pm-plugins/decorations/createGranularBlockReferenceWidget.d.ts +36 -0
- package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeView.d.ts +15 -0
- package/package.json +2 -2
|
@@ -401,4 +401,127 @@ export var diffBySteps = function diffBySteps(originalDoc, steps) {
|
|
|
401
401
|
});
|
|
402
402
|
}
|
|
403
403
|
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;
|
|
404
527
|
};
|
|
@@ -136,6 +136,11 @@ export var standardDecorationMarkerVariable = convertToInlineCss({
|
|
|
136
136
|
'--diff-decoration-marker-color': "var(--ds-border-accent-purple, #AF59E1)",
|
|
137
137
|
'--diff-decoration-marker-ring-width': '1px'
|
|
138
138
|
});
|
|
139
|
+
export var deletedDecorationMarkerVariable = convertToInlineCss({
|
|
140
|
+
'--diff-decoration-marker-color': "var(--ds-border-accent-gray, #7D818A)",
|
|
141
|
+
'--diff-decoration-marker-ring-width': '1px',
|
|
142
|
+
opacity: 0.8
|
|
143
|
+
});
|
|
139
144
|
export var addedCellOverlayStyle = convertToInlineCss({
|
|
140
145
|
position: 'absolute',
|
|
141
146
|
top: 0,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
2
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
3
3
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
4
|
-
import { standardDecorationMarkerVariable, editingStyleQuoteNode, editingStyleRuleNode, editingStyleCardBlockNode, editingStyleNode, deletedContentStyleNew, deletedStyleQuoteNode, addedCellOverlayStyle, deletedCellOverlayStyle } from './colorSchemes/standard';
|
|
4
|
+
import { standardDecorationMarkerVariable, deletedDecorationMarkerVariable, editingStyleQuoteNode, editingStyleRuleNode, editingStyleCardBlockNode, editingStyleNode, deletedContentStyleNew, deletedStyleQuoteNode, addedCellOverlayStyle, deletedCellOverlayStyle } from './colorSchemes/standard';
|
|
5
5
|
import { traditionalDecorationMarkerVariableActive, traditionalDecorationMarkerVariableNew, traditionalDeletedDecorationMarkerVariableActive, traditionalDeletedDecorationMarkerVariableNew, traditionalStyleQuoteNodeActive, traditionalStyleQuoteNodeNew, traditionalStyleRuleNodeActive, traditionalStyleRuleNodeNew, traditionalStyleCardBlockNodeActive, traditionalStyleCardBlockNodeNew, traditionalStyleNodeActive, traditionalStyleNodeNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, traditionalAddedCellOverlayStyle, deletedTraditionalCellOverlayStyle } from './colorSchemes/traditional';
|
|
6
6
|
import { buildDiffDecorationSpec } from './decorationKeys';
|
|
7
7
|
var displayNoneStyle = convertToInlineCss({
|
|
@@ -31,6 +31,14 @@ var getBlockNodeStyle = function getBlockNodeStyle(_ref) {
|
|
|
31
31
|
// Layout nodes do not need special styling
|
|
32
32
|
return undefined;
|
|
33
33
|
}
|
|
34
|
+
// Media nodes inside mediaSingle should not get position:relative
|
|
35
|
+
// as it shifts the image outside its parent container (e.g. panel)
|
|
36
|
+
if (nodeName === 'media') {
|
|
37
|
+
if (!isInserted && expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
38
|
+
return isTraditional ? getDeletedTraditionalInlineStyle(false) : deletedDecorationMarkerVariable;
|
|
39
|
+
}
|
|
40
|
+
return isTraditional ? isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew : editingStyleNode;
|
|
41
|
+
}
|
|
34
42
|
if (['tableCell', 'tableHeader'].includes(nodeName)) {
|
|
35
43
|
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
36
44
|
// This is used for positioning the cell overlay widget decorations
|
|
@@ -41,11 +49,20 @@ var getBlockNodeStyle = function getBlockNodeStyle(_ref) {
|
|
|
41
49
|
// When gate is off, it should return undefined as above
|
|
42
50
|
return undefined;
|
|
43
51
|
}
|
|
52
|
+
if (nodeName === 'panel') {
|
|
53
|
+
if (!isInserted && expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
54
|
+
return isTraditional ? getDeletedTraditionalInlineStyle(false) : deletedDecorationMarkerVariable;
|
|
55
|
+
}
|
|
56
|
+
return isTraditional ? isActive ? traditionalStyleNodeActive : traditionalStyleNodeNew : editingStyleNode;
|
|
57
|
+
}
|
|
44
58
|
if (['extension', 'embedCard', 'listItem'].includes(nodeName)) {
|
|
45
59
|
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
46
60
|
if (isInserted) {
|
|
47
61
|
return isTraditional && isActive ? traditionalDecorationMarkerVariableActive : isTraditional ? traditionalDecorationMarkerVariableNew : standardDecorationMarkerVariable;
|
|
48
62
|
} else {
|
|
63
|
+
if (nodeName === 'listItem') {
|
|
64
|
+
return isTraditional && isActive ? traditionalDeletedDecorationMarkerVariableActive : isTraditional ? traditionalDeletedDecorationMarkerVariableNew : deletedDecorationMarkerVariable;
|
|
65
|
+
}
|
|
49
66
|
return isTraditional && isActive ? traditionalDeletedDecorationMarkerVariableActive : isTraditional ? traditionalDeletedDecorationMarkerVariableNew : deletedContentStyleNew;
|
|
50
67
|
}
|
|
51
68
|
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
2
|
+
import { createLeftAnchorWidget } from './createAnchorDecorationWidgets';
|
|
3
|
+
import { buildDiffDecorationSpec, buildAnchorDecorationKey } from './decorationKeys';
|
|
4
|
+
import { wrapBlockNodeView, injectInnerWrapper } from './utils/wrapBlockNodeView';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a single block widget that renders a reference text block content
|
|
8
|
+
* beneath a granular diff set, for reference when deleted content is hidden.
|
|
9
|
+
*
|
|
10
|
+
* Since granular diffing only applies to singular isTextBlock=true nodes, this
|
|
11
|
+
* widget always renders exactly one block node and does not need the slice/fragment
|
|
12
|
+
* complexity of createNodeChangedDecorationWidget.
|
|
13
|
+
*
|
|
14
|
+
* Resolves which doc and positions to render based on isInverted:
|
|
15
|
+
* - !isInverted: renders originalDoc at A-side positions (what was there before)
|
|
16
|
+
* - isInverted: renders newDoc at B-side positions (the current/new content)
|
|
17
|
+
*
|
|
18
|
+
* The widget is always inserted at the B-side block boundary in newDoc since
|
|
19
|
+
* ProseMirror decorations are always anchored against the live (new) document.
|
|
20
|
+
*/
|
|
21
|
+
export var createGranularBlockReferenceWidget = function createGranularBlockReferenceWidget(_ref) {
|
|
22
|
+
var change = _ref.change,
|
|
23
|
+
originalDoc = _ref.originalDoc,
|
|
24
|
+
newDoc = _ref.newDoc,
|
|
25
|
+
isInverted = _ref.isInverted,
|
|
26
|
+
nodeViewSerializer = _ref.nodeViewSerializer,
|
|
27
|
+
colorScheme = _ref.colorScheme,
|
|
28
|
+
intl = _ref.intl,
|
|
29
|
+
activeIndexPos = _ref.activeIndexPos,
|
|
30
|
+
diffId = _ref.diffId,
|
|
31
|
+
_ref$showIndicators = _ref.showIndicators,
|
|
32
|
+
showIndicators = _ref$showIndicators === void 0 ? false : _ref$showIndicators;
|
|
33
|
+
// Determine which doc and positions to use for rendering the reference block.
|
|
34
|
+
var renderDoc = isInverted ? newDoc : originalDoc;
|
|
35
|
+
var renderTo = isInverted ? change.toB : change.toA;
|
|
36
|
+
|
|
37
|
+
// The insertion point is always in newDoc — ProseMirror decorates against the live document.
|
|
38
|
+
// Walk up from toB to find the enclosing text block boundary for widget placement.
|
|
39
|
+
var insertResolvedPos = newDoc.resolve(change.toB);
|
|
40
|
+
var blockEnd = change.toB;
|
|
41
|
+
for (var depth = insertResolvedPos.depth; depth >= 0; depth--) {
|
|
42
|
+
var node = insertResolvedPos.node(depth);
|
|
43
|
+
if (node.isTextblock) {
|
|
44
|
+
blockEnd = insertResolvedPos.start(depth) + node.nodeSize - 1;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Find the block node to render from the render doc at the render positions.
|
|
50
|
+
var renderResolvedPos = renderDoc.resolve(renderTo);
|
|
51
|
+
var renderBlockNode = null;
|
|
52
|
+
for (var _depth = renderResolvedPos.depth; _depth >= 0; _depth--) {
|
|
53
|
+
var _node = renderResolvedPos.node(_depth);
|
|
54
|
+
if (_node.isTextblock) {
|
|
55
|
+
renderBlockNode = _node;
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (!renderBlockNode) {
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
var isActive = activeIndexPos && change.fromB === activeIndexPos.from && change.toB === activeIndexPos.to;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* This will always be a block node as it's a textBlock-like node.
|
|
66
|
+
* We use div instead of span so we can add margins.
|
|
67
|
+
*/
|
|
68
|
+
var dom = document.createElement('div');
|
|
69
|
+
dom.setAttribute('data-testid', 'show-diff-granular-block-reference');
|
|
70
|
+
dom.style.setProperty('margin-top', "var(--ds-space-200, 16px)");
|
|
71
|
+
var nodeView = nodeViewSerializer.tryCreateNodeView(renderBlockNode);
|
|
72
|
+
if (nodeView) {
|
|
73
|
+
wrapBlockNodeView({
|
|
74
|
+
dom: dom,
|
|
75
|
+
nodeView: nodeView,
|
|
76
|
+
targetNode: renderBlockNode,
|
|
77
|
+
colorScheme: colorScheme,
|
|
78
|
+
intl: intl,
|
|
79
|
+
isActive: !!isActive,
|
|
80
|
+
isInserted: false
|
|
81
|
+
});
|
|
82
|
+
} else {
|
|
83
|
+
var serialized = nodeViewSerializer.serializeNode(renderBlockNode);
|
|
84
|
+
if (serialized && serialized instanceof HTMLElement) {
|
|
85
|
+
injectInnerWrapper({
|
|
86
|
+
node: serialized,
|
|
87
|
+
colorScheme: colorScheme,
|
|
88
|
+
isActive: !!isActive,
|
|
89
|
+
isInserted: false
|
|
90
|
+
});
|
|
91
|
+
dom.append(serialized);
|
|
92
|
+
} else if (serialized) {
|
|
93
|
+
dom.append(serialized);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (dom.childNodes.length === 0) {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
var decorations = [];
|
|
100
|
+
if (showIndicators) {
|
|
101
|
+
var leftAnchor = createLeftAnchorWidget({
|
|
102
|
+
doc: newDoc,
|
|
103
|
+
from: blockEnd,
|
|
104
|
+
diffId: diffId
|
|
105
|
+
});
|
|
106
|
+
dom.style.setProperty('anchor-name', "--".concat(buildAnchorDecorationKey({
|
|
107
|
+
diffId: diffId
|
|
108
|
+
})));
|
|
109
|
+
if (leftAnchor) {
|
|
110
|
+
decorations.push(leftAnchor);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
decorations.push(Decoration.widget(blockEnd, dom, buildDiffDecorationSpec({
|
|
114
|
+
decorationType: 'widget',
|
|
115
|
+
diffId: diffId,
|
|
116
|
+
// We want it to be as close to the granular diff as possible
|
|
117
|
+
side: -999
|
|
118
|
+
})));
|
|
119
|
+
return decorations;
|
|
120
|
+
};
|
|
@@ -1,116 +1,31 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
-
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
3
2
|
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; }
|
|
4
3
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
5
|
-
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
6
4
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
7
5
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
8
|
-
import { editingStyle, editingStyleExtended, editingStyleActive, editingStyleActiveExtended, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleUnbounded, deletedInlineContentStyleExtended } from './colorSchemes/standard';
|
|
9
|
-
import { traditionalInsertStyle, traditionalInsertStyleActive, getDeletedTraditionalInlineStyle, deletedTraditionalContentStyleUnbounded, deletedTraditionalContentStyleUnboundedActive } from './colorSchemes/traditional';
|
|
10
6
|
import { createLeftAnchorWidget } from './createAnchorDecorationWidgets';
|
|
11
7
|
import { createChangedRowDecorationWidgets } from './createChangedRowDecorationWidgets';
|
|
12
8
|
import { buildDiffDecorationSpec, buildAnchorDecorationKey } from './decorationKeys';
|
|
13
9
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
14
|
-
import { wrapBlockNodeView } from './utils/wrapBlockNodeView';
|
|
15
|
-
var getDeletedContentStyleUnbounded = function getDeletedContentStyleUnbounded(colorScheme) {
|
|
16
|
-
var isActive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
17
|
-
if (colorScheme === 'traditional' && isActive) {
|
|
18
|
-
return deletedTraditionalContentStyleUnboundedActive;
|
|
19
|
-
}
|
|
20
|
-
return colorScheme === 'traditional' ? deletedTraditionalContentStyleUnbounded : deletedContentStyleUnbounded;
|
|
21
|
-
};
|
|
22
|
-
var getInsertedContentStyle = function getInsertedContentStyle(colorScheme) {
|
|
23
|
-
var isActive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
24
|
-
if (colorScheme === 'traditional') {
|
|
25
|
-
if (isActive) {
|
|
26
|
-
return traditionalInsertStyleActive;
|
|
27
|
-
}
|
|
28
|
-
return traditionalInsertStyle;
|
|
29
|
-
}
|
|
30
|
-
if (isActive) {
|
|
31
|
-
return expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? editingStyleActiveExtended : editingStyleActive;
|
|
32
|
-
}
|
|
33
|
-
return expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) ? editingStyleExtended : editingStyle;
|
|
34
|
-
};
|
|
35
|
-
var getDeletedContentStyle = function getDeletedContentStyle(colorScheme) {
|
|
36
|
-
var isActive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
37
|
-
if (colorScheme === 'traditional') {
|
|
38
|
-
return getDeletedTraditionalInlineStyle(isActive);
|
|
39
|
-
}
|
|
40
|
-
// Merge into existing styles when cleaning up
|
|
41
|
-
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
42
|
-
if (isActive) {
|
|
43
|
-
return deletedContentStyleActive + deletedInlineContentStyleExtended;
|
|
44
|
-
}
|
|
45
|
-
return deletedContentStyleNew + deletedInlineContentStyleExtended;
|
|
46
|
-
}
|
|
47
|
-
if (isActive) {
|
|
48
|
-
return deletedContentStyleActive;
|
|
49
|
-
}
|
|
50
|
-
return expValEquals('platform_editor_enghealth_a11y_jan_fixes', 'isEnabled', true) ? deletedContentStyleNew : deletedContentStyle;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* CSS backgrounds don't work when applied to a wrapper around a paragraph, so
|
|
55
|
-
* the wrapper needs to be injected inside the node around the child content
|
|
56
|
-
*/
|
|
57
|
-
var injectInnerWrapper = function injectInnerWrapper(_ref) {
|
|
58
|
-
var node = _ref.node,
|
|
59
|
-
colorScheme = _ref.colorScheme,
|
|
60
|
-
isActive = _ref.isActive,
|
|
61
|
-
isInserted = _ref.isInserted;
|
|
62
|
-
var wrapper = document.createElement('span');
|
|
63
|
-
wrapper.setAttribute('style', isInserted ? getInsertedContentStyle(colorScheme, isActive) : getDeletedContentStyle(colorScheme, isActive));
|
|
64
|
-
_toConsumableArray(node.childNodes).forEach(function (child) {
|
|
65
|
-
var removedChild = node.removeChild(child);
|
|
66
|
-
wrapper.append(removedChild);
|
|
67
|
-
});
|
|
68
|
-
node.appendChild(wrapper);
|
|
69
|
-
return node;
|
|
70
|
-
};
|
|
71
|
-
var createContentWrapper = function createContentWrapper(colorScheme) {
|
|
72
|
-
var isActive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
73
|
-
var isInserted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
74
|
-
var wrapper = document.createElement('span');
|
|
75
|
-
var baseStyle = convertToInlineCss({
|
|
76
|
-
position: 'relative',
|
|
77
|
-
width: 'fit-content'
|
|
78
|
-
});
|
|
79
|
-
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
80
|
-
if (isInserted) {
|
|
81
|
-
wrapper.setAttribute('style', "".concat(baseStyle).concat(getInsertedContentStyle(colorScheme, isActive)));
|
|
82
|
-
} else {
|
|
83
|
-
wrapper.setAttribute('style', "".concat(baseStyle).concat(getDeletedContentStyle(colorScheme, isActive)));
|
|
84
|
-
var strikethrough = document.createElement('span');
|
|
85
|
-
strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colorScheme, isActive));
|
|
86
|
-
wrapper.append(strikethrough);
|
|
87
|
-
}
|
|
88
|
-
} else {
|
|
89
|
-
wrapper.setAttribute('style', "".concat(baseStyle).concat(getDeletedContentStyle(colorScheme, isActive)));
|
|
90
|
-
var _strikethrough = document.createElement('span');
|
|
91
|
-
_strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colorScheme, isActive));
|
|
92
|
-
wrapper.append(_strikethrough);
|
|
93
|
-
}
|
|
94
|
-
return wrapper;
|
|
95
|
-
};
|
|
10
|
+
import { wrapBlockNodeView, injectInnerWrapper, createContentWrapper } from './utils/wrapBlockNodeView';
|
|
96
11
|
|
|
97
12
|
/**
|
|
98
13
|
* This function is used to create a decoration widget to show content
|
|
99
14
|
* that is not in the current document.
|
|
100
15
|
*/
|
|
101
|
-
export var createNodeChangedDecorationWidget = function createNodeChangedDecorationWidget(
|
|
16
|
+
export var createNodeChangedDecorationWidget = function createNodeChangedDecorationWidget(_ref) {
|
|
102
17
|
var _slice$content, _slice$content2, _slice$content3, _slice$content$firstC;
|
|
103
|
-
var change =
|
|
104
|
-
doc =
|
|
105
|
-
nodeViewSerializer =
|
|
106
|
-
colorScheme =
|
|
107
|
-
newDoc =
|
|
108
|
-
intl =
|
|
109
|
-
activeIndexPos =
|
|
110
|
-
|
|
111
|
-
isInserted =
|
|
112
|
-
|
|
113
|
-
showIndicators =
|
|
18
|
+
var change = _ref.change,
|
|
19
|
+
doc = _ref.doc,
|
|
20
|
+
nodeViewSerializer = _ref.nodeViewSerializer,
|
|
21
|
+
colorScheme = _ref.colorScheme,
|
|
22
|
+
newDoc = _ref.newDoc,
|
|
23
|
+
intl = _ref.intl,
|
|
24
|
+
activeIndexPos = _ref.activeIndexPos,
|
|
25
|
+
_ref$isInserted = _ref.isInserted,
|
|
26
|
+
isInserted = _ref$isInserted === void 0 ? false : _ref$isInserted,
|
|
27
|
+
_ref$showIndicators = _ref.showIndicators,
|
|
28
|
+
showIndicators = _ref$showIndicators === void 0 ? false : _ref$showIndicators;
|
|
114
29
|
var slice = doc.slice(change.fromA, change.toA);
|
|
115
30
|
var shouldSkipDeletedEmptyParagraphDecoration = !isInserted && (slice === null || slice === void 0 || (_slice$content = slice.content) === null || _slice$content === void 0 ? void 0 : _slice$content.childCount) === 1 && (slice === null || slice === void 0 || (_slice$content2 = slice.content) === null || _slice$content2 === void 0 || (_slice$content2 = _slice$content2.firstChild) === null || _slice$content2 === void 0 ? void 0 : _slice$content2.type.name) === 'paragraph' && (slice === null || slice === void 0 || (_slice$content3 = slice.content) === null || _slice$content3 === void 0 || (_slice$content3 = _slice$content3.firstChild) === null || _slice$content3 === void 0 ? void 0 : _slice$content3.content.size) === 0;
|
|
116
31
|
// Widget decoration used for deletions as the content is not in the document
|
|
@@ -147,6 +62,32 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
147
62
|
|
|
148
63
|
// For non-table content, use the existing span wrapper approach
|
|
149
64
|
var dom = document.createElement('span');
|
|
65
|
+
// When mediaSingle nodes are rendered inside a widget decoration (e.g. as part of
|
|
66
|
+
// a replaced panel), the centering CSS (margin-left: 50%; transform: translateX(-50%))
|
|
67
|
+
// incorrectly applies because isNestedNode resolves to false (getPos returns 0).
|
|
68
|
+
// Observe DOM mutations and override the transform on .rich-media-item elements
|
|
69
|
+
// after React mounts to prevent the image from shifting outside its parent container.
|
|
70
|
+
var constrainMediaObserver;
|
|
71
|
+
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
72
|
+
constrainMediaObserver = new MutationObserver(function () {
|
|
73
|
+
var richMediaItems = dom.querySelectorAll('.rich-media-item');
|
|
74
|
+
richMediaItems.forEach(function (el) {
|
|
75
|
+
if (el instanceof HTMLElement) {
|
|
76
|
+
el.style.transform = 'none';
|
|
77
|
+
el.style.marginLeft = '0';
|
|
78
|
+
el.style.maxWidth = '100%';
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
if (richMediaItems.length > 0) {
|
|
82
|
+
var _constrainMediaObserv;
|
|
83
|
+
(_constrainMediaObserv = constrainMediaObserver) === null || _constrainMediaObserv === void 0 || _constrainMediaObserv.disconnect();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
constrainMediaObserver.observe(dom, {
|
|
87
|
+
childList: true,
|
|
88
|
+
subtree: true
|
|
89
|
+
});
|
|
90
|
+
}
|
|
150
91
|
var diffId = crypto.randomUUID();
|
|
151
92
|
var decorations = [];
|
|
152
93
|
|
|
@@ -267,13 +208,18 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
267
208
|
decorations.push(leftAnchor);
|
|
268
209
|
}
|
|
269
210
|
}
|
|
270
|
-
decorations.push(Decoration.widget(safeInsertPos, dom, buildDiffDecorationSpec(_objectSpread({
|
|
211
|
+
decorations.push(Decoration.widget(safeInsertPos, dom, _objectSpread(_objectSpread({}, buildDiffDecorationSpec(_objectSpread({
|
|
271
212
|
decorationType: 'widget',
|
|
272
213
|
diffId: diffId,
|
|
273
214
|
isActive: isActive
|
|
274
215
|
}, expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true) && {
|
|
275
216
|
side: -1
|
|
276
|
-
})))
|
|
217
|
+
}))), {}, {
|
|
218
|
+
destroy: function destroy() {
|
|
219
|
+
var _constrainMediaObserv2;
|
|
220
|
+
return (_constrainMediaObserv2 = constrainMediaObserver) === null || _constrainMediaObserv2 === void 0 ? void 0 : _constrainMediaObserv2.disconnect();
|
|
221
|
+
}
|
|
222
|
+
})));
|
|
277
223
|
|
|
278
224
|
// When a single block node is purely deleted at the very start of the doc (first child),
|
|
279
225
|
// the deleted widget decoration overlaps with the existing first child's decoration.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
1
2
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
3
|
import { trackChangesMessages } from '@atlaskit/editor-common/messages';
|
|
3
4
|
import { getBaseNodeTypeName } from '@atlaskit/editor-common/utils/node-type-utils';
|
|
4
5
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
5
|
-
import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlockExtended, editingStyleExtended, editingStyleActiveExtended, editingStyleNode, addedCellOverlayStyle, deletedCellOverlayStyle } from '../colorSchemes/standard';
|
|
6
|
-
import { deletedTraditionalBlockOutlineActive, deletedTraditionalBlockOutlineNew, deletedTraditionalBlockOutlineRoundedActive, deletedTraditionalBlockOutlineRoundedNew, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, deletedTraditionalStyleQuoteNodeActive, traditionalInsertStyle, traditionalInsertStyleActive, traditionalStyleNodeActive, traditionalStyleNodeNew, traditionalAddedCellOverlayStyleNew, deletedTraditionalCellOverlayStyle } from '../colorSchemes/traditional';
|
|
6
|
+
import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyle, deletedContentStyleActive, deletedContentStyleNew, deletedContentStyleUnbounded, deletedInlineContentStyleExtended, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlockExtended, editingStyleExtended, editingStyleActiveExtended, editingStyleNode, addedCellOverlayStyle, deletedCellOverlayStyle } from '../colorSchemes/standard';
|
|
7
|
+
import { deletedTraditionalBlockOutlineActive, deletedTraditionalBlockOutlineNew, deletedTraditionalBlockOutlineRoundedActive, deletedTraditionalBlockOutlineRoundedNew, deletedTraditionalContentStyleUnbounded, deletedTraditionalContentStyleUnboundedActive, getDeletedTraditionalInlineStyle, deletedTraditionalStyleQuoteNode, deletedTraditionalStyleQuoteNodeActive, traditionalInsertStyle, traditionalInsertStyleActive, traditionalStyleNodeActive, traditionalStyleNodeNew, traditionalAddedCellOverlayStyleNew, deletedTraditionalCellOverlayStyle } from '../colorSchemes/traditional';
|
|
7
8
|
var lozengeStyle = convertToInlineCss({
|
|
8
9
|
display: 'inline-flex',
|
|
9
10
|
boxSizing: 'border-box',
|
|
@@ -545,4 +546,80 @@ export var wrapBlockNodeView = function wrapBlockNodeView(_ref0) {
|
|
|
545
546
|
});
|
|
546
547
|
}
|
|
547
548
|
}
|
|
549
|
+
};
|
|
550
|
+
var getDeletedContentStyleUnbounded = function getDeletedContentStyleUnbounded(colorScheme) {
|
|
551
|
+
var isActive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
552
|
+
if (colorScheme === 'traditional' && isActive) {
|
|
553
|
+
return deletedTraditionalContentStyleUnboundedActive;
|
|
554
|
+
}
|
|
555
|
+
return colorScheme === 'traditional' ? deletedTraditionalContentStyleUnbounded : deletedContentStyleUnbounded;
|
|
556
|
+
};
|
|
557
|
+
var getInsertedContentStyle = function getInsertedContentStyle(colorScheme) {
|
|
558
|
+
var isActive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
559
|
+
if (colorScheme === 'traditional') {
|
|
560
|
+
return isActive ? traditionalInsertStyleActive : traditionalInsertStyle;
|
|
561
|
+
}
|
|
562
|
+
if (isActive) {
|
|
563
|
+
return editingStyleActiveExtended;
|
|
564
|
+
}
|
|
565
|
+
return editingStyleExtended;
|
|
566
|
+
};
|
|
567
|
+
var getDeletedContentStyle = function getDeletedContentStyle(colorScheme) {
|
|
568
|
+
var isActive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
569
|
+
if (colorScheme === 'traditional') {
|
|
570
|
+
return getDeletedTraditionalInlineStyle(isActive);
|
|
571
|
+
}
|
|
572
|
+
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
573
|
+
return (isActive ? deletedContentStyleActive : deletedContentStyleNew) + deletedInlineContentStyleExtended;
|
|
574
|
+
}
|
|
575
|
+
return isActive ? deletedContentStyleActive : deletedContentStyleNew;
|
|
576
|
+
};
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Injects a styled inner wrapper span around the children of a block node element.
|
|
580
|
+
* CSS backgrounds don't work when applied to a wrapper around a paragraph, so
|
|
581
|
+
* the wrapper needs to be injected inside the node around the child content.
|
|
582
|
+
*/
|
|
583
|
+
export var injectInnerWrapper = function injectInnerWrapper(_ref1) {
|
|
584
|
+
var node = _ref1.node,
|
|
585
|
+
colorScheme = _ref1.colorScheme,
|
|
586
|
+
isActive = _ref1.isActive,
|
|
587
|
+
isInserted = _ref1.isInserted;
|
|
588
|
+
var wrapper = document.createElement('span');
|
|
589
|
+
wrapper.setAttribute('style', isInserted ? getInsertedContentStyle(colorScheme, isActive) : getDeletedContentStyle(colorScheme, isActive));
|
|
590
|
+
_toConsumableArray(node.childNodes).forEach(function (child) {
|
|
591
|
+
var removedChild = node.removeChild(child);
|
|
592
|
+
wrapper.append(removedChild);
|
|
593
|
+
});
|
|
594
|
+
node.appendChild(wrapper);
|
|
595
|
+
return node;
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Creates a styled span wrapper for inline content within a change decoration.
|
|
600
|
+
*/
|
|
601
|
+
export var createContentWrapper = function createContentWrapper(colorScheme) {
|
|
602
|
+
var isActive = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
603
|
+
var isInserted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
604
|
+
var wrapper = document.createElement('span');
|
|
605
|
+
var baseStyle = convertToInlineCss({
|
|
606
|
+
position: 'relative',
|
|
607
|
+
width: 'fit-content'
|
|
608
|
+
});
|
|
609
|
+
if (expValEquals('platform_editor_diff_plugin_extended', 'isEnabled', true)) {
|
|
610
|
+
if (isInserted) {
|
|
611
|
+
wrapper.setAttribute('style', "".concat(baseStyle).concat(getInsertedContentStyle(colorScheme, isActive)));
|
|
612
|
+
} else {
|
|
613
|
+
wrapper.setAttribute('style', "".concat(baseStyle).concat(getDeletedContentStyle(colorScheme, isActive)));
|
|
614
|
+
var strikethrough = document.createElement('span');
|
|
615
|
+
strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colorScheme, isActive));
|
|
616
|
+
wrapper.append(strikethrough);
|
|
617
|
+
}
|
|
618
|
+
} else {
|
|
619
|
+
wrapper.setAttribute('style', "".concat(baseStyle).concat(getDeletedContentStyle(colorScheme, isActive)));
|
|
620
|
+
var _strikethrough = document.createElement('span');
|
|
621
|
+
_strikethrough.setAttribute('style', getDeletedContentStyleUnbounded(colorScheme, isActive));
|
|
622
|
+
wrapper.append(_strikethrough);
|
|
623
|
+
}
|
|
624
|
+
return wrapper;
|
|
548
625
|
};
|
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
import { type Change } from 'prosemirror-changeset';
|
|
2
2
|
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
3
3
|
import type { Step } from '@atlaskit/editor-prosemirror/transform';
|
|
4
|
+
type StepChanges = {
|
|
5
|
+
changes: Change[];
|
|
6
|
+
isGranular: boolean;
|
|
7
|
+
};
|
|
4
8
|
export declare const diffBySteps: (originalDoc: PMNode, steps: Step[]) => Change[];
|
|
9
|
+
/**
|
|
10
|
+
* A fork of `diffBySteps` that returns changes grouped per step, rather than as a flat list.
|
|
11
|
+
*
|
|
12
|
+
* Why forked rather than refactoring `diffBySteps`:
|
|
13
|
+
* - `diffBySteps` returns a flat `Change[]` and is consumed by the existing decoration path.
|
|
14
|
+
* Changing its return shape would require threading per-step metadata through all callers,
|
|
15
|
+
* adding complexity to a stable code path.
|
|
16
|
+
* - The per-step grouping is only needed for the `platform_editor_diff_granular_extended` gate,
|
|
17
|
+
* where we need to know how many granular changes a single step produced in order to decide
|
|
18
|
+
* whether to suppress deleted decorations (threshold: > 3 granular changes per step).
|
|
19
|
+
* - Keeping the two functions separate means each has a clear, focused contract and neither
|
|
20
|
+
* accumulates the other's concerns. Shared logic (mapping helpers, `mergeOverlappingByNewDocRange`,
|
|
21
|
+
* `shouldCheckGranularDiff`, etc.) is already extracted and reused by both.
|
|
22
|
+
*/
|
|
23
|
+
export declare const getStepChanges: (originalDoc: PMNode, steps: Step[]) => StepChanges[];
|
|
24
|
+
export {};
|
|
@@ -26,5 +26,6 @@ export declare const editingStyleRuleNode: string;
|
|
|
26
26
|
export declare const editingStyleNode: string;
|
|
27
27
|
export declare const editingStyleCardBlockNode: string;
|
|
28
28
|
export declare const standardDecorationMarkerVariable: string;
|
|
29
|
+
export declare const deletedDecorationMarkerVariable: string;
|
|
29
30
|
export declare const addedCellOverlayStyle: string;
|
|
30
31
|
export declare const deletedCellOverlayStyle: string;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Change } from 'prosemirror-changeset';
|
|
2
|
+
import type { IntlShape } from 'react-intl';
|
|
3
|
+
import type { Node as PMNode } from '@atlaskit/editor-prosemirror/model';
|
|
4
|
+
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
5
|
+
import type { ColorScheme } from '../../showDiffPluginType';
|
|
6
|
+
import type { NodeViewSerializer } from '../NodeViewSerializer';
|
|
7
|
+
/**
|
|
8
|
+
* Creates a single block widget that renders a reference text block content
|
|
9
|
+
* beneath a granular diff set, for reference when deleted content is hidden.
|
|
10
|
+
*
|
|
11
|
+
* Since granular diffing only applies to singular isTextBlock=true nodes, this
|
|
12
|
+
* widget always renders exactly one block node and does not need the slice/fragment
|
|
13
|
+
* complexity of createNodeChangedDecorationWidget.
|
|
14
|
+
*
|
|
15
|
+
* Resolves which doc and positions to render based on isInverted:
|
|
16
|
+
* - !isInverted: renders originalDoc at A-side positions (what was there before)
|
|
17
|
+
* - isInverted: renders newDoc at B-side positions (the current/new content)
|
|
18
|
+
*
|
|
19
|
+
* The widget is always inserted at the B-side block boundary in newDoc since
|
|
20
|
+
* ProseMirror decorations are always anchored against the live (new) document.
|
|
21
|
+
*/
|
|
22
|
+
export declare const createGranularBlockReferenceWidget: ({ change, originalDoc, newDoc, isInverted, nodeViewSerializer, colorScheme, intl, activeIndexPos, diffId, showIndicators, }: {
|
|
23
|
+
activeIndexPos?: {
|
|
24
|
+
from: number;
|
|
25
|
+
to: number;
|
|
26
|
+
};
|
|
27
|
+
change: Change;
|
|
28
|
+
colorScheme?: ColorScheme;
|
|
29
|
+
diffId: string;
|
|
30
|
+
intl: IntlShape;
|
|
31
|
+
isInverted: boolean;
|
|
32
|
+
newDoc: PMNode;
|
|
33
|
+
nodeViewSerializer: NodeViewSerializer;
|
|
34
|
+
originalDoc: PMNode;
|
|
35
|
+
showIndicators?: boolean;
|
|
36
|
+
}) => Decoration[];
|