@atlaskit/editor-plugin-show-diff 16.0.2 → 16.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +17 -2
- package/dist/cjs/pm-plugins/calculateDiff/isOpenTokenOnlyChange.js +32 -0
- package/dist/cjs/pm-plugins/decorations/createAnchorDecorationWidgets.js +13 -1
- package/dist/cjs/pm-plugins/decorations/createContributorTagWidget.js +20 -1
- package/dist/cjs/pm-plugins/decorations/extractContributorTags.js +121 -21
- package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeView.js +6 -6
- package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +8 -10
- package/dist/cjs/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +2 -1
- package/dist/cjs/ui/ContributorTag/buildContributorTagDom.js +25 -1
- package/dist/cjs/ui/ContributorTag/contributorTagController.js +31 -9
- package/dist/es2019/pm-plugins/calculateDiff/calculateDiffDecorations.js +17 -2
- package/dist/es2019/pm-plugins/calculateDiff/isOpenTokenOnlyChange.js +27 -0
- package/dist/es2019/pm-plugins/decorations/createAnchorDecorationWidgets.js +13 -1
- package/dist/es2019/pm-plugins/decorations/createContributorTagWidget.js +18 -1
- package/dist/es2019/pm-plugins/decorations/extractContributorTags.js +70 -10
- package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeView.js +6 -6
- package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +6 -8
- package/dist/es2019/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +2 -1
- package/dist/es2019/ui/ContributorTag/buildContributorTagDom.js +24 -0
- package/dist/es2019/ui/ContributorTag/contributorTagController.js +30 -10
- package/dist/esm/pm-plugins/calculateDiff/calculateDiffDecorations.js +17 -2
- package/dist/esm/pm-plugins/calculateDiff/isOpenTokenOnlyChange.js +26 -0
- package/dist/esm/pm-plugins/decorations/createAnchorDecorationWidgets.js +13 -1
- package/dist/esm/pm-plugins/decorations/createContributorTagWidget.js +20 -1
- package/dist/esm/pm-plugins/decorations/extractContributorTags.js +121 -21
- package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeView.js +6 -6
- package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.js +8 -10
- package/dist/esm/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.legacy.js +2 -1
- package/dist/esm/ui/ContributorTag/buildContributorTagDom.js +24 -0
- package/dist/esm/ui/ContributorTag/contributorTagController.js +32 -10
- package/dist/types/pm-plugins/calculateDiff/isOpenTokenOnlyChange.d.ts +22 -0
- package/dist/types/pm-plugins/decorations/extractContributorTags.d.ts +14 -1
- package/dist/types/pm-plugins/decorations/utils/wrapBlockNodeViewStyles.d.ts +2 -3
- package/dist/types/ui/ContributorTag/buildContributorTagDom.d.ts +7 -0
- package/dist/types/ui/ContributorTag/contributorTagController.d.ts +11 -0
- package/package.json +5 -5
|
@@ -17,10 +17,12 @@ import { extractDiffDescriptors } from '../decorations/decorationKeys';
|
|
|
17
17
|
import { extractContributorTags } from '../decorations/extractContributorTags';
|
|
18
18
|
import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
|
|
19
19
|
import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
|
|
20
|
+
import { getScrollableDecorations } from '../getScrollableDecorations';
|
|
20
21
|
import { getDefaultDiffType, isExtendedEnabled } from '../isExtendedEnabled';
|
|
21
22
|
import { diffBySteps } from './diffBySteps';
|
|
22
23
|
import { groupChangesByBlock } from './groupChangesByBlock';
|
|
23
24
|
import { isMarkOnlyChange } from './isMarkOnlyChange';
|
|
25
|
+
import { isOpenTokenOnlyChange } from './isOpenTokenOnlyChange';
|
|
24
26
|
import { optimizeChanges } from './optimizeChanges';
|
|
25
27
|
import { selectTokenEncoder } from './selectTokenEncoder';
|
|
26
28
|
import { collapseOverlappingChanges, simplifyChangesWithAttribution } from './simplifyChangesWithAttribution';
|
|
@@ -463,6 +465,16 @@ const calculateDiffDecorationsInner = ({
|
|
|
463
465
|
newDoc: tr.doc
|
|
464
466
|
});
|
|
465
467
|
|
|
468
|
+
// The deleted side of a change over a node's open token is an attribute state rather than
|
|
469
|
+
// content, so there is nothing for the deleted-content widget to draw. Decided here, with
|
|
470
|
+
// the other deleted-side suppressions, so the widget is never asked for a slice it can only
|
|
471
|
+
// render as an empty copy of the block (EDITOR-8912). Its inserted side is untouched, and
|
|
472
|
+
// the node's content change is a change of its own.
|
|
473
|
+
const hasNoDeletedContent = fg('platform_editor_ai_show_diff_patch_1') && change.deleted.length > 0 && isOpenTokenOnlyChange({
|
|
474
|
+
change,
|
|
475
|
+
originalDoc
|
|
476
|
+
});
|
|
477
|
+
|
|
466
478
|
// Hoisted because it decides BOTH where the deleted widget is anchored and — since the
|
|
467
479
|
// widget pins whichever end of the range it sits at — how the indicator anchors below are
|
|
468
480
|
// allowed to move.
|
|
@@ -572,7 +584,7 @@ const calculateDiffDecorationsInner = ({
|
|
|
572
584
|
coarseTableCellsOnly: useCoarseTableDecoration
|
|
573
585
|
}));
|
|
574
586
|
}
|
|
575
|
-
if (change.deleted.length > 0 && !isMarkOnly) {
|
|
587
|
+
if (change.deleted.length > 0 && !isMarkOnly && !hasNoDeletedContent) {
|
|
576
588
|
const shouldHideDeleted = shouldHideDeletedSide({
|
|
577
589
|
change,
|
|
578
590
|
diffType,
|
|
@@ -732,7 +744,10 @@ const calculateDiffDecorationsInner = ({
|
|
|
732
744
|
});
|
|
733
745
|
const decorationSet = DecorationSet.empty.add(tr.doc, decorations);
|
|
734
746
|
return {
|
|
735
|
-
contributorTags: showContributorTags ? extractContributorTags(decorationSet, contributors
|
|
747
|
+
contributorTags: showContributorTags ? extractContributorTags(decorationSet, contributors, activeIndexPos,
|
|
748
|
+
// The stops the step buttons walk, so a stop cannot hold a second tag for one
|
|
749
|
+
// contributor that navigation can never reach.
|
|
750
|
+
getScrollableDecorations(decorationSet, tr.doc, diffType)) : [],
|
|
736
751
|
decorations: decorationSet,
|
|
737
752
|
diffDescriptors: extractDiffDescriptors(decorationSet)
|
|
738
753
|
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a change spans nothing but a block node's open token, so its deleted side carries no
|
|
3
|
+
* content.
|
|
4
|
+
*
|
|
5
|
+
* The attribute-aware token encoder folds a node's diffable attributes into its open token, so a
|
|
6
|
+
* same-type replacement — an AI suggestion rewriting a code block — is reported as two changes: one
|
|
7
|
+
* over the single position of that token, carrying the attribute change, and one for the content.
|
|
8
|
+
* Slicing the first yields the node with none of its content, which leaves the deleted-content
|
|
9
|
+
* widget nothing to draw but an empty copy of the block (EDITOR-8912). The content change is a
|
|
10
|
+
* change of its own and is decorated in place.
|
|
11
|
+
*
|
|
12
|
+
* A whole node is not matched: its range covers its close token too. Neither is an empty leaf (a
|
|
13
|
+
* `rule`, a `blockCard`), which is one position but slices closed rather than open.
|
|
14
|
+
*/
|
|
15
|
+
export const isOpenTokenOnlyChange = ({
|
|
16
|
+
change,
|
|
17
|
+
originalDoc
|
|
18
|
+
}) => {
|
|
19
|
+
if (change.toA - change.fromA !== 1) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
const slice = originalDoc.slice(change.fromA, change.toA);
|
|
23
|
+
// `childCount === 1` already means `firstChild` is there; the optional chain is for the type,
|
|
24
|
+
// which has it nullable.
|
|
25
|
+
const node = slice.content.firstChild;
|
|
26
|
+
return (slice.openStart > 0 || slice.openEnd > 0) && slice.content.childCount === 1 && (node === null || node === void 0 ? void 0 : node.isBlock) === true && node.content.size === 0;
|
|
27
|
+
};
|
|
@@ -44,6 +44,16 @@ const edgeCases = (doc, from) => {
|
|
|
44
44
|
nodeStart,
|
|
45
45
|
beforePos
|
|
46
46
|
} = resolved;
|
|
47
|
+
if (node.type.name === 'layoutSection' && fg('platform_editor_ai_show_diff_patch_1')) {
|
|
48
|
+
// Columns extend past the node-view wrapper via negative margins (12px or 20px).
|
|
49
|
+
// Measure their container so the indicator stays outside the diff outline, including
|
|
50
|
+
// breakout layouts and after responsive resizing, without changing the column geometry.
|
|
51
|
+
return {
|
|
52
|
+
beforePos,
|
|
53
|
+
measurePos: beforePos,
|
|
54
|
+
measureSelector: '[data-layout-section]'
|
|
55
|
+
};
|
|
56
|
+
}
|
|
47
57
|
|
|
48
58
|
/**
|
|
49
59
|
* All resizable nodes will need dynamic calculations of the block indicator left anchor
|
|
@@ -152,10 +162,12 @@ export const createLeftAnchorWidget = ({
|
|
|
152
162
|
anchor.style.setProperty('transform', 'translateX(-50%)');
|
|
153
163
|
wrapper.appendChild(anchor);
|
|
154
164
|
const measureWidth = () => {
|
|
165
|
+
var _nodeDOM$querySelecto;
|
|
155
166
|
if (getPos() === undefined || edgeCase.measurePos === undefined) {
|
|
156
167
|
return;
|
|
157
168
|
}
|
|
158
|
-
const
|
|
169
|
+
const nodeDOM = view.nodeDOM(edgeCase.measurePos);
|
|
170
|
+
const dom = edgeCase.measureSelector && nodeDOM instanceof HTMLElement ? (_nodeDOM$querySelecto = nodeDOM.querySelector(edgeCase.measureSelector)) !== null && _nodeDOM$querySelecto !== void 0 ? _nodeDOM$querySelecto : nodeDOM : nodeDOM;
|
|
159
171
|
if (dom instanceof HTMLElement) {
|
|
160
172
|
// The left anchor only needs the container width so the
|
|
161
173
|
// IndicatorBar can align against the block's horizontal extent.
|
|
@@ -39,7 +39,24 @@ export const mountContributorTag = ({
|
|
|
39
39
|
diffId
|
|
40
40
|
});
|
|
41
41
|
controller.mount(host);
|
|
42
|
-
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Kept alive when ProseMirror only rebuilt the widget desc around this same host: a document
|
|
45
|
+
* change remaps the decoration and fires `destroy`, but an element `toDOM` is reused verbatim
|
|
46
|
+
* and runs no mount callback, so tearing down here left an active change with no tag
|
|
47
|
+
* (EDITOR-8971).
|
|
48
|
+
*
|
|
49
|
+
* Deferred, because the host is still attached while that update is in flight. A host outside a
|
|
50
|
+
* live editor root is a real removal — including the view being destroyed, which drops the root.
|
|
51
|
+
*/
|
|
52
|
+
return {
|
|
53
|
+
destroy: () => queueMicrotask(() => {
|
|
54
|
+
var _mountContext$getEdit;
|
|
55
|
+
if (!host.isConnected || !((_mountContext$getEdit = mountContext.getEditorRoot()) !== null && _mountContext$getEdit !== void 0 && _mountContext$getEdit.contains(host))) {
|
|
56
|
+
controller.destroy();
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
};
|
|
43
60
|
};
|
|
44
61
|
export const unmountContributorTag = mount => {
|
|
45
62
|
mount === null || mount === void 0 ? void 0 : mount.destroy();
|
|
@@ -34,12 +34,44 @@ const leadsReplacement = widget => fg('confluence_ncs_step_diffing_version_histo
|
|
|
34
34
|
*/
|
|
35
35
|
const isSameBlockChange = (inner, block) => inner.spec.attributionKey === block.spec.attributionKey && (block.from <= inner.from && inner.to <= block.to || inner.from <= block.from && block.to <= inner.to);
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Which of two changes in the same range leads, and so is the one a tag captions. Position first,
|
|
39
|
+
* then `side`, since deleted content shares its `from` with the content that replaced it and paints
|
|
40
|
+
* above; then the narrower range, so a change nested in another captions itself.
|
|
41
|
+
*/
|
|
42
|
+
const byLeadingPosition = (a, b) => {
|
|
43
|
+
var _a$decoration$spec$si, _b$decoration$spec$si;
|
|
44
|
+
return a.decoration.from - b.decoration.from || ((_a$decoration$spec$si = a.decoration.spec.side) !== null && _a$decoration$spec$si !== void 0 ? _a$decoration$spec$si : 0) - ((_b$decoration$spec$si = b.decoration.spec.side) !== null && _b$decoration$spec$si !== void 0 ? _b$decoration$spec$si : 0) || a.decoration.to - a.decoration.from - (b.decoration.to - b.decoration.from);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** The targets a navigation range wholly covers, leader first. */
|
|
48
|
+
const containedBy = (targets, {
|
|
49
|
+
from,
|
|
50
|
+
to
|
|
51
|
+
}) => targets.filter(({
|
|
52
|
+
decoration
|
|
53
|
+
}) => from <= decoration.from && decoration.to <= to).sort(byLeadingPosition);
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The one tag a navigation step reveals. `spec.isActive` is no use here: it covers everything the
|
|
57
|
+
* group's union range touches, so several tags revealed over each other (EDITOR-8971). Hence
|
|
58
|
+
* containment, and the leading change of what it covers.
|
|
59
|
+
*/
|
|
60
|
+
const resolveActiveTarget = (surviving, activeIndexPos) => containedBy(surviving, activeIndexPos)[0];
|
|
61
|
+
|
|
37
62
|
/**
|
|
38
63
|
* One model per diff decoration whose attribution resolves to a supplied contributor; anything
|
|
39
64
|
* unattributed, untaggable or unresolved is skipped. A replacement's two decorations are collapsed
|
|
40
65
|
* into a single tag, on whichever half renders first — see `isSameChange` and `leadsReplacement`.
|
|
66
|
+
*
|
|
67
|
+
* `activeIndexPos`, when given, reveals exactly one of the tags — see `resolveActiveTarget`.
|
|
68
|
+
* Absent, each tag keeps the active state its own decoration was drawn with.
|
|
69
|
+
*
|
|
70
|
+
* `stops`, when given, is the navigation stop list the step buttons walk
|
|
71
|
+
* (`getScrollableDecorations`). One contributor cannot hold two tags in one stop, since only the
|
|
72
|
+
* leading one would ever be reachable. Absent, every decoration keeps its own tag.
|
|
41
73
|
*/
|
|
42
|
-
export const extractContributorTags = (decorations, contributors) => {
|
|
74
|
+
export const extractContributorTags = (decorations, contributors, activeIndexPos, stops) => {
|
|
43
75
|
if (!contributors) {
|
|
44
76
|
return [];
|
|
45
77
|
}
|
|
@@ -77,10 +109,15 @@ export const extractContributorTags = (decorations, contributors) => {
|
|
|
77
109
|
const linkedDiffIds = new Map();
|
|
78
110
|
const folded = new Set();
|
|
79
111
|
const fold = (host, target) => {
|
|
80
|
-
var _linkedDiffIds$get;
|
|
112
|
+
var _linkedDiffIds$get, _linkedDiffIds$get2;
|
|
81
113
|
folded.add(target);
|
|
82
114
|
const hostDiffId = host.decoration.spec.diffId;
|
|
83
|
-
|
|
115
|
+
const targetDiffId = target.decoration.spec.diffId;
|
|
116
|
+
// A target that already hosts folded tags hands them up, so no hover target is orphaned when
|
|
117
|
+
// one host folds into another.
|
|
118
|
+
const inherited = (_linkedDiffIds$get = linkedDiffIds.get(targetDiffId)) !== null && _linkedDiffIds$get !== void 0 ? _linkedDiffIds$get : [];
|
|
119
|
+
linkedDiffIds.delete(targetDiffId);
|
|
120
|
+
linkedDiffIds.set(hostDiffId, [...((_linkedDiffIds$get2 = linkedDiffIds.get(hostDiffId)) !== null && _linkedDiffIds$get2 !== void 0 ? _linkedDiffIds$get2 : []), targetDiffId, ...inherited]);
|
|
84
121
|
};
|
|
85
122
|
for (const target of targets) {
|
|
86
123
|
const {
|
|
@@ -120,15 +157,38 @@ export const extractContributorTags = (decorations, contributors) => {
|
|
|
120
157
|
fold(host, target);
|
|
121
158
|
}
|
|
122
159
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
160
|
+
|
|
161
|
+
// One tag per contributor per navigation stop. The folds above only catch a replacement's two
|
|
162
|
+
// halves and a block's own highlights; two of one contributor's changes that merely touch are a
|
|
163
|
+
// single stop (`groupTouchingDecorations`) yet kept a tag each, so the stop's trailing tag was
|
|
164
|
+
// drawn but could never be stepped to (EDITOR-8971). It folds into the leading tag of its
|
|
165
|
+
// contributor, staying a hover target. Contributors are kept apart: a stop spanning two of them
|
|
166
|
+
// still captions each, rather than crediting one for the other's change.
|
|
167
|
+
for (const stop of stops !== null && stops !== void 0 ? stops : []) {
|
|
168
|
+
const byContributor = new Map();
|
|
169
|
+
for (const target of containedBy(targets.filter(target => !folded.has(target)), stop)) {
|
|
170
|
+
var _target$decoration$sp, _byContributor$get;
|
|
171
|
+
const key = (_target$decoration$sp = target.decoration.spec.attributionKey) !== null && _target$decoration$sp !== void 0 ? _target$decoration$sp : '';
|
|
172
|
+
byContributor.set(key, [...((_byContributor$get = byContributor.get(key)) !== null && _byContributor$get !== void 0 ? _byContributor$get : []), target]);
|
|
127
173
|
}
|
|
128
|
-
|
|
174
|
+
for (const [leader, ...trailing] of byContributor.values()) {
|
|
175
|
+
trailing.forEach(target => fold(leader, target));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const surviving = targets.filter(target => !folded.has(target));
|
|
179
|
+
const activeTarget = activeIndexPos === undefined ? undefined : resolveActiveTarget(surviving, activeIndexPos);
|
|
180
|
+
return surviving.map(target => {
|
|
181
|
+
const {
|
|
182
|
+
contributor,
|
|
183
|
+
decoration: {
|
|
184
|
+
spec
|
|
185
|
+
}
|
|
186
|
+
} = target;
|
|
129
187
|
const connected = contributor.connectedToKey ? contributors[contributor.connectedToKey] : undefined;
|
|
130
188
|
const connectedContributor = connected ? toTagContributor(connected) : undefined;
|
|
131
189
|
const linked = linkedDiffIds.get(spec.diffId);
|
|
190
|
+
// Only the navigated tag reveals; with no active range, the decoration's own state stands.
|
|
191
|
+
const isActive = activeIndexPos === undefined ? spec.isActive : target === activeTarget;
|
|
132
192
|
return {
|
|
133
193
|
contributor: toTagContributor(contributor),
|
|
134
194
|
diffId: spec.diffId,
|
|
@@ -138,8 +198,8 @@ export const extractContributorTags = (decorations, contributors) => {
|
|
|
138
198
|
...(spec.colorScheme ? {
|
|
139
199
|
colorScheme: spec.colorScheme
|
|
140
200
|
} : {}),
|
|
141
|
-
...(
|
|
142
|
-
isActive
|
|
201
|
+
...(isActive !== undefined ? {
|
|
202
|
+
isActive
|
|
143
203
|
} : {}),
|
|
144
204
|
...(spec.isInserted !== undefined ? {
|
|
145
205
|
isInserted: spec.isInserted
|
|
@@ -206,25 +206,25 @@ const applyMultiContainerLikeStyles = ({
|
|
|
206
206
|
const targetNodeName = expValEquals('platform_editor_nest_table_in_panel', 'isEnabled', true) ? getBaseNodeTypeName(targetNode.type) : targetNode.type.name;
|
|
207
207
|
const nodeSpecificStyle = getChangedNodeStyle(targetNodeName, colorScheme, isInserted, isActive, diffType, hideAddedDiffsUnderline) || '';
|
|
208
208
|
if (targetNode.type.name === 'decisionList') {
|
|
209
|
-
const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
|
|
209
|
+
const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle(colorScheme);
|
|
210
210
|
element.querySelectorAll('li').forEach(listItem => {
|
|
211
211
|
const currentListItemStyle = listItem.getAttribute('style') || '';
|
|
212
|
-
listItem.setAttribute('style', `${currentListItemStyle}${nestedInsertedNodeStyle}`);
|
|
212
|
+
listItem.setAttribute('style', fg('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentListItemStyle, nestedInsertedNodeStyle) : `${currentListItemStyle}${nestedInsertedNodeStyle}`);
|
|
213
213
|
});
|
|
214
214
|
} else if (targetNode.type.name === 'layoutSection') {
|
|
215
|
-
const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
|
|
215
|
+
const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle(colorScheme);
|
|
216
216
|
element.querySelectorAll('[data-layout-column="true"]').forEach(section => {
|
|
217
217
|
const currentSectionStyle = section.getAttribute('style') || '';
|
|
218
|
-
section.setAttribute('style', `${currentSectionStyle}${nestedInsertedNodeStyle}`);
|
|
218
|
+
section.setAttribute('style', fg('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentSectionStyle, nestedInsertedNodeStyle) : `${currentSectionStyle}${nestedInsertedNodeStyle}`);
|
|
219
219
|
});
|
|
220
220
|
} else if (targetNode.type.name === 'taskList') {
|
|
221
|
-
const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle();
|
|
221
|
+
const nestedInsertedNodeStyle = resolveNestedInsertedNodeStyle(colorScheme);
|
|
222
222
|
element.querySelectorAll('li').forEach(listItem => {
|
|
223
223
|
const currentListItemStyle = listItem.getAttribute('style') || '';
|
|
224
224
|
listItem.setAttribute('style', `${currentListItemStyle}${nestedInsertedNodeStyle}`);
|
|
225
225
|
});
|
|
226
226
|
}
|
|
227
|
-
element.setAttribute('style', `${currentStyle};${nodeSpecificStyle}`);
|
|
227
|
+
element.setAttribute('style', fg('platform_editor_ai_show_diff_patch_1') ? combineStyles(currentStyle, nodeSpecificStyle) : `${currentStyle};${nodeSpecificStyle}`);
|
|
228
228
|
};
|
|
229
229
|
const combineStyles = (currentStyle, appendedStyle) => {
|
|
230
230
|
const separator = currentStyle && appendedStyle && !currentStyle.trimEnd().endsWith(';') ? '; ' : '';
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* keeping the `*Next` bodies.
|
|
12
12
|
*/
|
|
13
13
|
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
14
|
+
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
14
15
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
15
16
|
import { isExtendedEnabled } from '../../isExtendedEnabled';
|
|
16
17
|
import { buildAddedCellOverlayRoundedStyle, buildAddedCellOverlayStyle, buildAddedCellOverlayStyleNew, buildDeletedCellOverlayRoundedStyle, buildDeletedCellOverlayStyle, buildDeletedInlineContentStyle, buildDeletedInlineContentStyleExtended, buildDeletedLozengeActiveStyle, buildDeletedLozengeStyle, buildDeletedNodeCSSVariables, buildDeletedQuoteNodeWithLozengeStyle, buildDeletedStrikethroughLine, buildDeletedWrappedBlockOutline, buildInsertedBlockNodeStyle, buildInsertedInlineStyle, buildInsertStyleInBlockExtended, buildInsertStyleInBlockExtendedNoUnderline, buildInsertStyleNode } from '../colorSchemes/factory';
|
|
@@ -19,9 +20,7 @@ import { getChangedContentStyleLegacy, getChangedNodeStyleLegacy, getDeletedCont
|
|
|
19
20
|
const getColorScheme = colorScheme => colorSchemeRegistry[colorScheme !== null && colorScheme !== void 0 ? colorScheme : 'standard'];
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
-
* traditional diff shows purple here. Pre-existing: these call sites predate traditional.
|
|
24
|
-
* Preserved as-is; see EDITOR-8281.
|
|
23
|
+
* Preserve the historical purple nested outlines when the layout/decision diff patch is off.
|
|
25
24
|
*/
|
|
26
25
|
const nestedContentScheme = standardScheme;
|
|
27
26
|
|
|
@@ -49,7 +48,7 @@ const getChangedNodeStyleNext = (nodeName, colorScheme, isInserted = false, isAc
|
|
|
49
48
|
const colors = getColorScheme(colorScheme);
|
|
50
49
|
if (isExtendedEnabled(diffType) && isInserted) {
|
|
51
50
|
if (isMultiContainerBlockNode(nodeName)) {
|
|
52
|
-
return hideAddedDiffsUnderline ? buildInsertStyleInBlockExtendedNoUnderline(nestedContentScheme) : buildInsertStyleInBlockExtended(nestedContentScheme);
|
|
51
|
+
return hideAddedDiffsUnderline || fg('platform_editor_ai_show_diff_patch_1') ? buildInsertStyleInBlockExtendedNoUnderline(nestedContentScheme) : buildInsertStyleInBlockExtended(nestedContentScheme);
|
|
53
52
|
}
|
|
54
53
|
if (isTextLikeBlockNode(nodeName)) {
|
|
55
54
|
return undefined;
|
|
@@ -101,7 +100,7 @@ const resolveRemovedLozengeStyleNext = (colorScheme, isActive) => {
|
|
|
101
100
|
const colors = getColorScheme(colorScheme);
|
|
102
101
|
return isActive ? buildDeletedLozengeActiveStyle(colors) : buildDeletedLozengeStyle(colors);
|
|
103
102
|
};
|
|
104
|
-
const resolveNestedInsertedNodeStyleNext =
|
|
103
|
+
const resolveNestedInsertedNodeStyleNext = colorScheme => buildInsertStyleNode(fg('platform_editor_ai_show_diff_patch_1') ? getColorScheme(colorScheme) : nestedContentScheme);
|
|
105
104
|
|
|
106
105
|
// Only 'stateful' schemes have a resting ring.
|
|
107
106
|
const hasRestingDeletedRingNext = colorScheme => getColorScheme(colorScheme).deletedNodeEmphasis === 'stateful';
|
|
@@ -138,10 +137,9 @@ export const resolveRemovedLozengeStyle = (colorScheme, isActive) => isExperimen
|
|
|
138
137
|
|
|
139
138
|
/**
|
|
140
139
|
* Style for inserted content nested inside a multi-container or list node — the `decisionList` and
|
|
141
|
-
* `taskList` `li`s and the `layoutSection` columns.
|
|
142
|
-
* `nestedContentScheme` above.
|
|
140
|
+
* `taskList` `li`s and the `layoutSection` columns.
|
|
143
141
|
*/
|
|
144
|
-
export const resolveNestedInsertedNodeStyle =
|
|
142
|
+
export const resolveNestedInsertedNodeStyle = colorScheme => isExperimentEnabled('platform_editor_show_diff_color_scheme_refactor') ? resolveNestedInsertedNodeStyleNext(colorScheme) : resolveNestedInsertedNodeStyleLegacy();
|
|
145
143
|
|
|
146
144
|
/**
|
|
147
145
|
* Whether the colour scheme draws a resting (non-active) ring on a deleted media/embed node, which
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* `colorSchemes/standard.ts`, `colorSchemes/traditional.ts` (EDITOR-8281).
|
|
10
10
|
*/
|
|
11
11
|
import { convertToInlineCss } from '@atlaskit/editor-common/lazy-node-view';
|
|
12
|
+
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
12
13
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
13
14
|
import { isExtendedEnabled } from '../../isExtendedEnabled';
|
|
14
15
|
import { deletedBlockOutline, deletedBlockOutlineActive, deletedBlockOutlineRounded, deletedBlockOutlineRoundedActive, deletedContentStyleUnbounded, deletedInlineContentStyleExtended, deletedStyleQuoteNodeWithLozenge, deletedStyleQuoteNodeWithLozengeActive, editingContentStyleInBlockExtended, editingContentStyleInBlockExtendedNoUnderline, editingStyleExtended, editingStyleExtendedNoUnderline, editingStyleActiveExtended, editingStyleActiveExtendedNoUnderline, editingStyleNode, getStandardDeletedContentStyle, getStandardDeletedContentStyleActive, getStandardDeletedContentStyleNew, addedCellOverlayStyle, addedCellOverlayRoundedStyle, deletedCellOverlayStyle, deletedCellOverlayRoundedStyle } from '../colorSchemes/standard';
|
|
@@ -97,7 +98,7 @@ export const getChangedNodeStyleLegacy = (nodeName, colorScheme, isInserted = fa
|
|
|
97
98
|
const isTraditional = colorScheme === 'traditional';
|
|
98
99
|
if (isExtendedEnabled(diffType) && isInserted) {
|
|
99
100
|
if (isMultiContainerBlockNode(nodeName)) {
|
|
100
|
-
return hideAddedDiffsUnderline ? editingContentStyleInBlockExtendedNoUnderline : editingContentStyleInBlockExtended;
|
|
101
|
+
return hideAddedDiffsUnderline || fg('platform_editor_ai_show_diff_patch_1') ? editingContentStyleInBlockExtendedNoUnderline : editingContentStyleInBlockExtended;
|
|
101
102
|
}
|
|
102
103
|
if (isTextLikeBlockNode(nodeName)) {
|
|
103
104
|
return undefined;
|
|
@@ -41,6 +41,30 @@ export const CONTRIBUTOR_TAG_REVEALED_ATTRIBUTE = 'data-revealed';
|
|
|
41
41
|
*/
|
|
42
42
|
export const TAG_EXIT_FALLBACK_MS = 1200;
|
|
43
43
|
|
|
44
|
+
/**
|
|
45
|
+
* The tooltip's look, inline rather than through `VANILLA_TOOLTIP_DEFAULT_CLASS`: this tooltip is
|
|
46
|
+
* hoisted out of the tag, and that class's rule is scoped under `.ProseMirror` — see
|
|
47
|
+
* `resolveTooltipContainer`. Otherwise `vanillaTooltipDefaultStyles` in editor-core, which is the
|
|
48
|
+
* look every other vanilla tooltip has; keep the two in step.
|
|
49
|
+
*/
|
|
50
|
+
export const CONTRIBUTOR_TAG_TOOLTIP_STYLES = {
|
|
51
|
+
boxSizing: 'border-box',
|
|
52
|
+
maxWidth: '240px',
|
|
53
|
+
backgroundColor: "var(--ds-background-neutral-bold, #292A2E)",
|
|
54
|
+
// A `popover` is given one by the UA stylesheet.
|
|
55
|
+
border: 'none',
|
|
56
|
+
borderRadius: "var(--ds-radius-small, 3px)",
|
|
57
|
+
color: "var(--ds-text-inverse, #FFFFFF)",
|
|
58
|
+
font: "var(--ds-font-body-small, normal 400 12px/16px \"Atlassian Sans\", ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, \"Helvetica Neue\", sans-serif)",
|
|
59
|
+
fontFamily: "var(--ds-font-family-body, \"Atlassian Sans\", ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, \"Helvetica Neue\", sans-serif)",
|
|
60
|
+
overflowWrap: 'break-word',
|
|
61
|
+
paddingBlock: "var(--ds-space-050, 4px)",
|
|
62
|
+
paddingInline: "var(--ds-space-075, 6px)",
|
|
63
|
+
whiteSpace: 'normal',
|
|
64
|
+
// A tooltip is never a hit target — it hangs over the document's own content.
|
|
65
|
+
pointerEvents: 'none'
|
|
66
|
+
};
|
|
67
|
+
|
|
44
68
|
// Positioned against the host widget its decoration renders on the change's first character:
|
|
45
69
|
// `bottom: 100%` lifts the tag onto the line above, `inset-inline-start` starts it on that
|
|
46
70
|
// character.
|
|
@@ -3,7 +3,7 @@ import { bind, bindAll } from 'bind-event-listener';
|
|
|
3
3
|
import { VanillaTooltip } from '@atlaskit/editor-common/vanilla-tooltip';
|
|
4
4
|
import { getAccentTokens } from '../../pm-plugins/decorations/colorSchemes/factory';
|
|
5
5
|
import { colorSchemeRegistry } from '../../pm-plugins/decorations/colorSchemes/schemes';
|
|
6
|
-
import { buildContributorTagDom, CONTRIBUTOR_TAG_REVEALED_ATTRIBUTE, TAG_EXIT_FALLBACK_MS } from './buildContributorTagDom';
|
|
6
|
+
import { buildContributorTagDom, CONTRIBUTOR_TAG_REVEALED_ATTRIBUTE, CONTRIBUTOR_TAG_TOOLTIP_STYLES, TAG_EXIT_FALLBACK_MS } from './buildContributorTagDom';
|
|
7
7
|
import { contributorAvatarRenderer } from './contributorAvatarRenderer';
|
|
8
8
|
import { formatContributorLabel } from './contributorLabel';
|
|
9
9
|
/**
|
|
@@ -357,7 +357,7 @@ export class ContributorTagController {
|
|
|
357
357
|
* shape of `syncVanillaDisabledTooltip` in `mentionNodeView`.
|
|
358
358
|
*/
|
|
359
359
|
syncTooltip() {
|
|
360
|
-
var _this$tooltip2
|
|
360
|
+
var _this$tooltip2;
|
|
361
361
|
const content = this.dom ? this.fullLabel : undefined;
|
|
362
362
|
if (content === this.tooltipContent) {
|
|
363
363
|
return;
|
|
@@ -368,17 +368,37 @@ export class ContributorTagController {
|
|
|
368
368
|
if (!content || !this.dom) {
|
|
369
369
|
return;
|
|
370
370
|
}
|
|
371
|
-
this.tooltip = new VanillaTooltip(this.dom.tag, content,
|
|
372
|
-
//
|
|
373
|
-
|
|
374
|
-
//
|
|
375
|
-
|
|
371
|
+
this.tooltip = new VanillaTooltip(this.dom.tag, content,
|
|
372
|
+
// Generated id.
|
|
373
|
+
undefined,
|
|
374
|
+
// No class: the look is inline, because a hoisted tooltip is outside the `.ProseMirror`
|
|
375
|
+
// scope `VANILLA_TOOLTIP_DEFAULT_CLASS` is keyed on — see `CONTRIBUTOR_TAG_TOOLTIP_STYLES`.
|
|
376
|
+
'',
|
|
377
|
+
// Default delay, no `onShow`, and the default `top` placement.
|
|
378
|
+
undefined, CONTRIBUTOR_TAG_TOOLTIP_STYLES, undefined, undefined, this.resolveTooltipContainer());
|
|
376
379
|
// `VanillaTooltip` sets `aria-describedby` on its trigger, which would announce the label a
|
|
377
380
|
// second time — the hidden child already announces it, and names the tag with it.
|
|
378
381
|
this.dom.tag.removeAttribute('aria-describedby');
|
|
379
|
-
//
|
|
380
|
-
// sentence. It stays visible for sighted users, who need the part of the name the tag
|
|
381
|
-
|
|
382
|
+
// Out of the tag but still in the document, so its text would otherwise be a third copy of the
|
|
383
|
+
// same sentence. It stays visible for sighted users, who need the part of the name the tag
|
|
384
|
+
// clipped.
|
|
385
|
+
this.tooltip.element.setAttribute('aria-hidden', 'true');
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Where the tooltip is appended, rather than inside the tag.
|
|
390
|
+
*
|
|
391
|
+
* Popper and the browser only agree on a top-layer popover's origin when nothing above it is
|
|
392
|
+
* transformed, and the tag hangs under the editor's own transformed nodes — inside a wide image
|
|
393
|
+
* that is `.rich-media-item`, whose `translateX(-50%)` threw the tooltip off screen
|
|
394
|
+
* (EDITOR-8971). The content area is the nearest ancestor with none of that above it, and keeps
|
|
395
|
+
* the tooltip inside the editor it belongs to; the document body covers an appearance that has
|
|
396
|
+
* no content area.
|
|
397
|
+
*/
|
|
398
|
+
resolveTooltipContainer() {
|
|
399
|
+
var _editorRoot$closest;
|
|
400
|
+
const editorRoot = this.options.getEditorRoot();
|
|
401
|
+
return (_editorRoot$closest = editorRoot === null || editorRoot === void 0 ? void 0 : editorRoot.closest('.ak-editor-content-area')) !== null && _editorRoot$closest !== void 0 ? _editorRoot$closest : editorRoot === null || editorRoot === void 0 ? void 0 : editorRoot.ownerDocument.body;
|
|
382
402
|
}
|
|
383
403
|
|
|
384
404
|
/**
|
|
@@ -25,10 +25,12 @@ import { extractDiffDescriptors } from '../decorations/decorationKeys';
|
|
|
25
25
|
import { extractContributorTags } from '../decorations/extractContributorTags';
|
|
26
26
|
import { getAttrChangeRanges, stepIsValidAttrChange } from '../decorations/utils/getAttrChangeRanges';
|
|
27
27
|
import { getMarkChangeRanges } from '../decorations/utils/getMarkChangeRanges';
|
|
28
|
+
import { getScrollableDecorations } from '../getScrollableDecorations';
|
|
28
29
|
import { getDefaultDiffType, isExtendedEnabled } from '../isExtendedEnabled';
|
|
29
30
|
import { diffBySteps } from './diffBySteps';
|
|
30
31
|
import { groupChangesByBlock } from './groupChangesByBlock';
|
|
31
32
|
import { isMarkOnlyChange } from './isMarkOnlyChange';
|
|
33
|
+
import { isOpenTokenOnlyChange } from './isOpenTokenOnlyChange';
|
|
32
34
|
import { optimizeChanges } from './optimizeChanges';
|
|
33
35
|
import { selectTokenEncoder } from './selectTokenEncoder';
|
|
34
36
|
import { collapseOverlappingChanges, simplifyChangesWithAttribution } from './simplifyChangesWithAttribution';
|
|
@@ -497,6 +499,16 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
|
|
|
497
499
|
newDoc: tr.doc
|
|
498
500
|
});
|
|
499
501
|
|
|
502
|
+
// The deleted side of a change over a node's open token is an attribute state rather than
|
|
503
|
+
// content, so there is nothing for the deleted-content widget to draw. Decided here, with
|
|
504
|
+
// the other deleted-side suppressions, so the widget is never asked for a slice it can only
|
|
505
|
+
// render as an empty copy of the block (EDITOR-8912). Its inserted side is untouched, and
|
|
506
|
+
// the node's content change is a change of its own.
|
|
507
|
+
var hasNoDeletedContent = fg('platform_editor_ai_show_diff_patch_1') && change.deleted.length > 0 && isOpenTokenOnlyChange({
|
|
508
|
+
change: change,
|
|
509
|
+
originalDoc: originalDoc
|
|
510
|
+
});
|
|
511
|
+
|
|
500
512
|
// Hoisted because it decides BOTH where the deleted widget is anchored and — since the
|
|
501
513
|
// widget pins whichever end of the range it sits at — how the indicator anchors below are
|
|
502
514
|
// allowed to move.
|
|
@@ -615,7 +627,7 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
|
|
|
615
627
|
coarseTableCellsOnly: useCoarseTableDecoration
|
|
616
628
|
}))));
|
|
617
629
|
}
|
|
618
|
-
if (change.deleted.length > 0 && !isMarkOnly) {
|
|
630
|
+
if (change.deleted.length > 0 && !isMarkOnly && !hasNoDeletedContent) {
|
|
619
631
|
var _shouldHideDeleted = shouldHideDeletedSide({
|
|
620
632
|
change: change,
|
|
621
633
|
diffType: diffType,
|
|
@@ -781,7 +793,10 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
|
|
|
781
793
|
});
|
|
782
794
|
var decorationSet = DecorationSet.empty.add(tr.doc, decorations);
|
|
783
795
|
return {
|
|
784
|
-
contributorTags: showContributorTags ? extractContributorTags(decorationSet, contributors
|
|
796
|
+
contributorTags: showContributorTags ? extractContributorTags(decorationSet, contributors, activeIndexPos,
|
|
797
|
+
// The stops the step buttons walk, so a stop cannot hold a second tag for one
|
|
798
|
+
// contributor that navigation can never reach.
|
|
799
|
+
getScrollableDecorations(decorationSet, tr.doc, diffType)) : [],
|
|
785
800
|
decorations: decorationSet,
|
|
786
801
|
diffDescriptors: extractDiffDescriptors(decorationSet)
|
|
787
802
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a change spans nothing but a block node's open token, so its deleted side carries no
|
|
3
|
+
* content.
|
|
4
|
+
*
|
|
5
|
+
* The attribute-aware token encoder folds a node's diffable attributes into its open token, so a
|
|
6
|
+
* same-type replacement — an AI suggestion rewriting a code block — is reported as two changes: one
|
|
7
|
+
* over the single position of that token, carrying the attribute change, and one for the content.
|
|
8
|
+
* Slicing the first yields the node with none of its content, which leaves the deleted-content
|
|
9
|
+
* widget nothing to draw but an empty copy of the block (EDITOR-8912). The content change is a
|
|
10
|
+
* change of its own and is decorated in place.
|
|
11
|
+
*
|
|
12
|
+
* A whole node is not matched: its range covers its close token too. Neither is an empty leaf (a
|
|
13
|
+
* `rule`, a `blockCard`), which is one position but slices closed rather than open.
|
|
14
|
+
*/
|
|
15
|
+
export var isOpenTokenOnlyChange = function isOpenTokenOnlyChange(_ref) {
|
|
16
|
+
var change = _ref.change,
|
|
17
|
+
originalDoc = _ref.originalDoc;
|
|
18
|
+
if (change.toA - change.fromA !== 1) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
var slice = originalDoc.slice(change.fromA, change.toA);
|
|
22
|
+
// `childCount === 1` already means `firstChild` is there; the optional chain is for the type,
|
|
23
|
+
// which has it nullable.
|
|
24
|
+
var node = slice.content.firstChild;
|
|
25
|
+
return (slice.openStart > 0 || slice.openEnd > 0) && slice.content.childCount === 1 && (node === null || node === void 0 ? void 0 : node.isBlock) === true && node.content.size === 0;
|
|
26
|
+
};
|
|
@@ -45,6 +45,16 @@ var edgeCases = function edgeCases(doc, from) {
|
|
|
45
45
|
var node = resolved.node,
|
|
46
46
|
nodeStart = resolved.nodeStart,
|
|
47
47
|
beforePos = resolved.beforePos;
|
|
48
|
+
if (node.type.name === 'layoutSection' && fg('platform_editor_ai_show_diff_patch_1')) {
|
|
49
|
+
// Columns extend past the node-view wrapper via negative margins (12px or 20px).
|
|
50
|
+
// Measure their container so the indicator stays outside the diff outline, including
|
|
51
|
+
// breakout layouts and after responsive resizing, without changing the column geometry.
|
|
52
|
+
return {
|
|
53
|
+
beforePos: beforePos,
|
|
54
|
+
measurePos: beforePos,
|
|
55
|
+
measureSelector: '[data-layout-section]'
|
|
56
|
+
};
|
|
57
|
+
}
|
|
48
58
|
|
|
49
59
|
/**
|
|
50
60
|
* All resizable nodes will need dynamic calculations of the block indicator left anchor
|
|
@@ -152,10 +162,12 @@ export var createLeftAnchorWidget = function createLeftAnchorWidget(_ref) {
|
|
|
152
162
|
anchor.style.setProperty('transform', 'translateX(-50%)');
|
|
153
163
|
wrapper.appendChild(anchor);
|
|
154
164
|
var measureWidth = function measureWidth() {
|
|
165
|
+
var _nodeDOM$querySelecto;
|
|
155
166
|
if (getPos() === undefined || edgeCase.measurePos === undefined) {
|
|
156
167
|
return;
|
|
157
168
|
}
|
|
158
|
-
var
|
|
169
|
+
var nodeDOM = view.nodeDOM(edgeCase.measurePos);
|
|
170
|
+
var dom = edgeCase.measureSelector && nodeDOM instanceof HTMLElement ? (_nodeDOM$querySelecto = nodeDOM.querySelector(edgeCase.measureSelector)) !== null && _nodeDOM$querySelecto !== void 0 ? _nodeDOM$querySelecto : nodeDOM : nodeDOM;
|
|
159
171
|
if (dom instanceof HTMLElement) {
|
|
160
172
|
// The left anchor only needs the container width so the
|
|
161
173
|
// IndicatorBar can align against the block's horizontal extent.
|
|
@@ -42,7 +42,26 @@ export var mountContributorTag = function mountContributorTag(_ref) {
|
|
|
42
42
|
diffId: diffId
|
|
43
43
|
}));
|
|
44
44
|
controller.mount(host);
|
|
45
|
-
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Kept alive when ProseMirror only rebuilt the widget desc around this same host: a document
|
|
48
|
+
* change remaps the decoration and fires `destroy`, but an element `toDOM` is reused verbatim
|
|
49
|
+
* and runs no mount callback, so tearing down here left an active change with no tag
|
|
50
|
+
* (EDITOR-8971).
|
|
51
|
+
*
|
|
52
|
+
* Deferred, because the host is still attached while that update is in flight. A host outside a
|
|
53
|
+
* live editor root is a real removal — including the view being destroyed, which drops the root.
|
|
54
|
+
*/
|
|
55
|
+
return {
|
|
56
|
+
destroy: function destroy() {
|
|
57
|
+
return queueMicrotask(function () {
|
|
58
|
+
var _mountContext$getEdit;
|
|
59
|
+
if (!host.isConnected || !((_mountContext$getEdit = mountContext.getEditorRoot()) !== null && _mountContext$getEdit !== void 0 && _mountContext$getEdit.contains(host))) {
|
|
60
|
+
controller.destroy();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
};
|
|
46
65
|
};
|
|
47
66
|
export var unmountContributorTag = function unmountContributorTag(mount) {
|
|
48
67
|
mount === null || mount === void 0 || mount.destroy();
|