@atlaskit/editor-plugin-show-diff 13.0.8 → 13.0.10
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
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 13.0.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 13.0.9
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`0123de9acf8b1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0123de9acf8b1) -
|
|
14
|
+
[CCI-18588] Fix multi-second browser freeze when opening the AI Review moment on a large generated
|
|
15
|
+
table. For big inserted tables the diff previously emitted one decoration per cell (O(cells)) plus
|
|
16
|
+
redundant inner-block decorations, forcing a full synchronous table relayout. It now skips the
|
|
17
|
+
per-cell inline and inner-block (table/row/paragraph) decorations while keeping the cell overlay
|
|
18
|
+
highlight. Gated behind `platform_editor_ai_new_aifc_editor_experience`; behaviour is unchanged
|
|
19
|
+
for small tables and when the experiment is off.
|
|
20
|
+
|
|
3
21
|
## 13.0.8
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -95,6 +95,26 @@ var leafTextblockRanges = function leafTextblockRanges(doc, from, to) {
|
|
|
95
95
|
});
|
|
96
96
|
return ranges;
|
|
97
97
|
};
|
|
98
|
+
|
|
99
|
+
// A large inserted table is treated with a coarse decoration path (see below)
|
|
100
|
+
// once it has more leaf textblocks (~cells) than this threshold. Small tables
|
|
101
|
+
// keep the precise per-cell path.
|
|
102
|
+
var LARGE_TABLE_LEAF_THRESHOLD = 40;
|
|
103
|
+
var isLargeInsertedTableRange = function isLargeInsertedTableRange(doc, from, to) {
|
|
104
|
+
var containsTable = false;
|
|
105
|
+
var leafCount = 0;
|
|
106
|
+
doc.nodesBetween(from, to, function (node) {
|
|
107
|
+
if (node.type.name === 'table') {
|
|
108
|
+
containsTable = true;
|
|
109
|
+
}
|
|
110
|
+
if (node.isTextblock) {
|
|
111
|
+
leafCount += 1;
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return true;
|
|
115
|
+
});
|
|
116
|
+
return containsTable && leafCount > LARGE_TABLE_LEAF_THRESHOLD;
|
|
117
|
+
};
|
|
98
118
|
var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration(_ref2) {
|
|
99
119
|
var doc = _ref2.doc,
|
|
100
120
|
from = _ref2.from,
|
|
@@ -107,10 +127,20 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
|
|
|
107
127
|
shouldHideDeleted = _ref2$shouldHideDelet === void 0 ? false : _ref2$shouldHideDelet,
|
|
108
128
|
_ref2$showIndicators = _ref2.showIndicators,
|
|
109
129
|
showIndicators = _ref2$showIndicators === void 0 ? false : _ref2$showIndicators,
|
|
110
|
-
diffType = _ref2.diffType
|
|
130
|
+
diffType = _ref2.diffType,
|
|
131
|
+
_ref2$coarseTableCell = _ref2.coarseTableCellsOnly,
|
|
132
|
+
coarseTableCellsOnly = _ref2$coarseTableCell === void 0 ? false : _ref2$coarseTableCell;
|
|
111
133
|
var decorations = [];
|
|
112
134
|
// Iterate over the document nodes within the range
|
|
113
135
|
doc.nodesBetween(from, to, function (node, pos) {
|
|
136
|
+
// Coarse path: only cell/header overlays are visible; table/row/paragraph
|
|
137
|
+
// decorations are redundant and cause expensive per-cell re-render.
|
|
138
|
+
if (coarseTableCellsOnly) {
|
|
139
|
+
var name = node.type.name;
|
|
140
|
+
if (name !== 'tableCell' && name !== 'tableHeader') {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
114
144
|
if (node.isBlock && (!(0, _isExtendedEnabled.isExtendedEnabled)(diffType) || pos + node.nodeSize <= to)) {
|
|
115
145
|
var nodeEnd = pos + node.nodeSize;
|
|
116
146
|
var isActive = activeIndexPos && pos === activeIndexPos.from && nodeEnd === activeIndexPos.to;
|
|
@@ -290,12 +320,18 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
290
320
|
// emit ONE inline decoration per leaf text-bearing block within the range — the text
|
|
291
321
|
// gets highlighted, and structural gaps never do.
|
|
292
322
|
var isSmartNodeLevel = diffType === 'smart' && (0, _platformFeatureFlags.fg)('platform_editor_ai_smart_diff') && (0, _helpers.smartChangeLevel)(change) === 'node';
|
|
323
|
+
// For a large inserted table, skip the per-cell inline decorations that
|
|
324
|
+
// freeze the browser on re-render. Only active in the AIFC experience.
|
|
325
|
+
var useCoarseTableDecoration = isSmartNodeLevel && (0, _expValEquals.expValEquals)('platform_editor_ai_new_aifc_editor_experience', 'isEnabled', true) && isLargeInsertedTableRange(tr.doc, change.fromB, change.toB);
|
|
293
326
|
// Whether the deleted-content widget will actually be rendered for this
|
|
294
327
|
// change. Used to decide if indicator anchor positions should be adjusted
|
|
295
328
|
// inward — when the widget is present the anchor must stay at the block
|
|
296
329
|
// boundary to keep the indicator bar continuous with the deleted content.
|
|
297
330
|
var willRenderDeletedWidget = change.deleted.length > 0 && !((0, _isExtendedEnabled.isExtendedEnabled)(diffType) && !isInverted && hideDeletedDiffs && change.inserted.length > 0);
|
|
298
|
-
if (
|
|
331
|
+
if (useCoarseTableDecoration) {
|
|
332
|
+
// Skip the O(cells) inline decorations; the cell overlays (added below)
|
|
333
|
+
// provide the highlight without the expensive content re-render.
|
|
334
|
+
} else if (isSmartNodeLevel) {
|
|
299
335
|
var _iterator2 = _createForOfIteratorHelper(leafTextblockRanges(tr.doc, change.fromB, change.toB)),
|
|
300
336
|
_step2;
|
|
301
337
|
try {
|
|
@@ -354,7 +390,8 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
354
390
|
}), {}, {
|
|
355
391
|
activeIndexPos: activeIndexPos,
|
|
356
392
|
intl: intl,
|
|
357
|
-
diffType: diffType
|
|
393
|
+
diffType: diffType,
|
|
394
|
+
coarseTableCellsOnly: useCoarseTableDecoration
|
|
358
395
|
}))));
|
|
359
396
|
}
|
|
360
397
|
if (change.deleted.length > 0) {
|
|
@@ -81,6 +81,26 @@ const leafTextblockRanges = (doc, from, to) => {
|
|
|
81
81
|
});
|
|
82
82
|
return ranges;
|
|
83
83
|
};
|
|
84
|
+
|
|
85
|
+
// A large inserted table is treated with a coarse decoration path (see below)
|
|
86
|
+
// once it has more leaf textblocks (~cells) than this threshold. Small tables
|
|
87
|
+
// keep the precise per-cell path.
|
|
88
|
+
const LARGE_TABLE_LEAF_THRESHOLD = 40;
|
|
89
|
+
const isLargeInsertedTableRange = (doc, from, to) => {
|
|
90
|
+
let containsTable = false;
|
|
91
|
+
let leafCount = 0;
|
|
92
|
+
doc.nodesBetween(from, to, node => {
|
|
93
|
+
if (node.type.name === 'table') {
|
|
94
|
+
containsTable = true;
|
|
95
|
+
}
|
|
96
|
+
if (node.isTextblock) {
|
|
97
|
+
leafCount += 1;
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return true;
|
|
101
|
+
});
|
|
102
|
+
return containsTable && leafCount > LARGE_TABLE_LEAF_THRESHOLD;
|
|
103
|
+
};
|
|
84
104
|
const calculateNodesForBlockDecoration = ({
|
|
85
105
|
doc,
|
|
86
106
|
from,
|
|
@@ -90,11 +110,20 @@ const calculateNodesForBlockDecoration = ({
|
|
|
90
110
|
activeIndexPos,
|
|
91
111
|
shouldHideDeleted = false,
|
|
92
112
|
showIndicators = false,
|
|
93
|
-
diffType
|
|
113
|
+
diffType,
|
|
114
|
+
coarseTableCellsOnly = false
|
|
94
115
|
}) => {
|
|
95
116
|
const decorations = [];
|
|
96
117
|
// Iterate over the document nodes within the range
|
|
97
118
|
doc.nodesBetween(from, to, (node, pos) => {
|
|
119
|
+
// Coarse path: only cell/header overlays are visible; table/row/paragraph
|
|
120
|
+
// decorations are redundant and cause expensive per-cell re-render.
|
|
121
|
+
if (coarseTableCellsOnly) {
|
|
122
|
+
const name = node.type.name;
|
|
123
|
+
if (name !== 'tableCell' && name !== 'tableHeader') {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
98
127
|
if (node.isBlock && (!isExtendedEnabled(diffType) || pos + node.nodeSize <= to)) {
|
|
99
128
|
const nodeEnd = pos + node.nodeSize;
|
|
100
129
|
const isActive = activeIndexPos && pos === activeIndexPos.from && nodeEnd === activeIndexPos.to;
|
|
@@ -264,12 +293,18 @@ const calculateDiffDecorationsInner = ({
|
|
|
264
293
|
// emit ONE inline decoration per leaf text-bearing block within the range — the text
|
|
265
294
|
// gets highlighted, and structural gaps never do.
|
|
266
295
|
const isSmartNodeLevel = diffType === 'smart' && fg('platform_editor_ai_smart_diff') && smartChangeLevel(change) === 'node';
|
|
296
|
+
// For a large inserted table, skip the per-cell inline decorations that
|
|
297
|
+
// freeze the browser on re-render. Only active in the AIFC experience.
|
|
298
|
+
const useCoarseTableDecoration = isSmartNodeLevel && expValEquals('platform_editor_ai_new_aifc_editor_experience', 'isEnabled', true) && isLargeInsertedTableRange(tr.doc, change.fromB, change.toB);
|
|
267
299
|
// Whether the deleted-content widget will actually be rendered for this
|
|
268
300
|
// change. Used to decide if indicator anchor positions should be adjusted
|
|
269
301
|
// inward — when the widget is present the anchor must stay at the block
|
|
270
302
|
// boundary to keep the indicator bar continuous with the deleted content.
|
|
271
303
|
const willRenderDeletedWidget = change.deleted.length > 0 && !(isExtendedEnabled(diffType) && !isInverted && hideDeletedDiffs && change.inserted.length > 0);
|
|
272
|
-
if (
|
|
304
|
+
if (useCoarseTableDecoration) {
|
|
305
|
+
// Skip the O(cells) inline decorations; the cell overlays (added below)
|
|
306
|
+
// provide the highlight without the expensive content re-render.
|
|
307
|
+
} else if (isSmartNodeLevel) {
|
|
273
308
|
for (const [from, to] of leafTextblockRanges(tr.doc, change.fromB, change.toB)) {
|
|
274
309
|
decorations.push(...createInlineChangedDecoration({
|
|
275
310
|
change: {
|
|
@@ -319,7 +354,8 @@ const calculateDiffDecorationsInner = ({
|
|
|
319
354
|
}),
|
|
320
355
|
activeIndexPos,
|
|
321
356
|
intl,
|
|
322
|
-
diffType
|
|
357
|
+
diffType,
|
|
358
|
+
coarseTableCellsOnly: useCoarseTableDecoration
|
|
323
359
|
}));
|
|
324
360
|
}
|
|
325
361
|
if (change.deleted.length > 0) {
|
|
@@ -88,6 +88,26 @@ var leafTextblockRanges = function leafTextblockRanges(doc, from, to) {
|
|
|
88
88
|
});
|
|
89
89
|
return ranges;
|
|
90
90
|
};
|
|
91
|
+
|
|
92
|
+
// A large inserted table is treated with a coarse decoration path (see below)
|
|
93
|
+
// once it has more leaf textblocks (~cells) than this threshold. Small tables
|
|
94
|
+
// keep the precise per-cell path.
|
|
95
|
+
var LARGE_TABLE_LEAF_THRESHOLD = 40;
|
|
96
|
+
var isLargeInsertedTableRange = function isLargeInsertedTableRange(doc, from, to) {
|
|
97
|
+
var containsTable = false;
|
|
98
|
+
var leafCount = 0;
|
|
99
|
+
doc.nodesBetween(from, to, function (node) {
|
|
100
|
+
if (node.type.name === 'table') {
|
|
101
|
+
containsTable = true;
|
|
102
|
+
}
|
|
103
|
+
if (node.isTextblock) {
|
|
104
|
+
leafCount += 1;
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
});
|
|
109
|
+
return containsTable && leafCount > LARGE_TABLE_LEAF_THRESHOLD;
|
|
110
|
+
};
|
|
91
111
|
var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration(_ref2) {
|
|
92
112
|
var doc = _ref2.doc,
|
|
93
113
|
from = _ref2.from,
|
|
@@ -100,10 +120,20 @@ var calculateNodesForBlockDecoration = function calculateNodesForBlockDecoration
|
|
|
100
120
|
shouldHideDeleted = _ref2$shouldHideDelet === void 0 ? false : _ref2$shouldHideDelet,
|
|
101
121
|
_ref2$showIndicators = _ref2.showIndicators,
|
|
102
122
|
showIndicators = _ref2$showIndicators === void 0 ? false : _ref2$showIndicators,
|
|
103
|
-
diffType = _ref2.diffType
|
|
123
|
+
diffType = _ref2.diffType,
|
|
124
|
+
_ref2$coarseTableCell = _ref2.coarseTableCellsOnly,
|
|
125
|
+
coarseTableCellsOnly = _ref2$coarseTableCell === void 0 ? false : _ref2$coarseTableCell;
|
|
104
126
|
var decorations = [];
|
|
105
127
|
// Iterate over the document nodes within the range
|
|
106
128
|
doc.nodesBetween(from, to, function (node, pos) {
|
|
129
|
+
// Coarse path: only cell/header overlays are visible; table/row/paragraph
|
|
130
|
+
// decorations are redundant and cause expensive per-cell re-render.
|
|
131
|
+
if (coarseTableCellsOnly) {
|
|
132
|
+
var name = node.type.name;
|
|
133
|
+
if (name !== 'tableCell' && name !== 'tableHeader') {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
107
137
|
if (node.isBlock && (!isExtendedEnabled(diffType) || pos + node.nodeSize <= to)) {
|
|
108
138
|
var nodeEnd = pos + node.nodeSize;
|
|
109
139
|
var isActive = activeIndexPos && pos === activeIndexPos.from && nodeEnd === activeIndexPos.to;
|
|
@@ -283,12 +313,18 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
283
313
|
// emit ONE inline decoration per leaf text-bearing block within the range — the text
|
|
284
314
|
// gets highlighted, and structural gaps never do.
|
|
285
315
|
var isSmartNodeLevel = diffType === 'smart' && fg('platform_editor_ai_smart_diff') && smartChangeLevel(change) === 'node';
|
|
316
|
+
// For a large inserted table, skip the per-cell inline decorations that
|
|
317
|
+
// freeze the browser on re-render. Only active in the AIFC experience.
|
|
318
|
+
var useCoarseTableDecoration = isSmartNodeLevel && expValEquals('platform_editor_ai_new_aifc_editor_experience', 'isEnabled', true) && isLargeInsertedTableRange(tr.doc, change.fromB, change.toB);
|
|
286
319
|
// Whether the deleted-content widget will actually be rendered for this
|
|
287
320
|
// change. Used to decide if indicator anchor positions should be adjusted
|
|
288
321
|
// inward — when the widget is present the anchor must stay at the block
|
|
289
322
|
// boundary to keep the indicator bar continuous with the deleted content.
|
|
290
323
|
var willRenderDeletedWidget = change.deleted.length > 0 && !(isExtendedEnabled(diffType) && !isInverted && hideDeletedDiffs && change.inserted.length > 0);
|
|
291
|
-
if (
|
|
324
|
+
if (useCoarseTableDecoration) {
|
|
325
|
+
// Skip the O(cells) inline decorations; the cell overlays (added below)
|
|
326
|
+
// provide the highlight without the expensive content re-render.
|
|
327
|
+
} else if (isSmartNodeLevel) {
|
|
292
328
|
var _iterator2 = _createForOfIteratorHelper(leafTextblockRanges(tr.doc, change.fromB, change.toB)),
|
|
293
329
|
_step2;
|
|
294
330
|
try {
|
|
@@ -347,7 +383,8 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref4
|
|
|
347
383
|
}), {}, {
|
|
348
384
|
activeIndexPos: activeIndexPos,
|
|
349
385
|
intl: intl,
|
|
350
|
-
diffType: diffType
|
|
386
|
+
diffType: diffType,
|
|
387
|
+
coarseTableCellsOnly: useCoarseTableDecoration
|
|
351
388
|
}))));
|
|
352
389
|
}
|
|
353
390
|
if (change.deleted.length > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-show-diff",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.10",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"@atlaskit/editor-prosemirror": "^8.0.0",
|
|
28
28
|
"@atlaskit/editor-tables": "^3.0.0",
|
|
29
29
|
"@atlaskit/platform-feature-flags": "^2.1.0",
|
|
30
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
30
|
+
"@atlaskit/tmp-editor-statsig": "^150.0.0",
|
|
31
31
|
"@atlaskit/tokens": "^16.7.0",
|
|
32
32
|
"@babel/runtime": "^7.0.0",
|
|
33
33
|
"@compiled/react": "^1.0.2",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"prosemirror-changeset": "^2.3.1"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@atlaskit/adf-utils": "^20.
|
|
39
|
+
"@atlaskit/adf-utils": "^20.7.0",
|
|
40
40
|
"@atlaskit/button": "^25.1.0",
|
|
41
41
|
"@atlaskit/css": "^1.0.0",
|
|
42
42
|
"@atlaskit/dropdown-menu": "^18.0.0",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"react-intl": "^7.0.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@atlaskit/editor-common": "^119.
|
|
56
|
+
"@atlaskit/editor-common": "^119.9.0",
|
|
57
57
|
"react": "^18.2.0 || ^19.2.0"
|
|
58
58
|
},
|
|
59
59
|
"techstack": {
|