@atlaskit/editor-plugin-show-diff 16.0.14 → 16.0.17
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 +29 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +1 -1
- package/dist/cjs/pm-plugins/decorations/createAnchorDecorationWidgets.js +19 -13
- package/dist/cjs/pm-plugins/decorations/createBlockChangedDecoration.js +2 -1
- package/dist/cjs/pm-plugins/decorations/createChangedRowDecorationWidgets.js +94 -28
- package/dist/cjs/pm-plugins/decorations/createInlineChangedDecoration.js +2 -1
- package/dist/cjs/pm-plugins/decorations/createNodeChangedDecorationWidget.js +14 -1
- package/dist/cjs/pm-plugins/decorations/decorationKeys.js +12 -2
- package/dist/cjs/pm-plugins/main.js +2 -2
- package/dist/cjs/pm-plugins/scrollToDiff.js +20 -0
- package/dist/cjs/ui/ContributorTag/buildContributorTagDom.js +5 -4
- package/dist/cjs/ui/IndicatorBar/IndicatorBar.js +1 -1
- package/dist/cjs/ui/IndicatorBar/IndicatorBarContentComponent.js +1 -1
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +1 -1
- package/dist/es2019/pm-plugins/decorations/createAnchorDecorationWidgets.js +7 -3
- package/dist/es2019/pm-plugins/decorations/createBlockChangedDecoration.js +4 -3
- package/dist/es2019/pm-plugins/decorations/createChangedRowDecorationWidgets.js +73 -13
- package/dist/es2019/pm-plugins/decorations/createInlineChangedDecoration.js +3 -2
- package/dist/es2019/pm-plugins/decorations/createNodeChangedDecorationWidget.js +15 -2
- package/dist/es2019/pm-plugins/decorations/decorationKeys.js +10 -0
- package/dist/es2019/pm-plugins/main.js +2 -2
- package/dist/es2019/pm-plugins/scrollToDiff.js +21 -3
- package/dist/es2019/ui/ContributorTag/buildContributorTagDom.js +5 -4
- package/dist/es2019/ui/IndicatorBar/IndicatorBar.js +1 -1
- package/dist/es2019/ui/IndicatorBar/IndicatorBarContentComponent.js +1 -1
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +1 -1
- package/dist/esm/pm-plugins/decorations/createAnchorDecorationWidgets.js +19 -13
- package/dist/esm/pm-plugins/decorations/createBlockChangedDecoration.js +3 -2
- package/dist/esm/pm-plugins/decorations/createChangedRowDecorationWidgets.js +95 -29
- package/dist/esm/pm-plugins/decorations/createInlineChangedDecoration.js +3 -2
- package/dist/esm/pm-plugins/decorations/createNodeChangedDecorationWidget.js +15 -2
- package/dist/esm/pm-plugins/decorations/decorationKeys.js +10 -0
- package/dist/esm/pm-plugins/main.js +2 -2
- package/dist/esm/pm-plugins/scrollToDiff.js +21 -2
- package/dist/esm/ui/ContributorTag/buildContributorTagDom.js +5 -4
- package/dist/esm/ui/IndicatorBar/IndicatorBar.js +1 -1
- package/dist/esm/ui/IndicatorBar/IndicatorBarContentComponent.js +1 -1
- package/dist/types/pm-plugins/decorations/createChangedRowDecorationWidgets.d.ts +6 -1
- package/dist/types/pm-plugins/decorations/decorationKeys.d.ts +9 -0
- package/dist/types/pm-plugins/scrollToDiff.d.ts +5 -1
- package/dist/types/showDiffPluginType.d.ts +2 -0
- package/dist/types/ui/ContributorTag/buildContributorTagDom.d.ts +4 -4
- package/package.json +4 -3
- package/dist/cjs/pm-plugins/areDocsEqualByBlockStructureAndText.js +0 -55
- package/dist/es2019/pm-plugins/areDocsEqualByBlockStructureAndText.js +0 -50
- package/dist/esm/pm-plugins/areDocsEqualByBlockStructureAndText.js +0 -50
- package/dist/types/pm-plugins/areDocsEqualByBlockStructureAndText.d.ts +0 -12
|
@@ -17,7 +17,8 @@ import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildDel
|
|
|
17
17
|
import { colorSchemeRegistry, getLegacyColorScheme } from './colorSchemes/schemes';
|
|
18
18
|
import { createLeftAnchorWidget } from './createAnchorDecorationWidgets';
|
|
19
19
|
import { resolveCellOverlayStyleLegacy, resolveDeletedRowStyleLegacy } from './createChangedRowDecorationWidgets.styles.legacy';
|
|
20
|
-
import {
|
|
20
|
+
import { createContributorTagWidget, isContributorTagWidgetEnabled } from './createContributorTagWidget';
|
|
21
|
+
import { AnchorTypeKey, buildAnchorDecorationKey, buildDiffDecorationSpec, scrollMarginTopValue } from './decorationKeys';
|
|
21
22
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
22
23
|
import { applyCellEdgeAttrs, getRowCellEdgeAttrs, getTableTopAndBottomCellEdgeAttrs } from './utils/tableCellEdgeAttrs';
|
|
23
24
|
/**
|
|
@@ -98,20 +99,40 @@ var extractChangedRows = function extractChangedRows(_ref) {
|
|
|
98
99
|
}
|
|
99
100
|
});
|
|
100
101
|
|
|
101
|
-
// Filter changes that never truly got deleted
|
|
102
|
+
// Filter changes that never truly got deleted. Compare the number of equivalent rows rather
|
|
103
|
+
// than only checking whether one still exists: deleting two of three identical empty rows should
|
|
104
|
+
// retain two changed rows even though the third remains in the new table.
|
|
105
|
+
var equivalentRowDeletionCounts = [];
|
|
102
106
|
return changedRows.filter(function (changedRow) {
|
|
103
107
|
// A replacement leaves every sibling row in place, so asking "does this row still exist
|
|
104
108
|
// ANYWHERE in the new table?" can drop a genuinely rewritten row that happens to match a
|
|
105
|
-
// sibling. Compare it against the row at the same index instead.
|
|
106
|
-
// whole-table `some()`: their indices shift, so an index comparison would let every
|
|
107
|
-
// surviving row through and draw a widget for each one.
|
|
109
|
+
// sibling. Compare it against the row at the same index instead.
|
|
108
110
|
if (handleRowReplacement) {
|
|
109
111
|
var counterpart = tableNew.node.maybeChild(changedRow.rowIndex);
|
|
110
112
|
return !counterpart || !areNodesEqualIgnoreAttrs(counterpart, changedRow.rowNode);
|
|
111
113
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
var deletionCount = equivalentRowDeletionCounts.find(function (_ref2) {
|
|
115
|
+
var rowNode = _ref2.rowNode;
|
|
116
|
+
return areNodesEqualIgnoreAttrs(rowNode, changedRow.rowNode);
|
|
114
117
|
});
|
|
118
|
+
if (!deletionCount) {
|
|
119
|
+
var oldRowCount = tableOld.node.children.filter(function (oldRow) {
|
|
120
|
+
return areNodesEqualIgnoreAttrs(oldRow, changedRow.rowNode);
|
|
121
|
+
}).length;
|
|
122
|
+
var newRowCount = tableNew.node.children.filter(function (newRow) {
|
|
123
|
+
return areNodesEqualIgnoreAttrs(newRow, changedRow.rowNode);
|
|
124
|
+
}).length;
|
|
125
|
+
deletionCount = {
|
|
126
|
+
remaining: Math.max(0, oldRowCount - newRowCount),
|
|
127
|
+
rowNode: changedRow.rowNode
|
|
128
|
+
};
|
|
129
|
+
equivalentRowDeletionCounts.push(deletionCount);
|
|
130
|
+
}
|
|
131
|
+
if (deletionCount.remaining === 0) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
deletionCount.remaining--;
|
|
135
|
+
return true;
|
|
115
136
|
});
|
|
116
137
|
};
|
|
117
138
|
|
|
@@ -156,6 +177,9 @@ var createChangedRowDOM = function createChangedRowDOM(rowNode, cellEdgeAttrs, n
|
|
|
156
177
|
// is ADDED content, so it must not claim the "deleted" testid — page models match that as
|
|
157
178
|
// removed content (same reasoning as `createTableCellContentWidgets`).
|
|
158
179
|
tr.setAttribute('data-testid', isExtendedEnabled(diffType) && isInserted && fg('platform_editor_ai_show_diff_patch_1') ? 'show-diff-changed-row' : 'show-diff-deleted-row');
|
|
180
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
181
|
+
tr.style.setProperty('scroll-margin-top', scrollMarginTopValue);
|
|
182
|
+
}
|
|
159
183
|
|
|
160
184
|
// Serialize each cell in the row
|
|
161
185
|
var cellIndex = 0;
|
|
@@ -194,11 +218,11 @@ var createChangedRowDOM = function createChangedRowDOM(rowNode, cellEdgeAttrs, n
|
|
|
194
218
|
/**
|
|
195
219
|
* Expands a diff to include whole changed rows when table rows are affected
|
|
196
220
|
*/
|
|
197
|
-
var expandDiffForChangedRows = function expandDiffForChangedRows(
|
|
198
|
-
var changes =
|
|
199
|
-
originalDoc =
|
|
200
|
-
newDoc =
|
|
201
|
-
diffType =
|
|
221
|
+
var expandDiffForChangedRows = function expandDiffForChangedRows(_ref3) {
|
|
222
|
+
var changes = _ref3.changes,
|
|
223
|
+
originalDoc = _ref3.originalDoc,
|
|
224
|
+
newDoc = _ref3.newDoc,
|
|
225
|
+
diffType = _ref3.diffType;
|
|
202
226
|
var rowInfo = [];
|
|
203
227
|
var _iterator = _createForOfIteratorHelper(changes),
|
|
204
228
|
_step;
|
|
@@ -227,17 +251,22 @@ var expandDiffForChangedRows = function expandDiffForChangedRows(_ref2) {
|
|
|
227
251
|
/**
|
|
228
252
|
* Main function to handle deleted rows - computes diff and creates decorations
|
|
229
253
|
*/
|
|
230
|
-
export var createChangedRowDecorationWidgets = function createChangedRowDecorationWidgets(
|
|
231
|
-
var
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
254
|
+
export var createChangedRowDecorationWidgets = function createChangedRowDecorationWidgets(_ref4) {
|
|
255
|
+
var attributionKey = _ref4.attributionKey,
|
|
256
|
+
changes = _ref4.changes,
|
|
257
|
+
originalDoc = _ref4.originalDoc,
|
|
258
|
+
newDoc = _ref4.newDoc,
|
|
259
|
+
nodeViewSerializer = _ref4.nodeViewSerializer,
|
|
260
|
+
colorScheme = _ref4.colorScheme,
|
|
261
|
+
isActive = _ref4.isActive,
|
|
262
|
+
_ref4$isInserted = _ref4.isInserted,
|
|
263
|
+
isInserted = _ref4$isInserted === void 0 ? false : _ref4$isInserted,
|
|
264
|
+
diffType = _ref4.diffType,
|
|
265
|
+
_ref4$showIndicators = _ref4.showIndicators,
|
|
266
|
+
showIndicators = _ref4$showIndicators === void 0 ? false : _ref4$showIndicators,
|
|
267
|
+
_ref4$showContributor = _ref4.showContributorTags,
|
|
268
|
+
showContributorTags = _ref4$showContributor === void 0 ? false : _ref4$showContributor,
|
|
269
|
+
tagMountContext = _ref4.tagMountContext;
|
|
241
270
|
// First, expand the changes to include complete deleted rows
|
|
242
271
|
var changedRows = expandDiffForChangedRows({
|
|
243
272
|
changes: changes.filter(function (change) {
|
|
@@ -254,8 +283,12 @@ export var createChangedRowDecorationWidgets = function createChangedRowDecorati
|
|
|
254
283
|
var safeInsertPos = findSafeInsertPos(newDoc, changedRow.fromB - 1,
|
|
255
284
|
// -1 to find the first safe position from the table
|
|
256
285
|
originalDoc.slice(changedRow.fromA, changedRow.toA));
|
|
257
|
-
|
|
286
|
+
|
|
287
|
+
// Stable while contributor tags are enabled so a decoration recalculation preserves the tag's
|
|
288
|
+
// identity and controller state.
|
|
289
|
+
var diffId = showContributorTags ? "widget-row-".concat(changedRow.fromA, "-").concat(changedRow.toA) : crypto.randomUUID();
|
|
258
290
|
var decorations = [];
|
|
291
|
+
var rowAnchorNames = [];
|
|
259
292
|
|
|
260
293
|
// `IndicatorBarContentComponent` renders a bar for every widget descriptor and anchors its
|
|
261
294
|
// top and bottom to `anchor-<diffId>`. Without an element carrying that anchor name the bar
|
|
@@ -263,9 +296,9 @@ export var createChangedRowDecorationWidgets = function createChangedRowDecorati
|
|
|
263
296
|
// bar covers only the row being changed. `createNodeChangedDecorationWidget` sets the same
|
|
264
297
|
// property on its own widget DOM for non-table content; this path returns before reaching it.
|
|
265
298
|
if (showIndicators && isExtendedEnabled(diffType) && fg('platform_editor_ai_show_diff_patch_1')) {
|
|
266
|
-
|
|
299
|
+
rowAnchorNames.push(buildAnchorDecorationKey({
|
|
267
300
|
diffId: diffId
|
|
268
|
-
}))
|
|
301
|
+
}));
|
|
269
302
|
|
|
270
303
|
// A table's content can extend past the doc margin, so the bar also needs a left anchor
|
|
271
304
|
// measured against the table itself or it is clipped once the table is resized.
|
|
@@ -278,14 +311,47 @@ export var createChangedRowDecorationWidgets = function createChangedRowDecorati
|
|
|
278
311
|
decorations.push(leftAnchor);
|
|
279
312
|
}
|
|
280
313
|
}
|
|
281
|
-
|
|
314
|
+
var tagAnchorName = showContributorTags && isContributorTagWidgetEnabled() ? buildAnchorDecorationKey({
|
|
315
|
+
diffId: diffId,
|
|
316
|
+
anchorType: AnchorTypeKey.tag
|
|
317
|
+
}) : undefined;
|
|
318
|
+
var tagWidget = tagAnchorName ? createContributorTagWidget({
|
|
319
|
+
anchorAtRangeStart: true,
|
|
320
|
+
anchorName: tagAnchorName,
|
|
321
|
+
diffId: diffId,
|
|
322
|
+
doc: newDoc,
|
|
323
|
+
from: safeInsertPos,
|
|
324
|
+
mountContext: tagMountContext,
|
|
325
|
+
to: safeInsertPos
|
|
326
|
+
}) : undefined;
|
|
327
|
+
if (tagAnchorName) {
|
|
328
|
+
// The tag host is a separate, table-safe widget. CSS anchor positioning aligns it to this
|
|
329
|
+
// synthetic row without placing non-cell DOM inside the `<tr>` or inheriting its deletion
|
|
330
|
+
// opacity and strikethrough.
|
|
331
|
+
rowAnchorNames.push(tagAnchorName);
|
|
332
|
+
}
|
|
333
|
+
if (rowAnchorNames.length > 0) {
|
|
334
|
+
rowDOM.style.setProperty('anchor-name', rowAnchorNames.map(function (anchorName) {
|
|
335
|
+
return "--".concat(anchorName);
|
|
336
|
+
}).join(', '));
|
|
337
|
+
}
|
|
338
|
+
if (tagWidget) {
|
|
339
|
+
// Lets the contributor tag reveal when any part of the deleted row is hovered.
|
|
340
|
+
rowDOM.setAttribute('data-diff-id', diffId);
|
|
341
|
+
}
|
|
342
|
+
var rowWidget = Decoration.widget(safeInsertPos, rowDOM, _objectSpread({}, buildDiffDecorationSpec({
|
|
343
|
+
attributionKey: tagWidget ? attributionKey : undefined,
|
|
282
344
|
colorScheme: colorScheme,
|
|
283
345
|
decorationType: 'widget',
|
|
284
346
|
diffId: diffId,
|
|
285
|
-
isActive:
|
|
347
|
+
isActive: isActive,
|
|
286
348
|
isInserted: isInserted,
|
|
287
349
|
diffType: diffType
|
|
288
|
-
})))
|
|
350
|
+
})));
|
|
351
|
+
decorations.push(rowWidget);
|
|
352
|
+
if (tagWidget) {
|
|
353
|
+
decorations.push(tagWidget);
|
|
354
|
+
}
|
|
289
355
|
return decorations;
|
|
290
356
|
});
|
|
291
357
|
};
|
|
@@ -5,6 +5,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
5
5
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
6
6
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
7
7
|
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
8
|
+
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
8
9
|
import { CONTRIBUTOR_TAG_Z_INDEX } from '../../ui/ContributorTag/buildContributorTagDom';
|
|
9
10
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
10
11
|
import { isEmptyParagraphSlice } from '../utils/isEmptyParagraphSlice';
|
|
@@ -13,7 +14,7 @@ import { colorSchemeRegistry, getLegacyColorScheme } from './colorSchemes/scheme
|
|
|
13
14
|
import { createInlineIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
|
|
14
15
|
import { createContributorTagWidget, isContributorTagWidgetEnabled } from './createContributorTagWidget';
|
|
15
16
|
import { getAtomicInlineNodeClassNameLegacy, resolveInlineChangedStyleLegacy } from './createInlineChangedDecoration.styles.legacy';
|
|
16
|
-
import { buildDiffDecorationSpec } from './decorationKeys';
|
|
17
|
+
import { buildDiffDecorationSpec, scrollMarginTopStyle } from './decorationKeys';
|
|
17
18
|
import { REVEAL_ATTR, resolveRevealStyle } from './revealStyles';
|
|
18
19
|
var displayNoneStyle = convertToInlineCss({
|
|
19
20
|
display: 'none'
|
|
@@ -208,7 +209,7 @@ export var createInlineChangedDecoration = function createInlineChangedDecoratio
|
|
|
208
209
|
diffId: diffId,
|
|
209
210
|
mountContext: tagMountContext
|
|
210
211
|
}) : undefined;
|
|
211
|
-
var inlineStyle = [style, atomicInlineAttrs === null || atomicInlineAttrs === void 0 ? void 0 : atomicInlineAttrs.styleSuffix, tagWidget ? stackBelowContributorTagStyle : undefined].filter(Boolean).join('');
|
|
212
|
+
var inlineStyle = [style, atomicInlineAttrs === null || atomicInlineAttrs === void 0 ? void 0 : atomicInlineAttrs.styleSuffix, tagWidget ? stackBelowContributorTagStyle : undefined, fg('platform_editor_ai_show_diff_patch_1') ? scrollMarginTopStyle : undefined].filter(Boolean).join('');
|
|
212
213
|
var decorations = [Decoration.inline(change.fromB, change.toB, _objectSpread(_objectSpread(_objectSpread({
|
|
213
214
|
style: inlineStyle
|
|
214
215
|
}, atomicInlineAttrs && {
|
|
@@ -8,7 +8,7 @@ import { isEmptyParagraphSlice } from '../utils/isEmptyParagraphSlice';
|
|
|
8
8
|
import { createLeftAnchorWidget } from './createAnchorDecorationWidgets';
|
|
9
9
|
import { createChangedRowDecorationWidgets } from './createChangedRowDecorationWidgets';
|
|
10
10
|
import { createContributorTagHost, unmountContributorTag } from './createContributorTagWidget';
|
|
11
|
-
import { buildDiffDecorationSpec, buildAnchorDecorationKey } from './decorationKeys';
|
|
11
|
+
import { buildDiffDecorationSpec, buildAnchorDecorationKey, scrollMarginTopValue } from './decorationKeys';
|
|
12
12
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
13
13
|
import { wrapBlockNodeView, injectInnerWrapper, createContentWrapper } from './utils/wrapBlockNodeView';
|
|
14
14
|
var isHeadingLevel = function isHeadingLevel(level) {
|
|
@@ -73,6 +73,9 @@ var createTableCellContentWidgets = function createTableCellContentWidgets(_ref)
|
|
|
73
73
|
// This helper only runs for added content, so use the "changed" testid — not
|
|
74
74
|
// "deleted", which page models match as removed content.
|
|
75
75
|
dom.setAttribute('data-testid', 'show-diff-changed-decoration');
|
|
76
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
77
|
+
dom.style.setProperty('scroll-margin-top', scrollMarginTopValue);
|
|
78
|
+
}
|
|
76
79
|
|
|
77
80
|
// Skip findSafeInsertPos: it walks forward to a schema-valid cell-insert point
|
|
78
81
|
// and pushes the widget into the next cell. `targetPos` is the correct spot.
|
|
@@ -159,16 +162,20 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
159
162
|
}
|
|
160
163
|
if (isTableRowContent) {
|
|
161
164
|
return createChangedRowDecorationWidgets({
|
|
165
|
+
attributionKey: attributionKey,
|
|
162
166
|
changes: [change],
|
|
163
167
|
originalDoc: doc,
|
|
164
168
|
newDoc: newDoc,
|
|
165
169
|
nodeViewSerializer: nodeViewSerializer,
|
|
166
170
|
colorScheme: colorScheme,
|
|
171
|
+
isActive: isActive,
|
|
167
172
|
isInserted: isInserted,
|
|
168
173
|
diffType: diffType,
|
|
169
174
|
// Needed for the row's own indicator anchor; this path returns before the
|
|
170
175
|
// `anchor-name` assignment further down.
|
|
171
|
-
showIndicators: showIndicators
|
|
176
|
+
showIndicators: showIndicators,
|
|
177
|
+
showContributorTags: showContributorTags,
|
|
178
|
+
tagMountContext: tagMountContext
|
|
172
179
|
});
|
|
173
180
|
}
|
|
174
181
|
var serializer = nodeViewSerializer;
|
|
@@ -345,6 +352,9 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
345
352
|
}
|
|
346
353
|
});
|
|
347
354
|
dom.setAttribute('data-testid', 'show-diff-deleted-decoration');
|
|
355
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
356
|
+
dom.style.setProperty('scroll-margin-top', scrollMarginTopValue);
|
|
357
|
+
}
|
|
348
358
|
|
|
349
359
|
// Needed even when the indicator bar is off, because a contributor tag also anchors against the
|
|
350
360
|
// widget.
|
|
@@ -424,6 +434,9 @@ export var createNodeChangedDecorationWidget = function createNodeChangedDecorat
|
|
|
424
434
|
defaultSpacer.dataset.testid = 'show-diff-default-margin-spacer';
|
|
425
435
|
defaultSpacer.style.display = 'block';
|
|
426
436
|
defaultSpacer.style.marginTop = "var(--ds-space-100, 8px)";
|
|
437
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
438
|
+
defaultSpacer.style.setProperty('scroll-margin-top', scrollMarginTopValue);
|
|
439
|
+
}
|
|
427
440
|
decorations.push(Decoration.widget(safeInsertPos, defaultSpacer, _objectSpread({}, buildDiffDecorationSpec({
|
|
428
441
|
colorScheme: colorScheme,
|
|
429
442
|
decorationType: 'widget',
|
|
@@ -12,6 +12,16 @@ export var DecorationFamily = {
|
|
|
12
12
|
anchor: 'anchor',
|
|
13
13
|
contributorTag: 'contributor-tag'
|
|
14
14
|
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Navigation measures the target table header and writes this variable on the
|
|
18
|
+
* editor root immediately before scrolling. Diff decorations inherit it, so
|
|
19
|
+
* native scrolling leaves room for the header without DOM mutation on the
|
|
20
|
+
* ProseMirror-rendered suggestion.
|
|
21
|
+
*/
|
|
22
|
+
export var SCROLL_TARGET_MARGIN_CSS_PROPERTY = '--ak-editor-diff-additional-margin';
|
|
23
|
+
export var scrollMarginTopValue = "calc(".concat("var(--ds-space-400, 32px)", " + var(", SCROLL_TARGET_MARGIN_CSS_PROPERTY, ", 0px))");
|
|
24
|
+
export var scrollMarginTopStyle = "scroll-margin-top: ".concat(scrollMarginTopValue, ";");
|
|
15
25
|
export var AnchorTypeKey = {
|
|
16
26
|
from: 'from',
|
|
17
27
|
to: 'to',
|
|
@@ -251,7 +251,7 @@ export var createPlugin = function createPlugin(config, getIntl, api, onEditorVi
|
|
|
251
251
|
if (pluginState !== null && pluginState !== void 0 && pluginState.scrollIntoView && isExtendedEnabled(pluginState === null || pluginState === void 0 ? void 0 : pluginState.diffType)) {
|
|
252
252
|
var _cancelPendingScrollT;
|
|
253
253
|
(_cancelPendingScrollT = cancelPendingScrollToDecoration) === null || _cancelPendingScrollT === void 0 || _cancelPendingScrollT();
|
|
254
|
-
cancelPendingScrollToDecoration = scrollToDecoration(view, getScrollableDecorations(pluginState.decorations, view.state.doc, pluginState === null || pluginState === void 0 ? void 0 : pluginState.diffType));
|
|
254
|
+
cancelPendingScrollToDecoration = scrollToDecoration(view, getScrollableDecorations(pluginState.decorations, view.state.doc, pluginState === null || pluginState === void 0 ? void 0 : pluginState.diffType), undefined, api);
|
|
255
255
|
|
|
256
256
|
// Reset the flag so we don't scroll again on subsequent updates
|
|
257
257
|
view.dispatch(view.state.tr.setMeta(showDiffPluginKey, {
|
|
@@ -272,7 +272,7 @@ export var createPlugin = function createPlugin(config, getIntl, api, onEditorVi
|
|
|
272
272
|
// avoid a circular dependency; expand picks up the meta if loaded (no-op if not).
|
|
273
273
|
api === null || api === void 0 || api.core.actions.execute(toggleExpandRange(activeDecoration.from, activeDecoration.to, true));
|
|
274
274
|
}
|
|
275
|
-
cancelPendingScrollToDecoration = scrollToDecoration(view, scrollableDecorations, pluginState.activeIndex);
|
|
275
|
+
cancelPendingScrollToDecoration = scrollToDecoration(view, scrollableDecorations, pluginState.activeIndex, api);
|
|
276
276
|
|
|
277
277
|
// Stepping only scrolls — no focus moves and no content changes — so without this a
|
|
278
278
|
// screen-reader user gets silence. Announced through the live region rather than by
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { tableMarginTop } from '@atlaskit/editor-common/styles';
|
|
2
|
+
import { getStickyHeaderHeight } from '@atlaskit/editor-common/table/get-sticky-header-height';
|
|
3
|
+
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
4
|
+
import { isDiffDecoration, SCROLL_TARGET_MARGIN_CSS_PROPERTY } from './decorations/decorationKeys';
|
|
3
5
|
/**
|
|
4
6
|
* Extra space above the scrolled-to element so it does not sit flush under the
|
|
5
7
|
* viewport edge (helps with sticky table headers, toolbars, etc.).
|
|
@@ -10,6 +12,12 @@ import { isDiffDecoration } from './decorations/decorationKeys';
|
|
|
10
12
|
* outer scroll or mis-identifies the active scroll container.
|
|
11
13
|
*/
|
|
12
14
|
var SCROLL_TOP_MARGIN_PX = 100;
|
|
15
|
+
function updateScrollTargetMargin(view, targetPos, api) {
|
|
16
|
+
var _api$limitedMode;
|
|
17
|
+
var isLimitedModeEnabled = Boolean(api === null || api === void 0 || (_api$limitedMode = api.limitedMode) === null || _api$limitedMode === void 0 || (_api$limitedMode = _api$limitedMode.sharedState.currentState()) === null || _api$limitedMode === void 0 ? void 0 : _api$limitedMode.enabled);
|
|
18
|
+
var tableHeaderHeight = isLimitedModeEnabled ? undefined : getStickyHeaderHeight(view, targetPos);
|
|
19
|
+
view.dom.style.setProperty(SCROLL_TARGET_MARGIN_CSS_PROPERTY, "".concat(tableHeaderHeight ? tableHeaderHeight + tableMarginTop : 0, "px"));
|
|
20
|
+
}
|
|
13
21
|
|
|
14
22
|
/**
|
|
15
23
|
* Returns the resolved HTMLElement for a given DOM node, walking up to the
|
|
@@ -20,6 +28,13 @@ function scrollToSelection(node) {
|
|
|
20
28
|
if (!(element instanceof HTMLElement)) {
|
|
21
29
|
return;
|
|
22
30
|
}
|
|
31
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
32
|
+
element.scrollIntoView({
|
|
33
|
+
behavior: 'smooth',
|
|
34
|
+
block: 'start'
|
|
35
|
+
});
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
23
38
|
|
|
24
39
|
// scroll-margin is included in scroll-into-view math; it does not change layout.
|
|
25
40
|
var previousScrollMarginTop = element.style.scrollMarginTop;
|
|
@@ -42,6 +57,7 @@ function scrollToSelection(node) {
|
|
|
42
57
|
*/
|
|
43
58
|
export var scrollToDecoration = function scrollToDecoration(view, decorations) {
|
|
44
59
|
var activeIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
60
|
+
var api = arguments.length > 3 ? arguments[3] : undefined;
|
|
45
61
|
var decoration = decorations[activeIndex];
|
|
46
62
|
if (!decoration) {
|
|
47
63
|
return function () {};
|
|
@@ -53,6 +69,9 @@ export var scrollToDecoration = function scrollToDecoration(view, decorations) {
|
|
|
53
69
|
var target = isDiffDecoration(decoration) && decoration.spec.scrollTarget || decoration;
|
|
54
70
|
var rafId = requestAnimationFrame(function () {
|
|
55
71
|
rafId = null;
|
|
72
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
73
|
+
updateScrollTargetMargin(view, target.from, api);
|
|
74
|
+
}
|
|
56
75
|
if (isDiffDecoration(target) && target.spec.decorationType === 'widget') {
|
|
57
76
|
var _target$type;
|
|
58
77
|
// @ts-expect-error - decoration.type is not typed public API
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
2
2
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
3
|
+
import { akEditorSmallZIndex } from '@atlaskit/editor-shared-styles/constants';
|
|
3
4
|
export var CONTRIBUTOR_TAG_TESTID = 'diff-contributor-tag';
|
|
4
5
|
export var CONTRIBUTOR_TAG_NAME_TESTID = 'diff-contributor-tag-name';
|
|
5
6
|
|
|
@@ -13,15 +14,15 @@ export var MAX_TAG_WIDTH = '200px';
|
|
|
13
14
|
/**
|
|
14
15
|
* The tag sits on the line above the change, so it has to paint over that line to be readable —
|
|
15
16
|
* including any diff highlight already on it, which would otherwise slice straight through the tag.
|
|
16
|
-
*
|
|
17
|
-
* change's own highlight is stacked one level below it — see
|
|
18
|
-
* `createInlineChangedDecoration`.
|
|
17
|
+
* It also has to paint above table interaction overlays and sticky-capable header rows, which use
|
|
18
|
+
* `akEditorSmallZIndex`. The change's own highlight is stacked one level below it — see
|
|
19
|
+
* `stackBelowContributorTagStyle` in `createInlineChangedDecoration`.
|
|
19
20
|
*
|
|
20
21
|
* Painting above its own highlight is only safe because the tag can never reach it: `bottom: 100%`
|
|
21
22
|
* puts the root's bottom edge exactly on the highlight's top edge, and the root's `overflow: clip`
|
|
22
23
|
* keeps every pixel the tag paints inside it.
|
|
23
24
|
*/
|
|
24
|
-
export var CONTRIBUTOR_TAG_Z_INDEX =
|
|
25
|
+
export var CONTRIBUTOR_TAG_Z_INDEX = akEditorSmallZIndex + 1;
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* The plugin's whole side of the tag's motion: the fade and the hidden state are
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* IndicatorBarContentComponent.tsx generated by @compiled/babel-plugin v3.0.
|
|
1
|
+
/* IndicatorBarContentComponent.tsx generated by @compiled/babel-plugin v3.0.2 */
|
|
2
2
|
import { ax, ix } from "@compiled/react/runtime";
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
@@ -4,18 +4,23 @@ import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
|
4
4
|
import type { DiffType } from '../../showDiffPluginType';
|
|
5
5
|
import type { NodeViewSerializer } from '../NodeViewSerializer';
|
|
6
6
|
import type { ColorScheme } from './colorSchemes/types';
|
|
7
|
+
import { type ContributorTagMountContext } from './createContributorTagWidget';
|
|
7
8
|
type SimpleChange = Pick<Change, 'fromA' | 'toA' | 'fromB' | 'deleted'>;
|
|
8
9
|
/**
|
|
9
10
|
* Main function to handle deleted rows - computes diff and creates decorations
|
|
10
11
|
*/
|
|
11
|
-
export declare const createChangedRowDecorationWidgets: ({ changes, originalDoc, newDoc, nodeViewSerializer, colorScheme, isInserted, diffType, showIndicators, }: {
|
|
12
|
+
export declare const createChangedRowDecorationWidgets: ({ attributionKey, changes, originalDoc, newDoc, nodeViewSerializer, colorScheme, isActive, isInserted, diffType, showIndicators, showContributorTags, tagMountContext, }: {
|
|
13
|
+
attributionKey?: string;
|
|
12
14
|
changes: SimpleChange[];
|
|
13
15
|
colorScheme?: ColorScheme;
|
|
14
16
|
diffType?: DiffType;
|
|
17
|
+
isActive?: boolean;
|
|
15
18
|
isInserted?: boolean;
|
|
16
19
|
newDoc: PMNode;
|
|
17
20
|
nodeViewSerializer: NodeViewSerializer;
|
|
18
21
|
originalDoc: PMNode;
|
|
22
|
+
showContributorTags?: boolean;
|
|
19
23
|
showIndicators?: boolean;
|
|
24
|
+
tagMountContext?: ContributorTagMountContext;
|
|
20
25
|
}) => Decoration[];
|
|
21
26
|
export {};
|
|
@@ -10,6 +10,15 @@ export declare const DecorationFamily: {
|
|
|
10
10
|
readonly anchor: 'anchor';
|
|
11
11
|
readonly contributorTag: 'contributor-tag';
|
|
12
12
|
};
|
|
13
|
+
/**
|
|
14
|
+
* Navigation measures the target table header and writes this variable on the
|
|
15
|
+
* editor root immediately before scrolling. Diff decorations inherit it, so
|
|
16
|
+
* native scrolling leaves room for the header without DOM mutation on the
|
|
17
|
+
* ProseMirror-rendered suggestion.
|
|
18
|
+
*/
|
|
19
|
+
export declare const SCROLL_TARGET_MARGIN_CSS_PROPERTY = "--ak-editor-diff-additional-margin";
|
|
20
|
+
export declare const scrollMarginTopValue: string;
|
|
21
|
+
export declare const scrollMarginTopStyle: string;
|
|
13
22
|
type DecorationFamilyValue = (typeof DecorationFamily)[keyof typeof DecorationFamily];
|
|
14
23
|
type BaseDecorationSpec<TFamily extends DecorationFamilyValue> = {
|
|
15
24
|
decorationFamily: TFamily;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import type { ExtractInjectionAPI } from '@atlaskit/editor-common/types';
|
|
1
2
|
import type { EditorView, Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
3
|
+
import type { ShowDiffPlugin } from '../showDiffPluginType';
|
|
4
|
+
type PluginInjectionAPI = ExtractInjectionAPI<ShowDiffPlugin>;
|
|
2
5
|
/**
|
|
3
6
|
* Schedules scrolling to the decoration at the given index after the next frame. Defaults to the
|
|
4
7
|
* first decoration when no index is provided.
|
|
5
8
|
*
|
|
6
9
|
* @returns A function that cancels the scheduled `requestAnimationFrame` if it has not run yet.
|
|
7
10
|
*/
|
|
8
|
-
export declare const scrollToDecoration: (view: EditorView, decorations: Decoration[], activeIndex?: number) => (() => void);
|
|
11
|
+
export declare const scrollToDecoration: (view: EditorView, decorations: Decoration[], activeIndex?: number, api?: PluginInjectionAPI) => (() => void);
|
|
12
|
+
export {};
|
|
@@ -3,6 +3,7 @@ import type { NextEditorPlugin, EditorCommand, OptionalPlugin } from '@atlaskit/
|
|
|
3
3
|
import type { JSONDocNode } from '@atlaskit/editor-json-transformer/types';
|
|
4
4
|
import type { AccessibilityUtilsPlugin } from '@atlaskit/editor-plugin-accessibility-utils';
|
|
5
5
|
import type { AnalyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
6
|
+
import type { LimitedModePlugin } from '@atlaskit/editor-plugin-limited-mode/limited-mode-plugin-type';
|
|
6
7
|
import type { UserIntentPlugin } from '@atlaskit/editor-plugin-user-intent';
|
|
7
8
|
import type { Node } from '@atlaskit/editor-prosemirror/model';
|
|
8
9
|
import type { Step } from '@atlaskit/editor-prosemirror/transform-override';
|
|
@@ -232,6 +233,7 @@ export type ShowDiffPlugin = NextEditorPlugin<'showDiff', {
|
|
|
232
233
|
dependencies: [
|
|
233
234
|
OptionalPlugin<AnalyticsPlugin>,
|
|
234
235
|
OptionalPlugin<UserIntentPlugin>,
|
|
236
|
+
OptionalPlugin<LimitedModePlugin>,
|
|
235
237
|
/** Carries the live-region announcement made when stepping between changes. */
|
|
236
238
|
OptionalPlugin<AccessibilityUtilsPlugin>
|
|
237
239
|
];
|
|
@@ -9,15 +9,15 @@ export declare const MAX_TAG_WIDTH = "200px";
|
|
|
9
9
|
/**
|
|
10
10
|
* The tag sits on the line above the change, so it has to paint over that line to be readable —
|
|
11
11
|
* including any diff highlight already on it, which would otherwise slice straight through the tag.
|
|
12
|
-
*
|
|
13
|
-
* change's own highlight is stacked one level below it — see
|
|
14
|
-
* `createInlineChangedDecoration`.
|
|
12
|
+
* It also has to paint above table interaction overlays and sticky-capable header rows, which use
|
|
13
|
+
* `akEditorSmallZIndex`. The change's own highlight is stacked one level below it — see
|
|
14
|
+
* `stackBelowContributorTagStyle` in `createInlineChangedDecoration`.
|
|
15
15
|
*
|
|
16
16
|
* Painting above its own highlight is only safe because the tag can never reach it: `bottom: 100%`
|
|
17
17
|
* puts the root's bottom edge exactly on the highlight's top edge, and the root's `overflow: clip`
|
|
18
18
|
* keeps every pixel the tag paints inside it.
|
|
19
19
|
*/
|
|
20
|
-
export declare const CONTRIBUTOR_TAG_Z_INDEX
|
|
20
|
+
export declare const CONTRIBUTOR_TAG_Z_INDEX: number;
|
|
21
21
|
/**
|
|
22
22
|
* The plugin's whole side of the tag's motion: the fade and the hidden state are
|
|
23
23
|
* `contributorTagStyles` in both EditorContentContainer stylesheets, keyed on this literal and the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.17",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"@atlaskit/custom-steps": "^1.1.0",
|
|
26
26
|
"@atlaskit/editor-plugin-accessibility-utils": "^18.0.0",
|
|
27
27
|
"@atlaskit/editor-plugin-analytics": "^18.0.0",
|
|
28
|
+
"@atlaskit/editor-plugin-limited-mode": "^15.0.0",
|
|
28
29
|
"@atlaskit/editor-plugin-user-intent": "^16.0.0",
|
|
29
30
|
"@atlaskit/editor-prosemirror": "^8.0.0",
|
|
30
31
|
"@atlaskit/editor-shared-styles": "^4.3.0",
|
|
@@ -32,7 +33,7 @@
|
|
|
32
33
|
"@atlaskit/platform-feature-experiments": "^0.3.0",
|
|
33
34
|
"@atlaskit/platform-feature-flags": "^2.2.0",
|
|
34
35
|
"@atlaskit/primitives": "^22.5.0",
|
|
35
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
36
|
+
"@atlaskit/tmp-editor-statsig": "^197.0.0",
|
|
36
37
|
"@atlaskit/tokens": "^17.0.0",
|
|
37
38
|
"@babel/runtime": "^7.0.0",
|
|
38
39
|
"@compiled/react": "^1.0.2",
|
|
@@ -64,7 +65,7 @@
|
|
|
64
65
|
"react-intl": "^7.0.0"
|
|
65
66
|
},
|
|
66
67
|
"peerDependencies": {
|
|
67
|
-
"@atlaskit/editor-common": "^122.
|
|
68
|
+
"@atlaskit/editor-common": "^122.9.0",
|
|
68
69
|
"react": "^18.2.0 || ^19.2.0",
|
|
69
70
|
"react-dom": "^18.2.0 || ^19.2.0",
|
|
70
71
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.areDocsEqualByBlockStructureAndText = areDocsEqualByBlockStructureAndText;
|
|
7
|
-
var _transform = require("@atlaskit/editor-prosemirror/transform");
|
|
8
|
-
/**
|
|
9
|
-
* Returns a copy of the document with all marks removed from all text.
|
|
10
|
-
* This normalises mark fragmentation — e.g. annotation marks reordering can split
|
|
11
|
-
* a single text run into many text nodes, making structural comparison unreliable.
|
|
12
|
-
* After stripping, ProseMirror will merge adjacent text nodes so childCounts are stable.
|
|
13
|
-
*/
|
|
14
|
-
function stripMarks(doc) {
|
|
15
|
-
var tr = new _transform.Transform(doc);
|
|
16
|
-
tr.removeMark(0, doc.content.size);
|
|
17
|
-
return tr.doc;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Returns true if both (mark-stripped) nodes have the same block tree structure (node type and child count at every level)
|
|
22
|
-
*/
|
|
23
|
-
function isBlockStructureEqual(node1, node2) {
|
|
24
|
-
if (node1.type !== node2.type || node1.childCount !== node2.childCount) {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
for (var i = 0; i < node1.childCount; i++) {
|
|
28
|
-
if (!isBlockStructureEqual(node1.child(i), node2.child(i))) {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Looser equality for "safe diff" cases: same full text content and same block structure
|
|
37
|
-
* (e.g. text moved across text-node boundaries). Used when strict areNodesEqualIgnoreAttrs fails.
|
|
38
|
-
* This is safe because we ensure decorations get applied to valid positions.
|
|
39
|
-
*
|
|
40
|
-
* Marks are intentionally ignored — two documents that differ only in mark application
|
|
41
|
-
* (e.g. bold/italic boundaries or annotation mark ordering) are considered equal here.
|
|
42
|
-
* Both documents are mark-stripped before comparison so that mark-driven text fragmentation
|
|
43
|
-
* does not produce false inequalities.
|
|
44
|
-
*/
|
|
45
|
-
function areDocsEqualByBlockStructureAndText(doc1, doc2) {
|
|
46
|
-
if (doc1.textContent !== doc2.textContent) {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
// Strip marks before comparing so that mark-driven text fragmentation
|
|
50
|
-
// (e.g. annotation mark reordering producing different childCounts) does not
|
|
51
|
-
// cause false inequalities.
|
|
52
|
-
var stripped1 = stripMarks(doc1);
|
|
53
|
-
var stripped2 = stripMarks(doc2);
|
|
54
|
-
return doc1.nodeSize === doc2.nodeSize && isBlockStructureEqual(stripped1, stripped2);
|
|
55
|
-
}
|