@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
|
@@ -10,7 +10,8 @@ import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildDel
|
|
|
10
10
|
import { colorSchemeRegistry, getLegacyColorScheme } from './colorSchemes/schemes';
|
|
11
11
|
import { createLeftAnchorWidget } from './createAnchorDecorationWidgets';
|
|
12
12
|
import { resolveCellOverlayStyleLegacy, resolveDeletedRowStyleLegacy } from './createChangedRowDecorationWidgets.styles.legacy';
|
|
13
|
-
import {
|
|
13
|
+
import { createContributorTagWidget, isContributorTagWidgetEnabled } from './createContributorTagWidget';
|
|
14
|
+
import { AnchorTypeKey, buildAnchorDecorationKey, buildDiffDecorationSpec, scrollMarginTopValue } from './decorationKeys';
|
|
14
15
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
15
16
|
import { applyCellEdgeAttrs, getRowCellEdgeAttrs, getTableTopAndBottomCellEdgeAttrs } from './utils/tableCellEdgeAttrs';
|
|
16
17
|
/**
|
|
@@ -86,18 +87,35 @@ const extractChangedRows = ({
|
|
|
86
87
|
}
|
|
87
88
|
});
|
|
88
89
|
|
|
89
|
-
// Filter changes that never truly got deleted
|
|
90
|
+
// Filter changes that never truly got deleted. Compare the number of equivalent rows rather
|
|
91
|
+
// than only checking whether one still exists: deleting two of three identical empty rows should
|
|
92
|
+
// retain two changed rows even though the third remains in the new table.
|
|
93
|
+
const equivalentRowDeletionCounts = [];
|
|
90
94
|
return changedRows.filter(changedRow => {
|
|
91
95
|
// A replacement leaves every sibling row in place, so asking "does this row still exist
|
|
92
96
|
// ANYWHERE in the new table?" can drop a genuinely rewritten row that happens to match a
|
|
93
|
-
// sibling. Compare it against the row at the same index instead.
|
|
94
|
-
// whole-table `some()`: their indices shift, so an index comparison would let every
|
|
95
|
-
// surviving row through and draw a widget for each one.
|
|
97
|
+
// sibling. Compare it against the row at the same index instead.
|
|
96
98
|
if (handleRowReplacement) {
|
|
97
99
|
const counterpart = tableNew.node.maybeChild(changedRow.rowIndex);
|
|
98
100
|
return !counterpart || !areNodesEqualIgnoreAttrs(counterpart, changedRow.rowNode);
|
|
99
101
|
}
|
|
100
|
-
|
|
102
|
+
let deletionCount = equivalentRowDeletionCounts.find(({
|
|
103
|
+
rowNode
|
|
104
|
+
}) => areNodesEqualIgnoreAttrs(rowNode, changedRow.rowNode));
|
|
105
|
+
if (!deletionCount) {
|
|
106
|
+
const oldRowCount = tableOld.node.children.filter(oldRow => areNodesEqualIgnoreAttrs(oldRow, changedRow.rowNode)).length;
|
|
107
|
+
const newRowCount = tableNew.node.children.filter(newRow => areNodesEqualIgnoreAttrs(newRow, changedRow.rowNode)).length;
|
|
108
|
+
deletionCount = {
|
|
109
|
+
remaining: Math.max(0, oldRowCount - newRowCount),
|
|
110
|
+
rowNode: changedRow.rowNode
|
|
111
|
+
};
|
|
112
|
+
equivalentRowDeletionCounts.push(deletionCount);
|
|
113
|
+
}
|
|
114
|
+
if (deletionCount.remaining === 0) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
deletionCount.remaining--;
|
|
118
|
+
return true;
|
|
101
119
|
});
|
|
102
120
|
};
|
|
103
121
|
|
|
@@ -142,6 +160,9 @@ const createChangedRowDOM = (rowNode, cellEdgeAttrs, nodeViewSerializer, colorSc
|
|
|
142
160
|
// is ADDED content, so it must not claim the "deleted" testid — page models match that as
|
|
143
161
|
// removed content (same reasoning as `createTableCellContentWidgets`).
|
|
144
162
|
tr.setAttribute('data-testid', isExtendedEnabled(diffType) && isInserted && fg('platform_editor_ai_show_diff_patch_1') ? 'show-diff-changed-row' : 'show-diff-deleted-row');
|
|
163
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
164
|
+
tr.style.setProperty('scroll-margin-top', scrollMarginTopValue);
|
|
165
|
+
}
|
|
145
166
|
|
|
146
167
|
// Serialize each cell in the row
|
|
147
168
|
let cellIndex = 0;
|
|
@@ -206,14 +227,18 @@ const expandDiffForChangedRows = ({
|
|
|
206
227
|
* Main function to handle deleted rows - computes diff and creates decorations
|
|
207
228
|
*/
|
|
208
229
|
export const createChangedRowDecorationWidgets = ({
|
|
230
|
+
attributionKey,
|
|
209
231
|
changes,
|
|
210
232
|
originalDoc,
|
|
211
233
|
newDoc,
|
|
212
234
|
nodeViewSerializer,
|
|
213
235
|
colorScheme,
|
|
236
|
+
isActive,
|
|
214
237
|
isInserted = false,
|
|
215
238
|
diffType,
|
|
216
|
-
showIndicators = false
|
|
239
|
+
showIndicators = false,
|
|
240
|
+
showContributorTags = false,
|
|
241
|
+
tagMountContext
|
|
217
242
|
}) => {
|
|
218
243
|
// First, expand the changes to include complete deleted rows
|
|
219
244
|
const changedRows = expandDiffForChangedRows({
|
|
@@ -229,8 +254,12 @@ export const createChangedRowDecorationWidgets = ({
|
|
|
229
254
|
const safeInsertPos = findSafeInsertPos(newDoc, changedRow.fromB - 1,
|
|
230
255
|
// -1 to find the first safe position from the table
|
|
231
256
|
originalDoc.slice(changedRow.fromA, changedRow.toA));
|
|
232
|
-
|
|
257
|
+
|
|
258
|
+
// Stable while contributor tags are enabled so a decoration recalculation preserves the tag's
|
|
259
|
+
// identity and controller state.
|
|
260
|
+
const diffId = showContributorTags ? `widget-row-${changedRow.fromA}-${changedRow.toA}` : crypto.randomUUID();
|
|
233
261
|
const decorations = [];
|
|
262
|
+
const rowAnchorNames = [];
|
|
234
263
|
|
|
235
264
|
// `IndicatorBarContentComponent` renders a bar for every widget descriptor and anchors its
|
|
236
265
|
// top and bottom to `anchor-<diffId>`. Without an element carrying that anchor name the bar
|
|
@@ -238,9 +267,9 @@ export const createChangedRowDecorationWidgets = ({
|
|
|
238
267
|
// bar covers only the row being changed. `createNodeChangedDecorationWidget` sets the same
|
|
239
268
|
// property on its own widget DOM for non-table content; this path returns before reaching it.
|
|
240
269
|
if (showIndicators && isExtendedEnabled(diffType) && fg('platform_editor_ai_show_diff_patch_1')) {
|
|
241
|
-
|
|
270
|
+
rowAnchorNames.push(buildAnchorDecorationKey({
|
|
242
271
|
diffId
|
|
243
|
-
})
|
|
272
|
+
}));
|
|
244
273
|
|
|
245
274
|
// A table's content can extend past the doc margin, so the bar also needs a left anchor
|
|
246
275
|
// measured against the table itself or it is clipped once the table is resized.
|
|
@@ -253,16 +282,47 @@ export const createChangedRowDecorationWidgets = ({
|
|
|
253
282
|
decorations.push(leftAnchor);
|
|
254
283
|
}
|
|
255
284
|
}
|
|
256
|
-
|
|
285
|
+
const tagAnchorName = showContributorTags && isContributorTagWidgetEnabled() ? buildAnchorDecorationKey({
|
|
286
|
+
diffId,
|
|
287
|
+
anchorType: AnchorTypeKey.tag
|
|
288
|
+
}) : undefined;
|
|
289
|
+
const tagWidget = tagAnchorName ? createContributorTagWidget({
|
|
290
|
+
anchorAtRangeStart: true,
|
|
291
|
+
anchorName: tagAnchorName,
|
|
292
|
+
diffId,
|
|
293
|
+
doc: newDoc,
|
|
294
|
+
from: safeInsertPos,
|
|
295
|
+
mountContext: tagMountContext,
|
|
296
|
+
to: safeInsertPos
|
|
297
|
+
}) : undefined;
|
|
298
|
+
if (tagAnchorName) {
|
|
299
|
+
// The tag host is a separate, table-safe widget. CSS anchor positioning aligns it to this
|
|
300
|
+
// synthetic row without placing non-cell DOM inside the `<tr>` or inheriting its deletion
|
|
301
|
+
// opacity and strikethrough.
|
|
302
|
+
rowAnchorNames.push(tagAnchorName);
|
|
303
|
+
}
|
|
304
|
+
if (rowAnchorNames.length > 0) {
|
|
305
|
+
rowDOM.style.setProperty('anchor-name', rowAnchorNames.map(anchorName => `--${anchorName}`).join(', '));
|
|
306
|
+
}
|
|
307
|
+
if (tagWidget) {
|
|
308
|
+
// Lets the contributor tag reveal when any part of the deleted row is hovered.
|
|
309
|
+
rowDOM.setAttribute('data-diff-id', diffId);
|
|
310
|
+
}
|
|
311
|
+
const rowWidget = Decoration.widget(safeInsertPos, rowDOM, {
|
|
257
312
|
...buildDiffDecorationSpec({
|
|
313
|
+
attributionKey: tagWidget ? attributionKey : undefined,
|
|
258
314
|
colorScheme,
|
|
259
315
|
decorationType: 'widget',
|
|
260
316
|
diffId,
|
|
261
|
-
isActive
|
|
317
|
+
isActive,
|
|
262
318
|
isInserted,
|
|
263
319
|
diffType
|
|
264
320
|
})
|
|
265
|
-
})
|
|
321
|
+
});
|
|
322
|
+
decorations.push(rowWidget);
|
|
323
|
+
if (tagWidget) {
|
|
324
|
+
decorations.push(tagWidget);
|
|
325
|
+
}
|
|
266
326
|
return decorations;
|
|
267
327
|
});
|
|
268
328
|
};
|
|
@@ -1,6 +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 { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
4
|
+
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
4
5
|
import { CONTRIBUTOR_TAG_Z_INDEX } from '../../ui/ContributorTag/buildContributorTagDom';
|
|
5
6
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
6
7
|
import { isEmptyParagraphSlice } from '../utils/isEmptyParagraphSlice';
|
|
@@ -9,7 +10,7 @@ import { colorSchemeRegistry, getLegacyColorScheme } from './colorSchemes/scheme
|
|
|
9
10
|
import { createInlineIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
|
|
10
11
|
import { createContributorTagWidget, isContributorTagWidgetEnabled } from './createContributorTagWidget';
|
|
11
12
|
import { getAtomicInlineNodeClassNameLegacy, resolveInlineChangedStyleLegacy } from './createInlineChangedDecoration.styles.legacy';
|
|
12
|
-
import { buildDiffDecorationSpec } from './decorationKeys';
|
|
13
|
+
import { buildDiffDecorationSpec, scrollMarginTopStyle } from './decorationKeys';
|
|
13
14
|
import { REVEAL_ATTR, resolveRevealStyle } from './revealStyles';
|
|
14
15
|
const displayNoneStyle = convertToInlineCss({
|
|
15
16
|
display: 'none'
|
|
@@ -190,7 +191,7 @@ export const createInlineChangedDecoration = ({
|
|
|
190
191
|
diffId,
|
|
191
192
|
mountContext: tagMountContext
|
|
192
193
|
}) : undefined;
|
|
193
|
-
const inlineStyle = [style, atomicInlineAttrs === null || atomicInlineAttrs === void 0 ? void 0 : atomicInlineAttrs.styleSuffix, tagWidget ? stackBelowContributorTagStyle : undefined].filter(Boolean).join('');
|
|
194
|
+
const 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('');
|
|
194
195
|
const decorations = [Decoration.inline(change.fromB, change.toB, {
|
|
195
196
|
style: inlineStyle,
|
|
196
197
|
...(atomicInlineAttrs && {
|
|
@@ -5,7 +5,7 @@ import { isEmptyParagraphSlice } from '../utils/isEmptyParagraphSlice';
|
|
|
5
5
|
import { createLeftAnchorWidget } from './createAnchorDecorationWidgets';
|
|
6
6
|
import { createChangedRowDecorationWidgets } from './createChangedRowDecorationWidgets';
|
|
7
7
|
import { createContributorTagHost, unmountContributorTag } from './createContributorTagWidget';
|
|
8
|
-
import { buildDiffDecorationSpec, buildAnchorDecorationKey } from './decorationKeys';
|
|
8
|
+
import { buildDiffDecorationSpec, buildAnchorDecorationKey, scrollMarginTopValue } from './decorationKeys';
|
|
9
9
|
import { findSafeInsertPos } from './utils/findSafeInsertPos';
|
|
10
10
|
import { wrapBlockNodeView, injectInnerWrapper, createContentWrapper } from './utils/wrapBlockNodeView';
|
|
11
11
|
const isHeadingLevel = level => typeof level === 'number' && level >= 1 && level <= 6;
|
|
@@ -69,6 +69,9 @@ const createTableCellContentWidgets = ({
|
|
|
69
69
|
// This helper only runs for added content, so use the "changed" testid — not
|
|
70
70
|
// "deleted", which page models match as removed content.
|
|
71
71
|
dom.setAttribute('data-testid', 'show-diff-changed-decoration');
|
|
72
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
73
|
+
dom.style.setProperty('scroll-margin-top', scrollMarginTopValue);
|
|
74
|
+
}
|
|
72
75
|
|
|
73
76
|
// Skip findSafeInsertPos: it walks forward to a schema-valid cell-insert point
|
|
74
77
|
// and pushes the widget into the next cell. `targetPos` is the correct spot.
|
|
@@ -150,16 +153,20 @@ export const createNodeChangedDecorationWidget = ({
|
|
|
150
153
|
}
|
|
151
154
|
if (isTableRowContent) {
|
|
152
155
|
return createChangedRowDecorationWidgets({
|
|
156
|
+
attributionKey,
|
|
153
157
|
changes: [change],
|
|
154
158
|
originalDoc: doc,
|
|
155
159
|
newDoc,
|
|
156
160
|
nodeViewSerializer,
|
|
157
161
|
colorScheme,
|
|
162
|
+
isActive,
|
|
158
163
|
isInserted,
|
|
159
164
|
diffType,
|
|
160
165
|
// Needed for the row's own indicator anchor; this path returns before the
|
|
161
166
|
// `anchor-name` assignment further down.
|
|
162
|
-
showIndicators
|
|
167
|
+
showIndicators,
|
|
168
|
+
showContributorTags,
|
|
169
|
+
tagMountContext
|
|
163
170
|
});
|
|
164
171
|
}
|
|
165
172
|
const serializer = nodeViewSerializer;
|
|
@@ -330,6 +337,9 @@ export const createNodeChangedDecorationWidget = ({
|
|
|
330
337
|
}
|
|
331
338
|
});
|
|
332
339
|
dom.setAttribute('data-testid', 'show-diff-deleted-decoration');
|
|
340
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
341
|
+
dom.style.setProperty('scroll-margin-top', scrollMarginTopValue);
|
|
342
|
+
}
|
|
333
343
|
|
|
334
344
|
// Needed even when the indicator bar is off, because a contributor tag also anchors against the
|
|
335
345
|
// widget.
|
|
@@ -416,6 +426,9 @@ export const createNodeChangedDecorationWidget = ({
|
|
|
416
426
|
defaultSpacer.dataset.testid = 'show-diff-default-margin-spacer';
|
|
417
427
|
defaultSpacer.style.display = 'block';
|
|
418
428
|
defaultSpacer.style.marginTop = "var(--ds-space-100, 8px)";
|
|
429
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
430
|
+
defaultSpacer.style.setProperty('scroll-margin-top', scrollMarginTopValue);
|
|
431
|
+
}
|
|
419
432
|
decorations.push(Decoration.widget(safeInsertPos, defaultSpacer, {
|
|
420
433
|
...buildDiffDecorationSpec({
|
|
421
434
|
colorScheme,
|
|
@@ -8,6 +8,16 @@ export const DecorationFamily = {
|
|
|
8
8
|
anchor: 'anchor',
|
|
9
9
|
contributorTag: 'contributor-tag'
|
|
10
10
|
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Navigation measures the target table header and writes this variable on the
|
|
14
|
+
* editor root immediately before scrolling. Diff decorations inherit it, so
|
|
15
|
+
* native scrolling leaves room for the header without DOM mutation on the
|
|
16
|
+
* ProseMirror-rendered suggestion.
|
|
17
|
+
*/
|
|
18
|
+
export const SCROLL_TARGET_MARGIN_CSS_PROPERTY = '--ak-editor-diff-additional-margin';
|
|
19
|
+
export const scrollMarginTopValue = `calc(${"var(--ds-space-400, 32px)"} + var(${SCROLL_TARGET_MARGIN_CSS_PROPERTY}, 0px))`;
|
|
20
|
+
export const scrollMarginTopStyle = `scroll-margin-top: ${scrollMarginTopValue};`;
|
|
11
21
|
export const AnchorTypeKey = {
|
|
12
22
|
from: 'from',
|
|
13
23
|
to: 'to',
|
|
@@ -264,7 +264,7 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
264
264
|
if (pluginState !== null && pluginState !== void 0 && pluginState.scrollIntoView && isExtendedEnabled(pluginState === null || pluginState === void 0 ? void 0 : pluginState.diffType)) {
|
|
265
265
|
var _cancelPendingScrollT;
|
|
266
266
|
(_cancelPendingScrollT = cancelPendingScrollToDecoration) === null || _cancelPendingScrollT === void 0 ? void 0 : _cancelPendingScrollT();
|
|
267
|
-
cancelPendingScrollToDecoration = scrollToDecoration(view, getScrollableDecorations(pluginState.decorations, view.state.doc, pluginState === null || pluginState === void 0 ? void 0 : pluginState.diffType));
|
|
267
|
+
cancelPendingScrollToDecoration = scrollToDecoration(view, getScrollableDecorations(pluginState.decorations, view.state.doc, pluginState === null || pluginState === void 0 ? void 0 : pluginState.diffType), undefined, api);
|
|
268
268
|
|
|
269
269
|
// Reset the flag so we don't scroll again on subsequent updates
|
|
270
270
|
view.dispatch(view.state.tr.setMeta(showDiffPluginKey, {
|
|
@@ -285,7 +285,7 @@ export const createPlugin = (config, getIntl, api, onEditorView) => {
|
|
|
285
285
|
// avoid a circular dependency; expand picks up the meta if loaded (no-op if not).
|
|
286
286
|
api === null || api === void 0 ? void 0 : api.core.actions.execute(toggleExpandRange(activeDecoration.from, activeDecoration.to, true));
|
|
287
287
|
}
|
|
288
|
-
cancelPendingScrollToDecoration = scrollToDecoration(view, scrollableDecorations, pluginState.activeIndex);
|
|
288
|
+
cancelPendingScrollToDecoration = scrollToDecoration(view, scrollableDecorations, pluginState.activeIndex, api);
|
|
289
289
|
|
|
290
290
|
// Stepping only scrolls — no focus moves and no content changes — so without this a
|
|
291
291
|
// 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
|
const SCROLL_TOP_MARGIN_PX = 100;
|
|
15
|
+
function updateScrollTargetMargin(view, targetPos, api) {
|
|
16
|
+
var _api$limitedMode, _api$limitedMode$shar;
|
|
17
|
+
const isLimitedModeEnabled = Boolean(api === null || api === void 0 ? void 0 : (_api$limitedMode = api.limitedMode) === null || _api$limitedMode === void 0 ? void 0 : (_api$limitedMode$shar = _api$limitedMode.sharedState.currentState()) === null || _api$limitedMode$shar === void 0 ? void 0 : _api$limitedMode$shar.enabled);
|
|
18
|
+
const tableHeaderHeight = isLimitedModeEnabled ? undefined : getStickyHeaderHeight(view, targetPos);
|
|
19
|
+
view.dom.style.setProperty(SCROLL_TARGET_MARGIN_CSS_PROPERTY, `${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
|
const previousScrollMarginTop = element.style.scrollMarginTop;
|
|
@@ -40,7 +55,7 @@ function scrollToSelection(node) {
|
|
|
40
55
|
*
|
|
41
56
|
* @returns A function that cancels the scheduled `requestAnimationFrame` if it has not run yet.
|
|
42
57
|
*/
|
|
43
|
-
export const scrollToDecoration = (view, decorations, activeIndex = 0) => {
|
|
58
|
+
export const scrollToDecoration = (view, decorations, activeIndex = 0, api) => {
|
|
44
59
|
const decoration = decorations[activeIndex];
|
|
45
60
|
if (!decoration) {
|
|
46
61
|
return () => {};
|
|
@@ -52,6 +67,9 @@ export const scrollToDecoration = (view, decorations, activeIndex = 0) => {
|
|
|
52
67
|
const target = isDiffDecoration(decoration) && decoration.spec.scrollTarget || decoration;
|
|
53
68
|
let rafId = requestAnimationFrame(() => {
|
|
54
69
|
rafId = null;
|
|
70
|
+
if (fg('platform_editor_ai_show_diff_patch_1')) {
|
|
71
|
+
updateScrollTargetMargin(view, target.from, api);
|
|
72
|
+
}
|
|
55
73
|
if (isDiffDecoration(target) && target.spec.decorationType === 'widget') {
|
|
56
74
|
var _target$type;
|
|
57
75
|
// @ts-expect-error - decoration.type is not typed public API
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
2
|
+
import { akEditorSmallZIndex } from '@atlaskit/editor-shared-styles/constants';
|
|
2
3
|
export const CONTRIBUTOR_TAG_TESTID = 'diff-contributor-tag';
|
|
3
4
|
export const CONTRIBUTOR_TAG_NAME_TESTID = 'diff-contributor-tag-name';
|
|
4
5
|
|
|
@@ -12,15 +13,15 @@ export const MAX_TAG_WIDTH = '200px';
|
|
|
12
13
|
/**
|
|
13
14
|
* The tag sits on the line above the change, so it has to paint over that line to be readable —
|
|
14
15
|
* including any diff highlight already on it, which would otherwise slice straight through the tag.
|
|
15
|
-
*
|
|
16
|
-
* change's own highlight is stacked one level below it — see
|
|
17
|
-
* `createInlineChangedDecoration`.
|
|
16
|
+
* It also has to paint above table interaction overlays and sticky-capable header rows, which use
|
|
17
|
+
* `akEditorSmallZIndex`. The change's own highlight is stacked one level below it — see
|
|
18
|
+
* `stackBelowContributorTagStyle` in `createInlineChangedDecoration`.
|
|
18
19
|
*
|
|
19
20
|
* Painting above its own highlight is only safe because the tag can never reach it: `bottom: 100%`
|
|
20
21
|
* puts the root's bottom edge exactly on the highlight's top edge, and the root's `overflow: clip`
|
|
21
22
|
* keeps every pixel the tag paints inside it.
|
|
22
23
|
*/
|
|
23
|
-
export const CONTRIBUTOR_TAG_Z_INDEX =
|
|
24
|
+
export const CONTRIBUTOR_TAG_Z_INDEX = akEditorSmallZIndex + 1;
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* 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';
|
|
@@ -9,13 +9,13 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
|
|
|
9
9
|
import isEqual from 'lodash/isEqual';
|
|
10
10
|
import memoizeOne from 'memoize-one';
|
|
11
11
|
import { ChangeSet, simplifyChanges } from 'prosemirror-changeset';
|
|
12
|
+
import { areDocsEqualByBlockStructureAndText } from '@atlaskit/editor-common/utils/areDocsEqualByBlockStructureAndText';
|
|
12
13
|
import { areNodesEqualIgnoreAttrs } from '@atlaskit/editor-common/utils/document';
|
|
13
14
|
import { Mapping } from '@atlaskit/editor-prosemirror/transform';
|
|
14
15
|
import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
15
16
|
import { UNSAFE_expValNoExposure } from '@atlaskit/platform-feature-experiments/unsafe-exp-val-no-exposure';
|
|
16
17
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
17
18
|
import { expValEqualsNoExposure } from '@atlaskit/tmp-editor-statsig/exp-val-equals-no-exposure';
|
|
18
|
-
import { areDocsEqualByBlockStructureAndText } from '../areDocsEqualByBlockStructureAndText';
|
|
19
19
|
import { createDocMarginAnchorWidget } from '../decorations/createAnchorDecorationWidgets';
|
|
20
20
|
import { createBlockChangedDecoration } from '../decorations/createBlockChangedDecoration';
|
|
21
21
|
import { createInlineChangedDecoration } from '../decorations/createInlineChangedDecoration';
|
|
@@ -214,6 +214,7 @@ export var createLeftAnchorWidget = function createLeftAnchorWidget(_ref) {
|
|
|
214
214
|
*
|
|
215
215
|
*/
|
|
216
216
|
export var createBlockIndicatorAnchorWidgets = function createBlockIndicatorAnchorWidgets(_ref2) {
|
|
217
|
+
var _ref3, _parentTable$pos;
|
|
217
218
|
var doc = _ref2.doc,
|
|
218
219
|
from = _ref2.from,
|
|
219
220
|
to = _ref2.to,
|
|
@@ -253,9 +254,14 @@ export var createBlockIndicatorAnchorWidgets = function createBlockIndicatorAnch
|
|
|
253
254
|
var parentCellOrRow = findParentNodeClosestToPos($from, function (ancestor) {
|
|
254
255
|
return ['tableCell', 'tableHeader', 'tableRow'].includes(ancestor.type.name);
|
|
255
256
|
});
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
257
|
+
var parentLayout = fg('platform_editor_ai_show_diff_patch_1') ? findParentNodeClosestToPos($from, function (ancestor) {
|
|
258
|
+
return ancestor.type.name === 'layoutSection';
|
|
259
|
+
}) : undefined;
|
|
260
|
+
// Layouts flatten direct widget children with display: contents. Such a wrapper has no
|
|
261
|
+
// bounding box or positioning context, so measuring its top produces an offset from the
|
|
262
|
+
// viewport origin and displaces the indicator into content below the editor. Keep the
|
|
263
|
+
// wrapper outside the layout, just as we do for tables, but still measure the target node.
|
|
264
|
+
var widgetPos = (_ref3 = (_parentTable$pos = parentTable === null || parentTable === void 0 ? void 0 : parentTable.pos) !== null && _parentTable$pos !== void 0 ? _parentTable$pos : parentLayout === null || parentLayout === void 0 ? void 0 : parentLayout.pos) !== null && _ref3 !== void 0 ? _ref3 : from;
|
|
259
265
|
// Measure the actual cell/row DOM when inside one; otherwise measure the
|
|
260
266
|
// widget's own position.
|
|
261
267
|
var measurePos = parentCellOrRow ? parentCellOrRow.pos : from;
|
|
@@ -354,11 +360,11 @@ export var createAnchorNameSpan = function createAnchorNameSpan(anchorKey) {
|
|
|
354
360
|
span.style.setProperty('anchor-name', "--".concat(anchorKey));
|
|
355
361
|
return span;
|
|
356
362
|
};
|
|
357
|
-
var createAnchorSpanWidget = function createAnchorSpanWidget(
|
|
358
|
-
var pos =
|
|
359
|
-
diffId =
|
|
360
|
-
anchorType =
|
|
361
|
-
side =
|
|
363
|
+
var createAnchorSpanWidget = function createAnchorSpanWidget(_ref4) {
|
|
364
|
+
var pos = _ref4.pos,
|
|
365
|
+
diffId = _ref4.diffId,
|
|
366
|
+
anchorType = _ref4.anchorType,
|
|
367
|
+
side = _ref4.side;
|
|
362
368
|
return Decoration.widget(pos, function () {
|
|
363
369
|
return createAnchorNameSpan(buildAnchorDecorationKey({
|
|
364
370
|
diffId: diffId,
|
|
@@ -375,11 +381,11 @@ var createAnchorSpanWidget = function createAnchorSpanWidget(_ref3) {
|
|
|
375
381
|
* Invisible `from`/`to` (and optional `left`) anchor widgets for one inline diff
|
|
376
382
|
* range, so the `IndicatorBar` can align itself via CSS anchor positioning.
|
|
377
383
|
*/
|
|
378
|
-
export var createInlineIndicatorAnchorWidgets = function createInlineIndicatorAnchorWidgets(
|
|
379
|
-
var doc =
|
|
380
|
-
from =
|
|
381
|
-
to =
|
|
382
|
-
diffId =
|
|
384
|
+
export var createInlineIndicatorAnchorWidgets = function createInlineIndicatorAnchorWidgets(_ref5) {
|
|
385
|
+
var doc = _ref5.doc,
|
|
386
|
+
from = _ref5.from,
|
|
387
|
+
to = _ref5.to,
|
|
388
|
+
diffId = _ref5.diffId;
|
|
383
389
|
var leftAnchor = createLeftAnchorWidget({
|
|
384
390
|
doc: doc,
|
|
385
391
|
from: from,
|
|
@@ -6,12 +6,13 @@ import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
|
6
6
|
import { findParentNodeClosestToPos } from '@atlaskit/editor-prosemirror/utils';
|
|
7
7
|
import { Decoration } from '@atlaskit/editor-prosemirror/view';
|
|
8
8
|
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
9
|
+
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
9
10
|
import { isExtendedEnabled } from '../isExtendedEnabled';
|
|
10
11
|
import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildDeletedBlockNodeStyle, buildDeletedCellOverlayRoundedStyle, buildDeletedCellOverlayStyle, buildInsertedBlockNodeStyle } from './colorSchemes/factory';
|
|
11
12
|
import { colorSchemeRegistry, getLegacyColorScheme } from './colorSchemes/schemes';
|
|
12
13
|
import { createBlockIndicatorAnchorWidgets } from './createAnchorDecorationWidgets';
|
|
13
14
|
import { createContributorTagWidget, isContributorTagWidgetEnabled } from './createContributorTagWidget';
|
|
14
|
-
import { AnchorTypeKey, buildAnchorDecorationKey,
|
|
15
|
+
import { AnchorTypeKey, buildDiffDecorationSpec, buildAnchorDecorationKey, scrollMarginTopStyle } from './decorationKeys';
|
|
15
16
|
import { getBlockNodeStyleLegacy, resolveCellOverlayStyleLegacy } from './createBlockChangedDecoration.styles.legacy';
|
|
16
17
|
var displayNoneStyle = convertToInlineCss({
|
|
17
18
|
display: 'none'
|
|
@@ -243,7 +244,7 @@ export var createBlockChangedDecoration = function createBlockChangedDecoration(
|
|
|
243
244
|
});
|
|
244
245
|
var style = tagAnchorName ? [nodeStyle, convertToInlineCss({
|
|
245
246
|
anchorName: "--".concat(tagAnchorName)
|
|
246
|
-
})].filter(Boolean).join(' ') : nodeStyle;
|
|
247
|
+
}), fg('platform_editor_ai_show_diff_patch_1') ? scrollMarginTopStyle : undefined].filter(Boolean).join(' ') : nodeStyle;
|
|
247
248
|
var className = getNodeClass(change.name);
|
|
248
249
|
if (style || className) {
|
|
249
250
|
decorations.push(Decoration.node(change.from, change.to, _objectSpread({
|