@atlaskit/editor-plugin-show-diff 16.0.2 → 16.0.3
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 +25 -0
- package/dist/cjs/pm-plugins/calculateDiff/calculateDiffDecorations.js +5 -1
- package/dist/cjs/pm-plugins/decorations/createContributorTagWidget.js +20 -1
- package/dist/cjs/pm-plugins/decorations/extractContributorTags.js +121 -21
- 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 +5 -1
- package/dist/es2019/pm-plugins/decorations/createContributorTagWidget.js +18 -1
- package/dist/es2019/pm-plugins/decorations/extractContributorTags.js +70 -10
- 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 +5 -1
- package/dist/esm/pm-plugins/decorations/createContributorTagWidget.js +20 -1
- package/dist/esm/pm-plugins/decorations/extractContributorTags.js +121 -21
- package/dist/esm/ui/ContributorTag/buildContributorTagDom.js +24 -0
- package/dist/esm/ui/ContributorTag/contributorTagController.js +32 -10
- package/dist/types/pm-plugins/decorations/extractContributorTags.d.ts +14 -1
- package/dist/types/ui/ContributorTag/buildContributorTagDom.d.ts +7 -0
- package/dist/types/ui/ContributorTag/contributorTagController.d.ts +11 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-show-diff
|
|
2
2
|
|
|
3
|
+
## 16.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`0265ca1688db1`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/0265ca1688db1) -
|
|
8
|
+
[EDITOR-8971] `VanillaTooltip` takes an optional container to append its tooltip to, instead of
|
|
9
|
+
appending it inside the trigger. Opt-in per caller, and used by the diff contributor tag; every
|
|
10
|
+
other tooltip is unchanged.
|
|
11
|
+
|
|
12
|
+
Diff contributor tag fixes, all behind `confluence_ncs_step_diffing_version_history`:
|
|
13
|
+
- The tag's full label no longer renders off screen. Its tooltip is hoisted out of the tag, so
|
|
14
|
+
Popper and the browser measure a top-layer popover from the same origin — inside the trigger
|
|
15
|
+
they disagreed whenever an ancestor was transformed, such as a wide image.
|
|
16
|
+
- Stepping to a change reveals only that change's tag, not every tag the active range touches.
|
|
17
|
+
- A contributor no longer gets two tags inside one navigation stop. Two of their changes that
|
|
18
|
+
merely touched each kept a tag, and the trailing one could be hovered but never stepped to; it
|
|
19
|
+
now folds into the leading tag and stays a hover target. Tags for different contributors sharing
|
|
20
|
+
a stop are still kept apart.
|
|
21
|
+
- A tag on deleted content no longer disappears when the document changes. Any change remaps the
|
|
22
|
+
decoration, which rebuilds its widget and fired the teardown — but the deleted-content widget's
|
|
23
|
+
DOM is reused as-is and runs no mount callback, so the tag was faded out of a change that was
|
|
24
|
+
still the active one. The tag is now kept whenever its host is still in a live editor.
|
|
25
|
+
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
|
|
3
28
|
## 16.0.2
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
|
@@ -27,6 +27,7 @@ var _decorationKeys = require("../decorations/decorationKeys");
|
|
|
27
27
|
var _extractContributorTags = require("../decorations/extractContributorTags");
|
|
28
28
|
var _getAttrChangeRanges = require("../decorations/utils/getAttrChangeRanges");
|
|
29
29
|
var _getMarkChangeRanges = require("../decorations/utils/getMarkChangeRanges");
|
|
30
|
+
var _getScrollableDecorations = require("../getScrollableDecorations");
|
|
30
31
|
var _isExtendedEnabled = require("../isExtendedEnabled");
|
|
31
32
|
var _diffBySteps = require("./diffBySteps");
|
|
32
33
|
var _groupChangesByBlock = require("./groupChangesByBlock");
|
|
@@ -788,7 +789,10 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
|
|
|
788
789
|
});
|
|
789
790
|
var decorationSet = _view.DecorationSet.empty.add(tr.doc, decorations);
|
|
790
791
|
return {
|
|
791
|
-
contributorTags: showContributorTags ? (0, _extractContributorTags.extractContributorTags)(decorationSet, contributors
|
|
792
|
+
contributorTags: showContributorTags ? (0, _extractContributorTags.extractContributorTags)(decorationSet, contributors, activeIndexPos,
|
|
793
|
+
// The stops the step buttons walk, so a stop cannot hold a second tag for one
|
|
794
|
+
// contributor that navigation can never reach.
|
|
795
|
+
(0, _getScrollableDecorations.getScrollableDecorations)(decorationSet, tr.doc, diffType)) : [],
|
|
792
796
|
decorations: decorationSet,
|
|
793
797
|
diffDescriptors: (0, _decorationKeys.extractDiffDescriptors)(decorationSet)
|
|
794
798
|
};
|
|
@@ -48,7 +48,26 @@ var mountContributorTag = exports.mountContributorTag = function mountContributo
|
|
|
48
48
|
diffId: diffId
|
|
49
49
|
}));
|
|
50
50
|
controller.mount(host);
|
|
51
|
-
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Kept alive when ProseMirror only rebuilt the widget desc around this same host: a document
|
|
54
|
+
* change remaps the decoration and fires `destroy`, but an element `toDOM` is reused verbatim
|
|
55
|
+
* and runs no mount callback, so tearing down here left an active change with no tag
|
|
56
|
+
* (EDITOR-8971).
|
|
57
|
+
*
|
|
58
|
+
* Deferred, because the host is still attached while that update is in flight. A host outside a
|
|
59
|
+
* live editor root is a real removal — including the view being destroyed, which drops the root.
|
|
60
|
+
*/
|
|
61
|
+
return {
|
|
62
|
+
destroy: function destroy() {
|
|
63
|
+
return queueMicrotask(function () {
|
|
64
|
+
var _mountContext$getEdit;
|
|
65
|
+
if (!host.isConnected || !((_mountContext$getEdit = mountContext.getEditorRoot()) !== null && _mountContext$getEdit !== void 0 && _mountContext$getEdit.contains(host))) {
|
|
66
|
+
controller.destroy();
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
};
|
|
52
71
|
};
|
|
53
72
|
var unmountContributorTag = exports.unmountContributorTag = function unmountContributorTag(mount) {
|
|
54
73
|
mount === null || mount === void 0 || mount.destroy();
|
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.extractContributorTags = void 0;
|
|
8
|
+
var _toArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toArray"));
|
|
8
9
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
9
10
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
10
11
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
@@ -56,12 +57,48 @@ var isSameBlockChange = function isSameBlockChange(inner, block) {
|
|
|
56
57
|
return inner.spec.attributionKey === block.spec.attributionKey && (block.from <= inner.from && inner.to <= block.to || inner.from <= block.from && block.to <= inner.to);
|
|
57
58
|
};
|
|
58
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Which of two changes in the same range leads, and so is the one a tag captions. Position first,
|
|
62
|
+
* then `side`, since deleted content shares its `from` with the content that replaced it and paints
|
|
63
|
+
* above; then the narrower range, so a change nested in another captions itself.
|
|
64
|
+
*/
|
|
65
|
+
var byLeadingPosition = function byLeadingPosition(a, b) {
|
|
66
|
+
var _a$decoration$spec$si, _b$decoration$spec$si;
|
|
67
|
+
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);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/** The targets a navigation range wholly covers, leader first. */
|
|
71
|
+
var containedBy = function containedBy(targets, _ref2) {
|
|
72
|
+
var from = _ref2.from,
|
|
73
|
+
to = _ref2.to;
|
|
74
|
+
return targets.filter(function (_ref3) {
|
|
75
|
+
var decoration = _ref3.decoration;
|
|
76
|
+
return from <= decoration.from && decoration.to <= to;
|
|
77
|
+
}).sort(byLeadingPosition);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The one tag a navigation step reveals. `spec.isActive` is no use here: it covers everything the
|
|
82
|
+
* group's union range touches, so several tags revealed over each other (EDITOR-8971). Hence
|
|
83
|
+
* containment, and the leading change of what it covers.
|
|
84
|
+
*/
|
|
85
|
+
var resolveActiveTarget = function resolveActiveTarget(surviving, activeIndexPos) {
|
|
86
|
+
return containedBy(surviving, activeIndexPos)[0];
|
|
87
|
+
};
|
|
88
|
+
|
|
59
89
|
/**
|
|
60
90
|
* One model per diff decoration whose attribution resolves to a supplied contributor; anything
|
|
61
91
|
* unattributed, untaggable or unresolved is skipped. A replacement's two decorations are collapsed
|
|
62
92
|
* into a single tag, on whichever half renders first — see `isSameChange` and `leadsReplacement`.
|
|
93
|
+
*
|
|
94
|
+
* `activeIndexPos`, when given, reveals exactly one of the tags — see `resolveActiveTarget`.
|
|
95
|
+
* Absent, each tag keeps the active state its own decoration was drawn with.
|
|
96
|
+
*
|
|
97
|
+
* `stops`, when given, is the navigation stop list the step buttons walk
|
|
98
|
+
* (`getScrollableDecorations`). One contributor cannot hold two tags in one stop, since only the
|
|
99
|
+
* leading one would ever be reachable. Absent, every decoration keeps its own tag.
|
|
63
100
|
*/
|
|
64
|
-
var extractContributorTags = exports.extractContributorTags = function extractContributorTags(decorations, contributors) {
|
|
101
|
+
var extractContributorTags = exports.extractContributorTags = function extractContributorTags(decorations, contributors, activeIndexPos, stops) {
|
|
65
102
|
if (!contributors) {
|
|
66
103
|
return [];
|
|
67
104
|
}
|
|
@@ -94,25 +131,30 @@ var extractContributorTags = exports.extractContributorTags = function extractCo
|
|
|
94
131
|
} finally {
|
|
95
132
|
_iterator.f();
|
|
96
133
|
}
|
|
97
|
-
var inlineTargets = targets.filter(function (
|
|
98
|
-
var decoration =
|
|
134
|
+
var inlineTargets = targets.filter(function (_ref4) {
|
|
135
|
+
var decoration = _ref4.decoration;
|
|
99
136
|
return decoration.spec.decorationType === 'inline';
|
|
100
137
|
});
|
|
101
|
-
var blockTargets = targets.filter(function (
|
|
102
|
-
var decoration =
|
|
138
|
+
var blockTargets = targets.filter(function (_ref5) {
|
|
139
|
+
var decoration = _ref5.decoration;
|
|
103
140
|
return decoration.spec.decorationType === 'block';
|
|
104
141
|
});
|
|
105
|
-
var widgetTargets = targets.filter(function (
|
|
106
|
-
var decoration =
|
|
142
|
+
var widgetTargets = targets.filter(function (_ref6) {
|
|
143
|
+
var decoration = _ref6.decoration;
|
|
107
144
|
return decoration.spec.decorationType === 'widget';
|
|
108
145
|
});
|
|
109
146
|
var linkedDiffIds = new Map();
|
|
110
147
|
var folded = new Set();
|
|
111
148
|
var fold = function fold(host, target) {
|
|
112
|
-
var _linkedDiffIds$get;
|
|
149
|
+
var _linkedDiffIds$get, _linkedDiffIds$get2;
|
|
113
150
|
folded.add(target);
|
|
114
151
|
var hostDiffId = host.decoration.spec.diffId;
|
|
115
|
-
|
|
152
|
+
var targetDiffId = target.decoration.spec.diffId;
|
|
153
|
+
// A target that already hosts folded tags hands them up, so no hover target is orphaned when
|
|
154
|
+
// one host folds into another.
|
|
155
|
+
var inherited = (_linkedDiffIds$get = linkedDiffIds.get(targetDiffId)) !== null && _linkedDiffIds$get !== void 0 ? _linkedDiffIds$get : [];
|
|
156
|
+
linkedDiffIds.delete(targetDiffId);
|
|
157
|
+
linkedDiffIds.set(hostDiffId, [].concat((0, _toConsumableArray2.default)((_linkedDiffIds$get2 = linkedDiffIds.get(hostDiffId)) !== null && _linkedDiffIds$get2 !== void 0 ? _linkedDiffIds$get2 : []), [targetDiffId], (0, _toConsumableArray2.default)(inherited)));
|
|
116
158
|
};
|
|
117
159
|
var _loop = function _loop() {
|
|
118
160
|
var target = _targets[_i];
|
|
@@ -122,8 +164,8 @@ var extractContributorTags = exports.extractContributorTags = function extractCo
|
|
|
122
164
|
}
|
|
123
165
|
|
|
124
166
|
// A block outranks both other kinds, so it is tried first.
|
|
125
|
-
var block = blockTargets.find(function (
|
|
126
|
-
var decoration =
|
|
167
|
+
var block = blockTargets.find(function (_ref7) {
|
|
168
|
+
var decoration = _ref7.decoration;
|
|
127
169
|
return isSameBlockChange(target.decoration, decoration);
|
|
128
170
|
});
|
|
129
171
|
if (block) {
|
|
@@ -132,8 +174,8 @@ var extractContributorTags = exports.extractContributorTags = function extractCo
|
|
|
132
174
|
}
|
|
133
175
|
if (decorationType === 'inline') {
|
|
134
176
|
// The deleted half renders in front of this one, so that half captions the change.
|
|
135
|
-
var leadingWidget = widgetTargets.find(function (
|
|
136
|
-
var decoration =
|
|
177
|
+
var leadingWidget = widgetTargets.find(function (_ref8) {
|
|
178
|
+
var decoration = _ref8.decoration;
|
|
137
179
|
return leadsReplacement(decoration) && isSameChange(decoration, target.decoration);
|
|
138
180
|
});
|
|
139
181
|
if (leadingWidget) {
|
|
@@ -146,8 +188,8 @@ var extractContributorTags = exports.extractContributorTags = function extractCo
|
|
|
146
188
|
if (leadsReplacement(target.decoration)) {
|
|
147
189
|
return 0; // continue
|
|
148
190
|
}
|
|
149
|
-
var host = inlineTargets.find(function (
|
|
150
|
-
var decoration =
|
|
191
|
+
var host = inlineTargets.find(function (_ref9) {
|
|
192
|
+
var decoration = _ref9.decoration;
|
|
151
193
|
return isSameChange(target.decoration, decoration);
|
|
152
194
|
});
|
|
153
195
|
if (host) {
|
|
@@ -159,14 +201,72 @@ var extractContributorTags = exports.extractContributorTags = function extractCo
|
|
|
159
201
|
_ret = _loop();
|
|
160
202
|
if (_ret === 0) continue;
|
|
161
203
|
}
|
|
162
|
-
|
|
204
|
+
|
|
205
|
+
// One tag per contributor per navigation stop. The folds above only catch a replacement's two
|
|
206
|
+
// halves and a block's own highlights; two of one contributor's changes that merely touch are a
|
|
207
|
+
// single stop (`groupTouchingDecorations`) yet kept a tag each, so the stop's trailing tag was
|
|
208
|
+
// drawn but could never be stepped to (EDITOR-8971). It folds into the leading tag of its
|
|
209
|
+
// contributor, staying a hover target. Contributors are kept apart: a stop spanning two of them
|
|
210
|
+
// still captions each, rather than crediting one for the other's change.
|
|
211
|
+
var _iterator2 = _createForOfIteratorHelper(stops !== null && stops !== void 0 ? stops : []),
|
|
212
|
+
_step2;
|
|
213
|
+
try {
|
|
214
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
215
|
+
var stop = _step2.value;
|
|
216
|
+
var byContributor = new Map();
|
|
217
|
+
var _iterator3 = _createForOfIteratorHelper(containedBy(targets.filter(function (target) {
|
|
218
|
+
return !folded.has(target);
|
|
219
|
+
}), stop)),
|
|
220
|
+
_step3;
|
|
221
|
+
try {
|
|
222
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
223
|
+
var _target$decoration$sp, _byContributor$get;
|
|
224
|
+
var target = _step3.value;
|
|
225
|
+
var key = (_target$decoration$sp = target.decoration.spec.attributionKey) !== null && _target$decoration$sp !== void 0 ? _target$decoration$sp : '';
|
|
226
|
+
byContributor.set(key, [].concat((0, _toConsumableArray2.default)((_byContributor$get = byContributor.get(key)) !== null && _byContributor$get !== void 0 ? _byContributor$get : []), [target]));
|
|
227
|
+
}
|
|
228
|
+
} catch (err) {
|
|
229
|
+
_iterator3.e(err);
|
|
230
|
+
} finally {
|
|
231
|
+
_iterator3.f();
|
|
232
|
+
}
|
|
233
|
+
var _iterator4 = _createForOfIteratorHelper(byContributor.values()),
|
|
234
|
+
_step4;
|
|
235
|
+
try {
|
|
236
|
+
var _loop2 = function _loop2() {
|
|
237
|
+
var _step4$value = (0, _toArray2.default)(_step4.value),
|
|
238
|
+
leader = _step4$value[0],
|
|
239
|
+
trailing = _arrayLikeToArray(_step4$value).slice(1);
|
|
240
|
+
trailing.forEach(function (target) {
|
|
241
|
+
return fold(leader, target);
|
|
242
|
+
});
|
|
243
|
+
};
|
|
244
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
245
|
+
_loop2();
|
|
246
|
+
}
|
|
247
|
+
} catch (err) {
|
|
248
|
+
_iterator4.e(err);
|
|
249
|
+
} finally {
|
|
250
|
+
_iterator4.f();
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
} catch (err) {
|
|
254
|
+
_iterator2.e(err);
|
|
255
|
+
} finally {
|
|
256
|
+
_iterator2.f();
|
|
257
|
+
}
|
|
258
|
+
var surviving = targets.filter(function (target) {
|
|
163
259
|
return !folded.has(target);
|
|
164
|
-
})
|
|
165
|
-
|
|
166
|
-
|
|
260
|
+
});
|
|
261
|
+
var activeTarget = activeIndexPos === undefined ? undefined : resolveActiveTarget(surviving, activeIndexPos);
|
|
262
|
+
return surviving.map(function (target) {
|
|
263
|
+
var contributor = target.contributor,
|
|
264
|
+
spec = target.decoration.spec;
|
|
167
265
|
var connected = contributor.connectedToKey ? contributors[contributor.connectedToKey] : undefined;
|
|
168
266
|
var connectedContributor = connected ? toTagContributor(connected) : undefined;
|
|
169
267
|
var linked = linkedDiffIds.get(spec.diffId);
|
|
268
|
+
// Only the navigated tag reveals; with no active range, the decoration's own state stands.
|
|
269
|
+
var isActive = activeIndexPos === undefined ? spec.isActive : target === activeTarget;
|
|
170
270
|
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
171
271
|
contributor: toTagContributor(contributor),
|
|
172
272
|
diffId: spec.diffId
|
|
@@ -174,8 +274,8 @@ var extractContributorTags = exports.extractContributorTags = function extractCo
|
|
|
174
274
|
connectedContributor: connectedContributor
|
|
175
275
|
} : {}), spec.colorScheme ? {
|
|
176
276
|
colorScheme: spec.colorScheme
|
|
177
|
-
} : {}),
|
|
178
|
-
isActive:
|
|
277
|
+
} : {}), isActive !== undefined ? {
|
|
278
|
+
isActive: isActive
|
|
179
279
|
} : {}), spec.isInserted !== undefined ? {
|
|
180
280
|
isInserted: spec.isInserted
|
|
181
281
|
} : {}), linked ? {
|
|
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
4
4
|
Object.defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.buildContributorTagDom = exports.TAG_EXIT_FALLBACK_MS = exports.MAX_TAG_WIDTH = exports.CONTRIBUTOR_TAG_Z_INDEX = exports.CONTRIBUTOR_TAG_TESTID = exports.CONTRIBUTOR_TAG_REVEALED_ATTRIBUTE = exports.CONTRIBUTOR_TAG_NAME_TESTID = exports.CONTRIBUTOR_TAG_CLASS = void 0;
|
|
7
|
+
exports.buildContributorTagDom = exports.TAG_EXIT_FALLBACK_MS = exports.MAX_TAG_WIDTH = exports.CONTRIBUTOR_TAG_Z_INDEX = exports.CONTRIBUTOR_TAG_TOOLTIP_STYLES = exports.CONTRIBUTOR_TAG_TESTID = exports.CONTRIBUTOR_TAG_REVEALED_ATTRIBUTE = exports.CONTRIBUTOR_TAG_NAME_TESTID = exports.CONTRIBUTOR_TAG_CLASS = void 0;
|
|
8
8
|
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
9
|
var _lazyNodeView = require("@atlaskit/editor-common/lazy-node-view");
|
|
10
10
|
var CONTRIBUTOR_TAG_TESTID = exports.CONTRIBUTOR_TAG_TESTID = 'diff-contributor-tag';
|
|
@@ -49,6 +49,30 @@ var CONTRIBUTOR_TAG_REVEALED_ATTRIBUTE = exports.CONTRIBUTOR_TAG_REVEALED_ATTRIB
|
|
|
49
49
|
*/
|
|
50
50
|
var TAG_EXIT_FALLBACK_MS = exports.TAG_EXIT_FALLBACK_MS = 1200;
|
|
51
51
|
|
|
52
|
+
/**
|
|
53
|
+
* The tooltip's look, inline rather than through `VANILLA_TOOLTIP_DEFAULT_CLASS`: this tooltip is
|
|
54
|
+
* hoisted out of the tag, and that class's rule is scoped under `.ProseMirror` — see
|
|
55
|
+
* `resolveTooltipContainer`. Otherwise `vanillaTooltipDefaultStyles` in editor-core, which is the
|
|
56
|
+
* look every other vanilla tooltip has; keep the two in step.
|
|
57
|
+
*/
|
|
58
|
+
var CONTRIBUTOR_TAG_TOOLTIP_STYLES = exports.CONTRIBUTOR_TAG_TOOLTIP_STYLES = {
|
|
59
|
+
boxSizing: 'border-box',
|
|
60
|
+
maxWidth: '240px',
|
|
61
|
+
backgroundColor: "var(--ds-background-neutral-bold, #292A2E)",
|
|
62
|
+
// A `popover` is given one by the UA stylesheet.
|
|
63
|
+
border: 'none',
|
|
64
|
+
borderRadius: "var(--ds-radius-small, 3px)",
|
|
65
|
+
color: "var(--ds-text-inverse, #FFFFFF)",
|
|
66
|
+
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)",
|
|
67
|
+
fontFamily: "var(--ds-font-family-body, \"Atlassian Sans\", ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, \"Helvetica Neue\", sans-serif)",
|
|
68
|
+
overflowWrap: 'break-word',
|
|
69
|
+
paddingBlock: "var(--ds-space-050, 4px)",
|
|
70
|
+
paddingInline: "var(--ds-space-075, 6px)",
|
|
71
|
+
whiteSpace: 'normal',
|
|
72
|
+
// A tooltip is never a hit target — it hangs over the document's own content.
|
|
73
|
+
pointerEvents: 'none'
|
|
74
|
+
};
|
|
75
|
+
|
|
52
76
|
// Positioned against the host widget its decoration renders on the change's first character:
|
|
53
77
|
// `bottom: 100%` lifts the tag onto the line above, `inset-inline-start` starts it on that
|
|
54
78
|
// character.
|
|
@@ -400,7 +400,7 @@ var ContributorTagController = exports.ContributorTagController = /*#__PURE__*/f
|
|
|
400
400
|
}, {
|
|
401
401
|
key: "syncTooltip",
|
|
402
402
|
value: function syncTooltip() {
|
|
403
|
-
var _this$tooltip2
|
|
403
|
+
var _this$tooltip2;
|
|
404
404
|
var content = this.dom ? this.fullLabel : undefined;
|
|
405
405
|
if (content === this.tooltipContent) {
|
|
406
406
|
return;
|
|
@@ -411,17 +411,39 @@ var ContributorTagController = exports.ContributorTagController = /*#__PURE__*/f
|
|
|
411
411
|
if (!content || !this.dom) {
|
|
412
412
|
return;
|
|
413
413
|
}
|
|
414
|
-
this.tooltip = new _vanillaTooltip.VanillaTooltip(this.dom.tag, content,
|
|
415
|
-
//
|
|
416
|
-
|
|
417
|
-
//
|
|
418
|
-
|
|
414
|
+
this.tooltip = new _vanillaTooltip.VanillaTooltip(this.dom.tag, content,
|
|
415
|
+
// Generated id.
|
|
416
|
+
undefined,
|
|
417
|
+
// No class: the look is inline, because a hoisted tooltip is outside the `.ProseMirror`
|
|
418
|
+
// scope `VANILLA_TOOLTIP_DEFAULT_CLASS` is keyed on — see `CONTRIBUTOR_TAG_TOOLTIP_STYLES`.
|
|
419
|
+
'',
|
|
420
|
+
// Default delay, no `onShow`, and the default `top` placement.
|
|
421
|
+
undefined, _buildContributorTagDom.CONTRIBUTOR_TAG_TOOLTIP_STYLES, undefined, undefined, this.resolveTooltipContainer());
|
|
419
422
|
// `VanillaTooltip` sets `aria-describedby` on its trigger, which would announce the label a
|
|
420
423
|
// second time — the hidden child already announces it, and names the tag with it.
|
|
421
424
|
this.dom.tag.removeAttribute('aria-describedby');
|
|
422
|
-
//
|
|
423
|
-
// sentence. It stays visible for sighted users, who need the part of the name the tag
|
|
424
|
-
|
|
425
|
+
// Out of the tag but still in the document, so its text would otherwise be a third copy of the
|
|
426
|
+
// same sentence. It stays visible for sighted users, who need the part of the name the tag
|
|
427
|
+
// clipped.
|
|
428
|
+
this.tooltip.element.setAttribute('aria-hidden', 'true');
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Where the tooltip is appended, rather than inside the tag.
|
|
433
|
+
*
|
|
434
|
+
* Popper and the browser only agree on a top-layer popover's origin when nothing above it is
|
|
435
|
+
* transformed, and the tag hangs under the editor's own transformed nodes — inside a wide image
|
|
436
|
+
* that is `.rich-media-item`, whose `translateX(-50%)` threw the tooltip off screen
|
|
437
|
+
* (EDITOR-8971). The content area is the nearest ancestor with none of that above it, and keeps
|
|
438
|
+
* the tooltip inside the editor it belongs to; the document body covers an appearance that has
|
|
439
|
+
* no content area.
|
|
440
|
+
*/
|
|
441
|
+
}, {
|
|
442
|
+
key: "resolveTooltipContainer",
|
|
443
|
+
value: function resolveTooltipContainer() {
|
|
444
|
+
var _editorRoot$closest;
|
|
445
|
+
var editorRoot = this.options.getEditorRoot();
|
|
446
|
+
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;
|
|
425
447
|
}
|
|
426
448
|
|
|
427
449
|
/**
|
|
@@ -17,6 +17,7 @@ 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';
|
|
@@ -732,7 +733,10 @@ const calculateDiffDecorationsInner = ({
|
|
|
732
733
|
});
|
|
733
734
|
const decorationSet = DecorationSet.empty.add(tr.doc, decorations);
|
|
734
735
|
return {
|
|
735
|
-
contributorTags: showContributorTags ? extractContributorTags(decorationSet, contributors
|
|
736
|
+
contributorTags: showContributorTags ? extractContributorTags(decorationSet, contributors, activeIndexPos,
|
|
737
|
+
// The stops the step buttons walk, so a stop cannot hold a second tag for one
|
|
738
|
+
// contributor that navigation can never reach.
|
|
739
|
+
getScrollableDecorations(decorationSet, tr.doc, diffType)) : [],
|
|
736
740
|
decorations: decorationSet,
|
|
737
741
|
diffDescriptors: extractDiffDescriptors(decorationSet)
|
|
738
742
|
};
|
|
@@ -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
|
|
@@ -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,6 +25,7 @@ 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';
|
|
@@ -781,7 +782,10 @@ var calculateDiffDecorationsInner = function calculateDiffDecorationsInner(_ref8
|
|
|
781
782
|
});
|
|
782
783
|
var decorationSet = DecorationSet.empty.add(tr.doc, decorations);
|
|
783
784
|
return {
|
|
784
|
-
contributorTags: showContributorTags ? extractContributorTags(decorationSet, contributors
|
|
785
|
+
contributorTags: showContributorTags ? extractContributorTags(decorationSet, contributors, activeIndexPos,
|
|
786
|
+
// The stops the step buttons walk, so a stop cannot hold a second tag for one
|
|
787
|
+
// contributor that navigation can never reach.
|
|
788
|
+
getScrollableDecorations(decorationSet, tr.doc, diffType)) : [],
|
|
785
789
|
decorations: decorationSet,
|
|
786
790
|
diffDescriptors: extractDiffDescriptors(decorationSet)
|
|
787
791
|
};
|
|
@@ -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();
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _toArray from "@babel/runtime/helpers/toArray";
|
|
1
2
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
3
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
3
4
|
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
|
|
@@ -50,12 +51,48 @@ var isSameBlockChange = function isSameBlockChange(inner, block) {
|
|
|
50
51
|
return inner.spec.attributionKey === block.spec.attributionKey && (block.from <= inner.from && inner.to <= block.to || inner.from <= block.from && block.to <= inner.to);
|
|
51
52
|
};
|
|
52
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Which of two changes in the same range leads, and so is the one a tag captions. Position first,
|
|
56
|
+
* then `side`, since deleted content shares its `from` with the content that replaced it and paints
|
|
57
|
+
* above; then the narrower range, so a change nested in another captions itself.
|
|
58
|
+
*/
|
|
59
|
+
var byLeadingPosition = function byLeadingPosition(a, b) {
|
|
60
|
+
var _a$decoration$spec$si, _b$decoration$spec$si;
|
|
61
|
+
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);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** The targets a navigation range wholly covers, leader first. */
|
|
65
|
+
var containedBy = function containedBy(targets, _ref2) {
|
|
66
|
+
var from = _ref2.from,
|
|
67
|
+
to = _ref2.to;
|
|
68
|
+
return targets.filter(function (_ref3) {
|
|
69
|
+
var decoration = _ref3.decoration;
|
|
70
|
+
return from <= decoration.from && decoration.to <= to;
|
|
71
|
+
}).sort(byLeadingPosition);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The one tag a navigation step reveals. `spec.isActive` is no use here: it covers everything the
|
|
76
|
+
* group's union range touches, so several tags revealed over each other (EDITOR-8971). Hence
|
|
77
|
+
* containment, and the leading change of what it covers.
|
|
78
|
+
*/
|
|
79
|
+
var resolveActiveTarget = function resolveActiveTarget(surviving, activeIndexPos) {
|
|
80
|
+
return containedBy(surviving, activeIndexPos)[0];
|
|
81
|
+
};
|
|
82
|
+
|
|
53
83
|
/**
|
|
54
84
|
* One model per diff decoration whose attribution resolves to a supplied contributor; anything
|
|
55
85
|
* unattributed, untaggable or unresolved is skipped. A replacement's two decorations are collapsed
|
|
56
86
|
* into a single tag, on whichever half renders first — see `isSameChange` and `leadsReplacement`.
|
|
87
|
+
*
|
|
88
|
+
* `activeIndexPos`, when given, reveals exactly one of the tags — see `resolveActiveTarget`.
|
|
89
|
+
* Absent, each tag keeps the active state its own decoration was drawn with.
|
|
90
|
+
*
|
|
91
|
+
* `stops`, when given, is the navigation stop list the step buttons walk
|
|
92
|
+
* (`getScrollableDecorations`). One contributor cannot hold two tags in one stop, since only the
|
|
93
|
+
* leading one would ever be reachable. Absent, every decoration keeps its own tag.
|
|
57
94
|
*/
|
|
58
|
-
export var extractContributorTags = function extractContributorTags(decorations, contributors) {
|
|
95
|
+
export var extractContributorTags = function extractContributorTags(decorations, contributors, activeIndexPos, stops) {
|
|
59
96
|
if (!contributors) {
|
|
60
97
|
return [];
|
|
61
98
|
}
|
|
@@ -88,25 +125,30 @@ export var extractContributorTags = function extractContributorTags(decorations,
|
|
|
88
125
|
} finally {
|
|
89
126
|
_iterator.f();
|
|
90
127
|
}
|
|
91
|
-
var inlineTargets = targets.filter(function (
|
|
92
|
-
var decoration =
|
|
128
|
+
var inlineTargets = targets.filter(function (_ref4) {
|
|
129
|
+
var decoration = _ref4.decoration;
|
|
93
130
|
return decoration.spec.decorationType === 'inline';
|
|
94
131
|
});
|
|
95
|
-
var blockTargets = targets.filter(function (
|
|
96
|
-
var decoration =
|
|
132
|
+
var blockTargets = targets.filter(function (_ref5) {
|
|
133
|
+
var decoration = _ref5.decoration;
|
|
97
134
|
return decoration.spec.decorationType === 'block';
|
|
98
135
|
});
|
|
99
|
-
var widgetTargets = targets.filter(function (
|
|
100
|
-
var decoration =
|
|
136
|
+
var widgetTargets = targets.filter(function (_ref6) {
|
|
137
|
+
var decoration = _ref6.decoration;
|
|
101
138
|
return decoration.spec.decorationType === 'widget';
|
|
102
139
|
});
|
|
103
140
|
var linkedDiffIds = new Map();
|
|
104
141
|
var folded = new Set();
|
|
105
142
|
var fold = function fold(host, target) {
|
|
106
|
-
var _linkedDiffIds$get;
|
|
143
|
+
var _linkedDiffIds$get, _linkedDiffIds$get2;
|
|
107
144
|
folded.add(target);
|
|
108
145
|
var hostDiffId = host.decoration.spec.diffId;
|
|
109
|
-
|
|
146
|
+
var targetDiffId = target.decoration.spec.diffId;
|
|
147
|
+
// A target that already hosts folded tags hands them up, so no hover target is orphaned when
|
|
148
|
+
// one host folds into another.
|
|
149
|
+
var inherited = (_linkedDiffIds$get = linkedDiffIds.get(targetDiffId)) !== null && _linkedDiffIds$get !== void 0 ? _linkedDiffIds$get : [];
|
|
150
|
+
linkedDiffIds.delete(targetDiffId);
|
|
151
|
+
linkedDiffIds.set(hostDiffId, [].concat(_toConsumableArray((_linkedDiffIds$get2 = linkedDiffIds.get(hostDiffId)) !== null && _linkedDiffIds$get2 !== void 0 ? _linkedDiffIds$get2 : []), [targetDiffId], _toConsumableArray(inherited)));
|
|
110
152
|
};
|
|
111
153
|
var _loop = function _loop() {
|
|
112
154
|
var target = _targets[_i];
|
|
@@ -116,8 +158,8 @@ export var extractContributorTags = function extractContributorTags(decorations,
|
|
|
116
158
|
}
|
|
117
159
|
|
|
118
160
|
// A block outranks both other kinds, so it is tried first.
|
|
119
|
-
var block = blockTargets.find(function (
|
|
120
|
-
var decoration =
|
|
161
|
+
var block = blockTargets.find(function (_ref7) {
|
|
162
|
+
var decoration = _ref7.decoration;
|
|
121
163
|
return isSameBlockChange(target.decoration, decoration);
|
|
122
164
|
});
|
|
123
165
|
if (block) {
|
|
@@ -126,8 +168,8 @@ export var extractContributorTags = function extractContributorTags(decorations,
|
|
|
126
168
|
}
|
|
127
169
|
if (decorationType === 'inline') {
|
|
128
170
|
// The deleted half renders in front of this one, so that half captions the change.
|
|
129
|
-
var leadingWidget = widgetTargets.find(function (
|
|
130
|
-
var decoration =
|
|
171
|
+
var leadingWidget = widgetTargets.find(function (_ref8) {
|
|
172
|
+
var decoration = _ref8.decoration;
|
|
131
173
|
return leadsReplacement(decoration) && isSameChange(decoration, target.decoration);
|
|
132
174
|
});
|
|
133
175
|
if (leadingWidget) {
|
|
@@ -140,8 +182,8 @@ export var extractContributorTags = function extractContributorTags(decorations,
|
|
|
140
182
|
if (leadsReplacement(target.decoration)) {
|
|
141
183
|
return 0; // continue
|
|
142
184
|
}
|
|
143
|
-
var host = inlineTargets.find(function (
|
|
144
|
-
var decoration =
|
|
185
|
+
var host = inlineTargets.find(function (_ref9) {
|
|
186
|
+
var decoration = _ref9.decoration;
|
|
145
187
|
return isSameChange(target.decoration, decoration);
|
|
146
188
|
});
|
|
147
189
|
if (host) {
|
|
@@ -153,14 +195,72 @@ export var extractContributorTags = function extractContributorTags(decorations,
|
|
|
153
195
|
_ret = _loop();
|
|
154
196
|
if (_ret === 0) continue;
|
|
155
197
|
}
|
|
156
|
-
|
|
198
|
+
|
|
199
|
+
// One tag per contributor per navigation stop. The folds above only catch a replacement's two
|
|
200
|
+
// halves and a block's own highlights; two of one contributor's changes that merely touch are a
|
|
201
|
+
// single stop (`groupTouchingDecorations`) yet kept a tag each, so the stop's trailing tag was
|
|
202
|
+
// drawn but could never be stepped to (EDITOR-8971). It folds into the leading tag of its
|
|
203
|
+
// contributor, staying a hover target. Contributors are kept apart: a stop spanning two of them
|
|
204
|
+
// still captions each, rather than crediting one for the other's change.
|
|
205
|
+
var _iterator2 = _createForOfIteratorHelper(stops !== null && stops !== void 0 ? stops : []),
|
|
206
|
+
_step2;
|
|
207
|
+
try {
|
|
208
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
209
|
+
var stop = _step2.value;
|
|
210
|
+
var byContributor = new Map();
|
|
211
|
+
var _iterator3 = _createForOfIteratorHelper(containedBy(targets.filter(function (target) {
|
|
212
|
+
return !folded.has(target);
|
|
213
|
+
}), stop)),
|
|
214
|
+
_step3;
|
|
215
|
+
try {
|
|
216
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
217
|
+
var _target$decoration$sp, _byContributor$get;
|
|
218
|
+
var target = _step3.value;
|
|
219
|
+
var key = (_target$decoration$sp = target.decoration.spec.attributionKey) !== null && _target$decoration$sp !== void 0 ? _target$decoration$sp : '';
|
|
220
|
+
byContributor.set(key, [].concat(_toConsumableArray((_byContributor$get = byContributor.get(key)) !== null && _byContributor$get !== void 0 ? _byContributor$get : []), [target]));
|
|
221
|
+
}
|
|
222
|
+
} catch (err) {
|
|
223
|
+
_iterator3.e(err);
|
|
224
|
+
} finally {
|
|
225
|
+
_iterator3.f();
|
|
226
|
+
}
|
|
227
|
+
var _iterator4 = _createForOfIteratorHelper(byContributor.values()),
|
|
228
|
+
_step4;
|
|
229
|
+
try {
|
|
230
|
+
var _loop2 = function _loop2() {
|
|
231
|
+
var _step4$value = _toArray(_step4.value),
|
|
232
|
+
leader = _step4$value[0],
|
|
233
|
+
trailing = _arrayLikeToArray(_step4$value).slice(1);
|
|
234
|
+
trailing.forEach(function (target) {
|
|
235
|
+
return fold(leader, target);
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
239
|
+
_loop2();
|
|
240
|
+
}
|
|
241
|
+
} catch (err) {
|
|
242
|
+
_iterator4.e(err);
|
|
243
|
+
} finally {
|
|
244
|
+
_iterator4.f();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
} catch (err) {
|
|
248
|
+
_iterator2.e(err);
|
|
249
|
+
} finally {
|
|
250
|
+
_iterator2.f();
|
|
251
|
+
}
|
|
252
|
+
var surviving = targets.filter(function (target) {
|
|
157
253
|
return !folded.has(target);
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
|
|
254
|
+
});
|
|
255
|
+
var activeTarget = activeIndexPos === undefined ? undefined : resolveActiveTarget(surviving, activeIndexPos);
|
|
256
|
+
return surviving.map(function (target) {
|
|
257
|
+
var contributor = target.contributor,
|
|
258
|
+
spec = target.decoration.spec;
|
|
161
259
|
var connected = contributor.connectedToKey ? contributors[contributor.connectedToKey] : undefined;
|
|
162
260
|
var connectedContributor = connected ? toTagContributor(connected) : undefined;
|
|
163
261
|
var linked = linkedDiffIds.get(spec.diffId);
|
|
262
|
+
// Only the navigated tag reveals; with no active range, the decoration's own state stands.
|
|
263
|
+
var isActive = activeIndexPos === undefined ? spec.isActive : target === activeTarget;
|
|
164
264
|
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({
|
|
165
265
|
contributor: toTagContributor(contributor),
|
|
166
266
|
diffId: spec.diffId
|
|
@@ -168,8 +268,8 @@ export var extractContributorTags = function extractContributorTags(decorations,
|
|
|
168
268
|
connectedContributor: connectedContributor
|
|
169
269
|
} : {}), spec.colorScheme ? {
|
|
170
270
|
colorScheme: spec.colorScheme
|
|
171
|
-
} : {}),
|
|
172
|
-
isActive:
|
|
271
|
+
} : {}), isActive !== undefined ? {
|
|
272
|
+
isActive: isActive
|
|
173
273
|
} : {}), spec.isInserted !== undefined ? {
|
|
174
274
|
isInserted: spec.isInserted
|
|
175
275
|
} : {}), linked ? {
|
|
@@ -42,6 +42,30 @@ export var CONTRIBUTOR_TAG_REVEALED_ATTRIBUTE = 'data-revealed';
|
|
|
42
42
|
*/
|
|
43
43
|
export var TAG_EXIT_FALLBACK_MS = 1200;
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The tooltip's look, inline rather than through `VANILLA_TOOLTIP_DEFAULT_CLASS`: this tooltip is
|
|
47
|
+
* hoisted out of the tag, and that class's rule is scoped under `.ProseMirror` — see
|
|
48
|
+
* `resolveTooltipContainer`. Otherwise `vanillaTooltipDefaultStyles` in editor-core, which is the
|
|
49
|
+
* look every other vanilla tooltip has; keep the two in step.
|
|
50
|
+
*/
|
|
51
|
+
export var CONTRIBUTOR_TAG_TOOLTIP_STYLES = {
|
|
52
|
+
boxSizing: 'border-box',
|
|
53
|
+
maxWidth: '240px',
|
|
54
|
+
backgroundColor: "var(--ds-background-neutral-bold, #292A2E)",
|
|
55
|
+
// A `popover` is given one by the UA stylesheet.
|
|
56
|
+
border: 'none',
|
|
57
|
+
borderRadius: "var(--ds-radius-small, 3px)",
|
|
58
|
+
color: "var(--ds-text-inverse, #FFFFFF)",
|
|
59
|
+
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)",
|
|
60
|
+
fontFamily: "var(--ds-font-family-body, \"Atlassian Sans\", ui-sans-serif, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Ubuntu, \"Helvetica Neue\", sans-serif)",
|
|
61
|
+
overflowWrap: 'break-word',
|
|
62
|
+
paddingBlock: "var(--ds-space-050, 4px)",
|
|
63
|
+
paddingInline: "var(--ds-space-075, 6px)",
|
|
64
|
+
whiteSpace: 'normal',
|
|
65
|
+
// A tooltip is never a hit target — it hangs over the document's own content.
|
|
66
|
+
pointerEvents: 'none'
|
|
67
|
+
};
|
|
68
|
+
|
|
45
69
|
// Positioned against the host widget its decoration renders on the change's first character:
|
|
46
70
|
// `bottom: 100%` lifts the tag onto the line above, `inset-inline-start` starts it on that
|
|
47
71
|
// character.
|
|
@@ -6,7 +6,7 @@ import { bind, bindAll } from 'bind-event-listener';
|
|
|
6
6
|
import { VanillaTooltip } from '@atlaskit/editor-common/vanilla-tooltip';
|
|
7
7
|
import { getAccentTokens } from '../../pm-plugins/decorations/colorSchemes/factory';
|
|
8
8
|
import { colorSchemeRegistry } from '../../pm-plugins/decorations/colorSchemes/schemes';
|
|
9
|
-
import { buildContributorTagDom, CONTRIBUTOR_TAG_REVEALED_ATTRIBUTE, TAG_EXIT_FALLBACK_MS } from './buildContributorTagDom';
|
|
9
|
+
import { buildContributorTagDom, CONTRIBUTOR_TAG_REVEALED_ATTRIBUTE, CONTRIBUTOR_TAG_TOOLTIP_STYLES, TAG_EXIT_FALLBACK_MS } from './buildContributorTagDom';
|
|
10
10
|
import { contributorAvatarRenderer } from './contributorAvatarRenderer';
|
|
11
11
|
import { formatContributorLabel } from './contributorLabel';
|
|
12
12
|
/**
|
|
@@ -393,7 +393,7 @@ export var ContributorTagController = /*#__PURE__*/function () {
|
|
|
393
393
|
}, {
|
|
394
394
|
key: "syncTooltip",
|
|
395
395
|
value: function syncTooltip() {
|
|
396
|
-
var _this$tooltip2
|
|
396
|
+
var _this$tooltip2;
|
|
397
397
|
var content = this.dom ? this.fullLabel : undefined;
|
|
398
398
|
if (content === this.tooltipContent) {
|
|
399
399
|
return;
|
|
@@ -404,17 +404,39 @@ export var ContributorTagController = /*#__PURE__*/function () {
|
|
|
404
404
|
if (!content || !this.dom) {
|
|
405
405
|
return;
|
|
406
406
|
}
|
|
407
|
-
this.tooltip = new VanillaTooltip(this.dom.tag, content,
|
|
408
|
-
//
|
|
409
|
-
|
|
410
|
-
//
|
|
411
|
-
|
|
407
|
+
this.tooltip = new VanillaTooltip(this.dom.tag, content,
|
|
408
|
+
// Generated id.
|
|
409
|
+
undefined,
|
|
410
|
+
// No class: the look is inline, because a hoisted tooltip is outside the `.ProseMirror`
|
|
411
|
+
// scope `VANILLA_TOOLTIP_DEFAULT_CLASS` is keyed on — see `CONTRIBUTOR_TAG_TOOLTIP_STYLES`.
|
|
412
|
+
'',
|
|
413
|
+
// Default delay, no `onShow`, and the default `top` placement.
|
|
414
|
+
undefined, CONTRIBUTOR_TAG_TOOLTIP_STYLES, undefined, undefined, this.resolveTooltipContainer());
|
|
412
415
|
// `VanillaTooltip` sets `aria-describedby` on its trigger, which would announce the label a
|
|
413
416
|
// second time — the hidden child already announces it, and names the tag with it.
|
|
414
417
|
this.dom.tag.removeAttribute('aria-describedby');
|
|
415
|
-
//
|
|
416
|
-
// sentence. It stays visible for sighted users, who need the part of the name the tag
|
|
417
|
-
|
|
418
|
+
// Out of the tag but still in the document, so its text would otherwise be a third copy of the
|
|
419
|
+
// same sentence. It stays visible for sighted users, who need the part of the name the tag
|
|
420
|
+
// clipped.
|
|
421
|
+
this.tooltip.element.setAttribute('aria-hidden', 'true');
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/**
|
|
425
|
+
* Where the tooltip is appended, rather than inside the tag.
|
|
426
|
+
*
|
|
427
|
+
* Popper and the browser only agree on a top-layer popover's origin when nothing above it is
|
|
428
|
+
* transformed, and the tag hangs under the editor's own transformed nodes — inside a wide image
|
|
429
|
+
* that is `.rich-media-item`, whose `translateX(-50%)` threw the tooltip off screen
|
|
430
|
+
* (EDITOR-8971). The content area is the nearest ancestor with none of that above it, and keeps
|
|
431
|
+
* the tooltip inside the editor it belongs to; the document body covers an appearance that has
|
|
432
|
+
* no content area.
|
|
433
|
+
*/
|
|
434
|
+
}, {
|
|
435
|
+
key: "resolveTooltipContainer",
|
|
436
|
+
value: function resolveTooltipContainer() {
|
|
437
|
+
var _editorRoot$closest;
|
|
438
|
+
var editorRoot = this.options.getEditorRoot();
|
|
439
|
+
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;
|
|
418
440
|
}
|
|
419
441
|
|
|
420
442
|
/**
|
|
@@ -5,5 +5,18 @@ import type { ResolvedDiffContributors } from './colorSchemes/attributions';
|
|
|
5
5
|
* One model per diff decoration whose attribution resolves to a supplied contributor; anything
|
|
6
6
|
* unattributed, untaggable or unresolved is skipped. A replacement's two decorations are collapsed
|
|
7
7
|
* into a single tag, on whichever half renders first — see `isSameChange` and `leadsReplacement`.
|
|
8
|
+
*
|
|
9
|
+
* `activeIndexPos`, when given, reveals exactly one of the tags — see `resolveActiveTarget`.
|
|
10
|
+
* Absent, each tag keeps the active state its own decoration was drawn with.
|
|
11
|
+
*
|
|
12
|
+
* `stops`, when given, is the navigation stop list the step buttons walk
|
|
13
|
+
* (`getScrollableDecorations`). One contributor cannot hold two tags in one stop, since only the
|
|
14
|
+
* leading one would ever be reachable. Absent, every decoration keeps its own tag.
|
|
8
15
|
*/
|
|
9
|
-
export declare const extractContributorTags: (decorations: DecorationSet, contributors: ResolvedDiffContributors | undefined
|
|
16
|
+
export declare const extractContributorTags: (decorations: DecorationSet, contributors: ResolvedDiffContributors | undefined, activeIndexPos?: {
|
|
17
|
+
from: number;
|
|
18
|
+
to: number;
|
|
19
|
+
}, stops?: ReadonlyArray<{
|
|
20
|
+
from: number;
|
|
21
|
+
to: number;
|
|
22
|
+
}>) => ContributorTagModel[];
|
|
@@ -34,6 +34,13 @@ export declare const CONTRIBUTOR_TAG_REVEALED_ATTRIBUTE = "data-revealed";
|
|
|
34
34
|
* number — hence the wide margin. Raise in step with that duration.
|
|
35
35
|
*/
|
|
36
36
|
export declare const TAG_EXIT_FALLBACK_MS = 1200;
|
|
37
|
+
/**
|
|
38
|
+
* The tooltip's look, inline rather than through `VANILLA_TOOLTIP_DEFAULT_CLASS`: this tooltip is
|
|
39
|
+
* hoisted out of the tag, and that class's rule is scoped under `.ProseMirror` — see
|
|
40
|
+
* `resolveTooltipContainer`. Otherwise `vanillaTooltipDefaultStyles` in editor-core, which is the
|
|
41
|
+
* look every other vanilla tooltip has; keep the two in step.
|
|
42
|
+
*/
|
|
43
|
+
export declare const CONTRIBUTOR_TAG_TOOLTIP_STYLES: Readonly<Record<string, string>>;
|
|
37
44
|
export type ContributorTagDom = {
|
|
38
45
|
avatars: HTMLSpanElement;
|
|
39
46
|
name: HTMLSpanElement;
|
|
@@ -91,6 +91,17 @@ export declare class ContributorTagController {
|
|
|
91
91
|
* shape of `syncVanillaDisabledTooltip` in `mentionNodeView`.
|
|
92
92
|
*/
|
|
93
93
|
private syncTooltip;
|
|
94
|
+
/**
|
|
95
|
+
* Where the tooltip is appended, rather than inside the tag.
|
|
96
|
+
*
|
|
97
|
+
* Popper and the browser only agree on a top-layer popover's origin when nothing above it is
|
|
98
|
+
* transformed, and the tag hangs under the editor's own transformed nodes — inside a wide image
|
|
99
|
+
* that is `.rich-media-item`, whose `translateX(-50%)` threw the tooltip off screen
|
|
100
|
+
* (EDITOR-8971). The content area is the nearest ancestor with none of that above it, and keeps
|
|
101
|
+
* the tooltip inside the editor it belongs to; the document body covers an appearance that has
|
|
102
|
+
* no content area.
|
|
103
|
+
*/
|
|
104
|
+
private resolveTooltipContainer;
|
|
94
105
|
/**
|
|
95
106
|
* Observes the highlight this tag describes, for what CSS here cannot see: its hover state. The
|
|
96
107
|
* highlight is a ProseMirror decoration in a different DOM subtree, so listeners are bound
|
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.3",
|
|
4
4
|
"description": "ShowDiff plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@atlaskit/platform-feature-experiments": "^0.3.0",
|
|
33
33
|
"@atlaskit/platform-feature-flags": "^2.2.0",
|
|
34
34
|
"@atlaskit/primitives": "^22.5.0",
|
|
35
|
-
"@atlaskit/tmp-editor-statsig": "^
|
|
35
|
+
"@atlaskit/tmp-editor-statsig": "^190.0.0",
|
|
36
36
|
"@atlaskit/tokens": "^16.12.0",
|
|
37
37
|
"@babel/runtime": "^7.0.0",
|
|
38
38
|
"@compiled/react": "^1.0.2",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"@atlaskit/button": "^25.3.0",
|
|
47
47
|
"@atlaskit/css": "^1.1.0",
|
|
48
48
|
"@atlaskit/dropdown-menu": "^18.3.0",
|
|
49
|
-
"@atlaskit/editor-core": "^228.
|
|
49
|
+
"@atlaskit/editor-core": "^228.1.0",
|
|
50
50
|
"@atlaskit/editor-json-transformer": "^9.8.0",
|
|
51
51
|
"@atlaskit/editor-plugins": "^16.1.0",
|
|
52
52
|
"@atlaskit/form": "^17.2.0",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"react-intl": "^7.0.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"@atlaskit/editor-common": "^122.
|
|
67
|
+
"@atlaskit/editor-common": "^122.3.0",
|
|
68
68
|
"react": "^18.2.0 || ^19.2.0",
|
|
69
69
|
"react-dom": "^18.2.0 || ^19.2.0",
|
|
70
70
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|