@atlaskit/editor-plugin-mentions 18.2.10 → 18.3.1
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 +31 -0
- package/dist/cjs/nodeviews/mentionNodeView.js +2 -6
- package/dist/cjs/pm-plugins/main.js +1 -1
- package/dist/cjs/providers/mention-node-data-provider.js +68 -8
- package/dist/es2019/nodeviews/mentionNodeView.js +3 -7
- package/dist/es2019/pm-plugins/main.js +1 -1
- package/dist/es2019/providers/mention-node-data-provider.js +58 -5
- package/dist/esm/nodeviews/mentionNodeView.js +3 -7
- package/dist/esm/pm-plugins/main.js +1 -1
- package/dist/esm/providers/mention-node-data-provider.js +68 -8
- package/dist/types/providers/mention-node-data-provider.d.ts +11 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-mentions
|
|
2
2
|
|
|
3
|
+
## 18.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`27143ffe51a5a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/27143ffe51a5a) -
|
|
8
|
+
`@atlaskit/editor-common/vanilla-tooltip` now exports `VANILLA_TOOLTIP_DEFAULT_CLASS`. Compose
|
|
9
|
+
tooltip class names from it rather than repeating the `ak-editor-vanilla-tooltip-default` literal.
|
|
10
|
+
|
|
11
|
+
Behind the `platform_editor_use_vanilla_components` experiment, `VanillaTooltip`:
|
|
12
|
+
- no longer throws `InvalidStateError` when shown again before its open delay has elapsed
|
|
13
|
+
- is `pointer-events: none`, so it cannot swallow pointer events meant for the content beneath —
|
|
14
|
+
pass `pointerEvents` in `styles` to opt out
|
|
15
|
+
- closes its popover before `destroy()` removes it from the document
|
|
16
|
+
|
|
17
|
+
Remaining changes are internal: tooltip consumers adopt the new constant, and the emoji tooltip
|
|
18
|
+
uses the shared class in place of an equivalent inline style object.
|
|
19
|
+
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
|
|
22
|
+
## 18.3.0
|
|
23
|
+
|
|
24
|
+
### Minor Changes
|
|
25
|
+
|
|
26
|
+
- [`5a0128690a065`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/5a0128690a065) -
|
|
27
|
+
Add mention avatars to Rovo editor and renderer surfaces behind
|
|
28
|
+
platform_editor_rovo_editor_mention_node_avatar
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
|
|
3
34
|
## 18.2.10
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
|
@@ -31,12 +31,8 @@ var primitiveClassName = 'editor-mention-primitive';
|
|
|
31
31
|
var primitiveWithAvatarClassName = 'editor-mention-primitive-with-avatar';
|
|
32
32
|
var avatarContainerClassName = 'editor-mention-avatar';
|
|
33
33
|
var mentionTextClassName = 'editor-mention-text';
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
* the shared `VanillaTooltip` look, defined as `vanillaTooltipDefaultStyles` in both
|
|
37
|
-
* EditorContentContainer stylesheets — keep them in sync when renaming.
|
|
38
|
-
*/
|
|
39
|
-
var disabledTooltipClassNames = 'ak-editor-vanilla-tooltip-default mention-disabled-tooltip';
|
|
34
|
+
/** Classes applied to the disabled-reason tooltip: the shared default look, plus our own hook. */
|
|
35
|
+
var disabledTooltipClassNames = "".concat(_vanillaTooltip.VANILLA_TOOLTIP_DEFAULT_CLASS, " mention-disabled-tooltip");
|
|
40
36
|
var genericMentionIds = ['HipChat', 'all', 'here'];
|
|
41
37
|
var unknownMentionText = "@".concat(_constants.UNKNOWN_USER_ID);
|
|
42
38
|
// eslint-disable-next-line require-unicode-regexp
|
|
@@ -43,7 +43,7 @@ var ACTIONS = exports.ACTIONS = {
|
|
|
43
43
|
CLEAR_PENDING_PASTED_AGENT_MENTION: 'CLEAR_PENDING_PASTED_AGENT_MENTION'
|
|
44
44
|
};
|
|
45
45
|
var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
46
|
-
var PACKAGE_VERSION = "18.
|
|
46
|
+
var PACKAGE_VERSION = "18.3.0";
|
|
47
47
|
var setProvider = function setProvider(provider) {
|
|
48
48
|
return function (state, dispatch) {
|
|
49
49
|
if (dispatch) {
|
|
@@ -42,6 +42,20 @@ var toMentionNode = function toMentionNode(_ref) {
|
|
|
42
42
|
var isMentionNode = function isMentionNode(node) {
|
|
43
43
|
return node.type === 'mention' && node.attrs !== undefined && 'id' in node.attrs && typeof node.attrs.id === 'string';
|
|
44
44
|
};
|
|
45
|
+
var SUBSCRIPTION_KEY_PREFIX = 'mention-node-data-provider';
|
|
46
|
+
var subscriptionKeyCounter = 0;
|
|
47
|
+
var cacheMentionData = function cacheMentionData(cache, mentions) {
|
|
48
|
+
mentions.forEach(function (mention) {
|
|
49
|
+
if (mention.isPlaceholder || !mention.avatarUrl) {
|
|
50
|
+
cache.delete(mention.id);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
cache.set(mention.id, {
|
|
54
|
+
avatarUrl: mention.avatarUrl,
|
|
55
|
+
appType: mention.appType
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
};
|
|
45
59
|
|
|
46
60
|
/**
|
|
47
61
|
* Page-scoped data provider for mention avatars.
|
|
@@ -59,6 +73,9 @@ var isMentionNode = function isMentionNode(node) {
|
|
|
59
73
|
* invoked. A Relay adapter can query `users(accountIds:)`, then map each user's
|
|
60
74
|
* `picture` and app type to a `MentionNodeData` record keyed by account ID. The
|
|
61
75
|
* resolved result is cached by the underlying `NodeDataProvider`.
|
|
76
|
+
*
|
|
77
|
+
* Products that already have a `MentionProvider` result stream can call `connect`
|
|
78
|
+
* so emitted mention results populate a synchronous avatar cache.
|
|
62
79
|
*/
|
|
63
80
|
var MentionNodeDataProvider = exports.MentionNodeDataProvider = /*#__PURE__*/function (_NodeDataProvider) {
|
|
64
81
|
function MentionNodeDataProvider(fetchMentionNodeData) {
|
|
@@ -67,6 +84,11 @@ var MentionNodeDataProvider = exports.MentionNodeDataProvider = /*#__PURE__*/fun
|
|
|
67
84
|
(0, _classCallCheck2.default)(this, MentionNodeDataProvider);
|
|
68
85
|
_this = _callSuper(this, MentionNodeDataProvider);
|
|
69
86
|
(0, _defineProperty2.default)(_this, "name", 'mentionNodeDataProvider');
|
|
87
|
+
(0, _defineProperty2.default)(_this, "abortControllerRef", {
|
|
88
|
+
current: new AbortController()
|
|
89
|
+
});
|
|
90
|
+
(0, _defineProperty2.default)(_this, "emittedMentionCache", new Map());
|
|
91
|
+
(0, _defineProperty2.default)(_this, "subscriptionKey", "".concat(SUBSCRIPTION_KEY_PREFIX, ":").concat(++subscriptionKeyCounter));
|
|
70
92
|
(0, _defineProperty2.default)(_this, "queuedFetches", []);
|
|
71
93
|
(0, _defineProperty2.default)(_this, "isFlushScheduled", false);
|
|
72
94
|
_this.fetchMentionNodeData = fetchMentionNodeData;
|
|
@@ -118,8 +140,7 @@ var MentionNodeDataProvider = exports.MentionNodeDataProvider = /*#__PURE__*/fun
|
|
|
118
140
|
}, {
|
|
119
141
|
key: "getMentionData",
|
|
120
142
|
value: function getMentionData(mention, callback) {
|
|
121
|
-
var
|
|
122
|
-
var resolvedData = (_this$resolveMentionN = this.resolveMentionNodeData) === null || _this$resolveMentionN === void 0 ? void 0 : _this$resolveMentionN.call(this, mention);
|
|
143
|
+
var resolvedData = this.resolveMentionNodeDataFromCache(mention);
|
|
123
144
|
if (resolvedData) {
|
|
124
145
|
callback({
|
|
125
146
|
data: enrichMentionNodeData(mention, resolvedData)
|
|
@@ -131,20 +152,59 @@ var MentionNodeDataProvider = exports.MentionNodeDataProvider = /*#__PURE__*/fun
|
|
|
131
152
|
}, {
|
|
132
153
|
key: "getMentionDataFromCache",
|
|
133
154
|
value: function getMentionDataFromCache(mention) {
|
|
134
|
-
var _this$
|
|
135
|
-
var resolvedData =
|
|
155
|
+
var _this$getNodeDataFrom;
|
|
156
|
+
var resolvedData = this.resolveMentionNodeDataFromCache(mention);
|
|
136
157
|
if (resolvedData) {
|
|
137
158
|
return enrichMentionNodeData(mention, resolvedData);
|
|
138
159
|
}
|
|
139
160
|
var data = (_this$getNodeDataFrom = this.getNodeDataFromCache(toMentionNode(mention))) === null || _this$getNodeDataFrom === void 0 ? void 0 : _this$getNodeDataFrom.data;
|
|
140
161
|
return data ? enrichMentionNodeData(mention, data) : undefined;
|
|
141
162
|
}
|
|
163
|
+
}, {
|
|
164
|
+
key: "connect",
|
|
165
|
+
value: function connect(mentionResource) {
|
|
166
|
+
var _this2 = this;
|
|
167
|
+
if (this.lastMentionResource && this.lastMentionResource !== mentionResource) {
|
|
168
|
+
this.emittedMentionCache.clear();
|
|
169
|
+
this.resetCache();
|
|
170
|
+
}
|
|
171
|
+
this.lastMentionResource = mentionResource;
|
|
172
|
+
if (this.abortControllerRef.current.signal.aborted) {
|
|
173
|
+
this.abortControllerRef.current = new AbortController();
|
|
174
|
+
}
|
|
175
|
+
var isDisconnected = false;
|
|
176
|
+
var subscribedMentionProvider;
|
|
177
|
+
void mentionResource.then(function (mentionProvider) {
|
|
178
|
+
if (isDisconnected) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
subscribedMentionProvider = mentionProvider;
|
|
182
|
+
mentionProvider.subscribe(_this2.subscriptionKey, function (mentions) {
|
|
183
|
+
cacheMentionData(_this2.emittedMentionCache, mentions);
|
|
184
|
+
});
|
|
185
|
+
}).catch(function () {
|
|
186
|
+
return undefined;
|
|
187
|
+
});
|
|
188
|
+
return function () {
|
|
189
|
+
var _subscribedMentionPro;
|
|
190
|
+
isDisconnected = true;
|
|
191
|
+
_this2.abortControllerRef.current.abort();
|
|
192
|
+
(_subscribedMentionPro = subscribedMentionProvider) === null || _subscribedMentionPro === void 0 || _subscribedMentionPro.unsubscribe(_this2.subscriptionKey);
|
|
193
|
+
subscribedMentionProvider = undefined;
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}, {
|
|
197
|
+
key: "resolveMentionNodeDataFromCache",
|
|
198
|
+
value: function resolveMentionNodeDataFromCache(mention) {
|
|
199
|
+
var _this$resolveMentionN, _this$resolveMentionN2;
|
|
200
|
+
return (_this$resolveMentionN = (_this$resolveMentionN2 = this.resolveMentionNodeData) === null || _this$resolveMentionN2 === void 0 ? void 0 : _this$resolveMentionN2.call(this, mention)) !== null && _this$resolveMentionN !== void 0 ? _this$resolveMentionN : this.emittedMentionCache.get(mention.id);
|
|
201
|
+
}
|
|
142
202
|
}, {
|
|
143
203
|
key: "enqueueFetch",
|
|
144
204
|
value: function enqueueFetch(accountIds) {
|
|
145
|
-
var
|
|
205
|
+
var _this3 = this;
|
|
146
206
|
var result = new Promise(function (resolve, reject) {
|
|
147
|
-
|
|
207
|
+
_this3.queuedFetches.push({
|
|
148
208
|
accountIds: accountIds,
|
|
149
209
|
reject: reject,
|
|
150
210
|
resolve: resolve
|
|
@@ -153,7 +213,7 @@ var MentionNodeDataProvider = exports.MentionNodeDataProvider = /*#__PURE__*/fun
|
|
|
153
213
|
if (!this.isFlushScheduled) {
|
|
154
214
|
this.isFlushScheduled = true;
|
|
155
215
|
void Promise.resolve().then(function () {
|
|
156
|
-
return
|
|
216
|
+
return _this3.flushFetches();
|
|
157
217
|
});
|
|
158
218
|
}
|
|
159
219
|
return result;
|
|
@@ -174,7 +234,7 @@ var MentionNodeDataProvider = exports.MentionNodeDataProvider = /*#__PURE__*/fun
|
|
|
174
234
|
})));
|
|
175
235
|
_context2.prev = 1;
|
|
176
236
|
_context2.next = 2;
|
|
177
|
-
return this.fetchMentionNodeData(accountIds);
|
|
237
|
+
return this.fetchMentionNodeData(accountIds, this.abortControllerRef.current.signal);
|
|
178
238
|
case 2:
|
|
179
239
|
data = _context2.sent;
|
|
180
240
|
queuedFetches.forEach(function (_ref4) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { getBrowserInfo } from '@atlaskit/editor-common/browser';
|
|
3
3
|
import { isSSR } from '@atlaskit/editor-common/core-utils';
|
|
4
|
-
import { VanillaTooltip } from '@atlaskit/editor-common/vanilla-tooltip';
|
|
4
|
+
import { VANILLA_TOOLTIP_DEFAULT_CLASS, VanillaTooltip } from '@atlaskit/editor-common/vanilla-tooltip';
|
|
5
5
|
import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
|
|
6
6
|
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
7
7
|
// oxlint-disable-next-line import/no-duplicates
|
|
@@ -20,12 +20,8 @@ const primitiveClassName = 'editor-mention-primitive';
|
|
|
20
20
|
const primitiveWithAvatarClassName = 'editor-mention-primitive-with-avatar';
|
|
21
21
|
const avatarContainerClassName = 'editor-mention-avatar';
|
|
22
22
|
const mentionTextClassName = 'editor-mention-text';
|
|
23
|
-
/**
|
|
24
|
-
|
|
25
|
-
* the shared `VanillaTooltip` look, defined as `vanillaTooltipDefaultStyles` in both
|
|
26
|
-
* EditorContentContainer stylesheets — keep them in sync when renaming.
|
|
27
|
-
*/
|
|
28
|
-
const disabledTooltipClassNames = 'ak-editor-vanilla-tooltip-default mention-disabled-tooltip';
|
|
23
|
+
/** Classes applied to the disabled-reason tooltip: the shared default look, plus our own hook. */
|
|
24
|
+
const disabledTooltipClassNames = `${VANILLA_TOOLTIP_DEFAULT_CLASS} mention-disabled-tooltip`;
|
|
29
25
|
const genericMentionIds = ['HipChat', 'all', 'here'];
|
|
30
26
|
const unknownMentionText = `@${UNKNOWN_USER_ID}`;
|
|
31
27
|
// eslint-disable-next-line require-unicode-regexp
|
|
@@ -32,7 +32,7 @@ export const ACTIONS = {
|
|
|
32
32
|
CLEAR_PENDING_PASTED_AGENT_MENTION: 'CLEAR_PENDING_PASTED_AGENT_MENTION'
|
|
33
33
|
};
|
|
34
34
|
const PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
35
|
-
const PACKAGE_VERSION = "18.
|
|
35
|
+
const PACKAGE_VERSION = "18.3.0";
|
|
36
36
|
const setProvider = provider => (state, dispatch) => {
|
|
37
37
|
if (dispatch) {
|
|
38
38
|
dispatch(state.tr.setMeta(mentionPluginKey, {
|
|
@@ -20,6 +20,20 @@ const toMentionNode = ({
|
|
|
20
20
|
type: 'mention'
|
|
21
21
|
});
|
|
22
22
|
const isMentionNode = node => node.type === 'mention' && node.attrs !== undefined && 'id' in node.attrs && typeof node.attrs.id === 'string';
|
|
23
|
+
const SUBSCRIPTION_KEY_PREFIX = 'mention-node-data-provider';
|
|
24
|
+
let subscriptionKeyCounter = 0;
|
|
25
|
+
const cacheMentionData = (cache, mentions) => {
|
|
26
|
+
mentions.forEach(mention => {
|
|
27
|
+
if (mention.isPlaceholder || !mention.avatarUrl) {
|
|
28
|
+
cache.delete(mention.id);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
cache.set(mention.id, {
|
|
32
|
+
avatarUrl: mention.avatarUrl,
|
|
33
|
+
appType: mention.appType
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
};
|
|
23
37
|
|
|
24
38
|
/**
|
|
25
39
|
* Page-scoped data provider for mention avatars.
|
|
@@ -37,11 +51,19 @@ const isMentionNode = node => node.type === 'mention' && node.attrs !== undefine
|
|
|
37
51
|
* invoked. A Relay adapter can query `users(accountIds:)`, then map each user's
|
|
38
52
|
* `picture` and app type to a `MentionNodeData` record keyed by account ID. The
|
|
39
53
|
* resolved result is cached by the underlying `NodeDataProvider`.
|
|
54
|
+
*
|
|
55
|
+
* Products that already have a `MentionProvider` result stream can call `connect`
|
|
56
|
+
* so emitted mention results populate a synchronous avatar cache.
|
|
40
57
|
*/
|
|
41
58
|
export class MentionNodeDataProvider extends NodeDataProvider {
|
|
42
59
|
constructor(fetchMentionNodeData, resolveMentionNodeData = undefined) {
|
|
43
60
|
super();
|
|
44
61
|
_defineProperty(this, "name", 'mentionNodeDataProvider');
|
|
62
|
+
_defineProperty(this, "abortControllerRef", {
|
|
63
|
+
current: new AbortController()
|
|
64
|
+
});
|
|
65
|
+
_defineProperty(this, "emittedMentionCache", new Map());
|
|
66
|
+
_defineProperty(this, "subscriptionKey", `${SUBSCRIPTION_KEY_PREFIX}:${++subscriptionKeyCounter}`);
|
|
45
67
|
_defineProperty(this, "queuedFetches", []);
|
|
46
68
|
_defineProperty(this, "isFlushScheduled", false);
|
|
47
69
|
this.fetchMentionNodeData = fetchMentionNodeData;
|
|
@@ -63,8 +85,7 @@ export class MentionNodeDataProvider extends NodeDataProvider {
|
|
|
63
85
|
}) => enrichMentionNodeData(attrs, dataByAccountId[attrs.id]));
|
|
64
86
|
}
|
|
65
87
|
getMentionData(mention, callback) {
|
|
66
|
-
|
|
67
|
-
const resolvedData = (_this$resolveMentionN = this.resolveMentionNodeData) === null || _this$resolveMentionN === void 0 ? void 0 : _this$resolveMentionN.call(this, mention);
|
|
88
|
+
const resolvedData = this.resolveMentionNodeDataFromCache(mention);
|
|
68
89
|
if (resolvedData) {
|
|
69
90
|
callback({
|
|
70
91
|
data: enrichMentionNodeData(mention, resolvedData)
|
|
@@ -74,14 +95,46 @@ export class MentionNodeDataProvider extends NodeDataProvider {
|
|
|
74
95
|
this.getData(toMentionNode(mention), callback);
|
|
75
96
|
}
|
|
76
97
|
getMentionDataFromCache(mention) {
|
|
77
|
-
var _this$
|
|
78
|
-
const resolvedData =
|
|
98
|
+
var _this$getNodeDataFrom;
|
|
99
|
+
const resolvedData = this.resolveMentionNodeDataFromCache(mention);
|
|
79
100
|
if (resolvedData) {
|
|
80
101
|
return enrichMentionNodeData(mention, resolvedData);
|
|
81
102
|
}
|
|
82
103
|
const data = (_this$getNodeDataFrom = this.getNodeDataFromCache(toMentionNode(mention))) === null || _this$getNodeDataFrom === void 0 ? void 0 : _this$getNodeDataFrom.data;
|
|
83
104
|
return data ? enrichMentionNodeData(mention, data) : undefined;
|
|
84
105
|
}
|
|
106
|
+
connect(mentionResource) {
|
|
107
|
+
if (this.lastMentionResource && this.lastMentionResource !== mentionResource) {
|
|
108
|
+
this.emittedMentionCache.clear();
|
|
109
|
+
this.resetCache();
|
|
110
|
+
}
|
|
111
|
+
this.lastMentionResource = mentionResource;
|
|
112
|
+
if (this.abortControllerRef.current.signal.aborted) {
|
|
113
|
+
this.abortControllerRef.current = new AbortController();
|
|
114
|
+
}
|
|
115
|
+
let isDisconnected = false;
|
|
116
|
+
let subscribedMentionProvider;
|
|
117
|
+
void mentionResource.then(mentionProvider => {
|
|
118
|
+
if (isDisconnected) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
subscribedMentionProvider = mentionProvider;
|
|
122
|
+
mentionProvider.subscribe(this.subscriptionKey, mentions => {
|
|
123
|
+
cacheMentionData(this.emittedMentionCache, mentions);
|
|
124
|
+
});
|
|
125
|
+
}).catch(() => undefined);
|
|
126
|
+
return () => {
|
|
127
|
+
var _subscribedMentionPro;
|
|
128
|
+
isDisconnected = true;
|
|
129
|
+
this.abortControllerRef.current.abort();
|
|
130
|
+
(_subscribedMentionPro = subscribedMentionProvider) === null || _subscribedMentionPro === void 0 ? void 0 : _subscribedMentionPro.unsubscribe(this.subscriptionKey);
|
|
131
|
+
subscribedMentionProvider = undefined;
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
resolveMentionNodeDataFromCache(mention) {
|
|
135
|
+
var _this$resolveMentionN, _this$resolveMentionN2;
|
|
136
|
+
return (_this$resolveMentionN = (_this$resolveMentionN2 = this.resolveMentionNodeData) === null || _this$resolveMentionN2 === void 0 ? void 0 : _this$resolveMentionN2.call(this, mention)) !== null && _this$resolveMentionN !== void 0 ? _this$resolveMentionN : this.emittedMentionCache.get(mention.id);
|
|
137
|
+
}
|
|
85
138
|
enqueueFetch(accountIds) {
|
|
86
139
|
const result = new Promise((resolve, reject) => {
|
|
87
140
|
this.queuedFetches.push({
|
|
@@ -102,7 +155,7 @@ export class MentionNodeDataProvider extends NodeDataProvider {
|
|
|
102
155
|
this.queuedFetches = [];
|
|
103
156
|
const accountIds = Array.from(new Set(queuedFetches.flatMap(request => request.accountIds)));
|
|
104
157
|
try {
|
|
105
|
-
const data = await this.fetchMentionNodeData(accountIds);
|
|
158
|
+
const data = await this.fetchMentionNodeData(accountIds, this.abortControllerRef.current.signal);
|
|
106
159
|
queuedFetches.forEach(({
|
|
107
160
|
resolve
|
|
108
161
|
}) => resolve(data));
|
|
@@ -7,7 +7,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
|
|
|
7
7
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
8
8
|
import { getBrowserInfo } from '@atlaskit/editor-common/browser';
|
|
9
9
|
import { isSSR } from '@atlaskit/editor-common/core-utils';
|
|
10
|
-
import { VanillaTooltip } from '@atlaskit/editor-common/vanilla-tooltip';
|
|
10
|
+
import { VANILLA_TOOLTIP_DEFAULT_CLASS, VanillaTooltip } from '@atlaskit/editor-common/vanilla-tooltip';
|
|
11
11
|
import { ZERO_WIDTH_SPACE } from '@atlaskit/editor-common/whitespace';
|
|
12
12
|
import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
|
|
13
13
|
// oxlint-disable-next-line import/no-duplicates
|
|
@@ -26,12 +26,8 @@ var primitiveClassName = 'editor-mention-primitive';
|
|
|
26
26
|
var primitiveWithAvatarClassName = 'editor-mention-primitive-with-avatar';
|
|
27
27
|
var avatarContainerClassName = 'editor-mention-avatar';
|
|
28
28
|
var mentionTextClassName = 'editor-mention-text';
|
|
29
|
-
/**
|
|
30
|
-
|
|
31
|
-
* the shared `VanillaTooltip` look, defined as `vanillaTooltipDefaultStyles` in both
|
|
32
|
-
* EditorContentContainer stylesheets — keep them in sync when renaming.
|
|
33
|
-
*/
|
|
34
|
-
var disabledTooltipClassNames = 'ak-editor-vanilla-tooltip-default mention-disabled-tooltip';
|
|
29
|
+
/** Classes applied to the disabled-reason tooltip: the shared default look, plus our own hook. */
|
|
30
|
+
var disabledTooltipClassNames = "".concat(VANILLA_TOOLTIP_DEFAULT_CLASS, " mention-disabled-tooltip");
|
|
35
31
|
var genericMentionIds = ['HipChat', 'all', 'here'];
|
|
36
32
|
var unknownMentionText = "@".concat(UNKNOWN_USER_ID);
|
|
37
33
|
// eslint-disable-next-line require-unicode-regexp
|
|
@@ -35,7 +35,7 @@ export var ACTIONS = {
|
|
|
35
35
|
CLEAR_PENDING_PASTED_AGENT_MENTION: 'CLEAR_PENDING_PASTED_AGENT_MENTION'
|
|
36
36
|
};
|
|
37
37
|
var PACKAGE_NAME = "@atlaskit/editor-plugin-mentions";
|
|
38
|
-
var PACKAGE_VERSION = "18.
|
|
38
|
+
var PACKAGE_VERSION = "18.3.0";
|
|
39
39
|
var setProvider = function setProvider(provider) {
|
|
40
40
|
return function (state, dispatch) {
|
|
41
41
|
if (dispatch) {
|
|
@@ -35,6 +35,20 @@ var toMentionNode = function toMentionNode(_ref) {
|
|
|
35
35
|
var isMentionNode = function isMentionNode(node) {
|
|
36
36
|
return node.type === 'mention' && node.attrs !== undefined && 'id' in node.attrs && typeof node.attrs.id === 'string';
|
|
37
37
|
};
|
|
38
|
+
var SUBSCRIPTION_KEY_PREFIX = 'mention-node-data-provider';
|
|
39
|
+
var subscriptionKeyCounter = 0;
|
|
40
|
+
var cacheMentionData = function cacheMentionData(cache, mentions) {
|
|
41
|
+
mentions.forEach(function (mention) {
|
|
42
|
+
if (mention.isPlaceholder || !mention.avatarUrl) {
|
|
43
|
+
cache.delete(mention.id);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
cache.set(mention.id, {
|
|
47
|
+
avatarUrl: mention.avatarUrl,
|
|
48
|
+
appType: mention.appType
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
};
|
|
38
52
|
|
|
39
53
|
/**
|
|
40
54
|
* Page-scoped data provider for mention avatars.
|
|
@@ -52,6 +66,9 @@ var isMentionNode = function isMentionNode(node) {
|
|
|
52
66
|
* invoked. A Relay adapter can query `users(accountIds:)`, then map each user's
|
|
53
67
|
* `picture` and app type to a `MentionNodeData` record keyed by account ID. The
|
|
54
68
|
* resolved result is cached by the underlying `NodeDataProvider`.
|
|
69
|
+
*
|
|
70
|
+
* Products that already have a `MentionProvider` result stream can call `connect`
|
|
71
|
+
* so emitted mention results populate a synchronous avatar cache.
|
|
55
72
|
*/
|
|
56
73
|
export var MentionNodeDataProvider = /*#__PURE__*/function (_NodeDataProvider) {
|
|
57
74
|
function MentionNodeDataProvider(fetchMentionNodeData) {
|
|
@@ -60,6 +77,11 @@ export var MentionNodeDataProvider = /*#__PURE__*/function (_NodeDataProvider) {
|
|
|
60
77
|
_classCallCheck(this, MentionNodeDataProvider);
|
|
61
78
|
_this = _callSuper(this, MentionNodeDataProvider);
|
|
62
79
|
_defineProperty(_this, "name", 'mentionNodeDataProvider');
|
|
80
|
+
_defineProperty(_this, "abortControllerRef", {
|
|
81
|
+
current: new AbortController()
|
|
82
|
+
});
|
|
83
|
+
_defineProperty(_this, "emittedMentionCache", new Map());
|
|
84
|
+
_defineProperty(_this, "subscriptionKey", "".concat(SUBSCRIPTION_KEY_PREFIX, ":").concat(++subscriptionKeyCounter));
|
|
63
85
|
_defineProperty(_this, "queuedFetches", []);
|
|
64
86
|
_defineProperty(_this, "isFlushScheduled", false);
|
|
65
87
|
_this.fetchMentionNodeData = fetchMentionNodeData;
|
|
@@ -111,8 +133,7 @@ export var MentionNodeDataProvider = /*#__PURE__*/function (_NodeDataProvider) {
|
|
|
111
133
|
}, {
|
|
112
134
|
key: "getMentionData",
|
|
113
135
|
value: function getMentionData(mention, callback) {
|
|
114
|
-
var
|
|
115
|
-
var resolvedData = (_this$resolveMentionN = this.resolveMentionNodeData) === null || _this$resolveMentionN === void 0 ? void 0 : _this$resolveMentionN.call(this, mention);
|
|
136
|
+
var resolvedData = this.resolveMentionNodeDataFromCache(mention);
|
|
116
137
|
if (resolvedData) {
|
|
117
138
|
callback({
|
|
118
139
|
data: enrichMentionNodeData(mention, resolvedData)
|
|
@@ -124,20 +145,59 @@ export var MentionNodeDataProvider = /*#__PURE__*/function (_NodeDataProvider) {
|
|
|
124
145
|
}, {
|
|
125
146
|
key: "getMentionDataFromCache",
|
|
126
147
|
value: function getMentionDataFromCache(mention) {
|
|
127
|
-
var _this$
|
|
128
|
-
var resolvedData =
|
|
148
|
+
var _this$getNodeDataFrom;
|
|
149
|
+
var resolvedData = this.resolveMentionNodeDataFromCache(mention);
|
|
129
150
|
if (resolvedData) {
|
|
130
151
|
return enrichMentionNodeData(mention, resolvedData);
|
|
131
152
|
}
|
|
132
153
|
var data = (_this$getNodeDataFrom = this.getNodeDataFromCache(toMentionNode(mention))) === null || _this$getNodeDataFrom === void 0 ? void 0 : _this$getNodeDataFrom.data;
|
|
133
154
|
return data ? enrichMentionNodeData(mention, data) : undefined;
|
|
134
155
|
}
|
|
156
|
+
}, {
|
|
157
|
+
key: "connect",
|
|
158
|
+
value: function connect(mentionResource) {
|
|
159
|
+
var _this2 = this;
|
|
160
|
+
if (this.lastMentionResource && this.lastMentionResource !== mentionResource) {
|
|
161
|
+
this.emittedMentionCache.clear();
|
|
162
|
+
this.resetCache();
|
|
163
|
+
}
|
|
164
|
+
this.lastMentionResource = mentionResource;
|
|
165
|
+
if (this.abortControllerRef.current.signal.aborted) {
|
|
166
|
+
this.abortControllerRef.current = new AbortController();
|
|
167
|
+
}
|
|
168
|
+
var isDisconnected = false;
|
|
169
|
+
var subscribedMentionProvider;
|
|
170
|
+
void mentionResource.then(function (mentionProvider) {
|
|
171
|
+
if (isDisconnected) {
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
subscribedMentionProvider = mentionProvider;
|
|
175
|
+
mentionProvider.subscribe(_this2.subscriptionKey, function (mentions) {
|
|
176
|
+
cacheMentionData(_this2.emittedMentionCache, mentions);
|
|
177
|
+
});
|
|
178
|
+
}).catch(function () {
|
|
179
|
+
return undefined;
|
|
180
|
+
});
|
|
181
|
+
return function () {
|
|
182
|
+
var _subscribedMentionPro;
|
|
183
|
+
isDisconnected = true;
|
|
184
|
+
_this2.abortControllerRef.current.abort();
|
|
185
|
+
(_subscribedMentionPro = subscribedMentionProvider) === null || _subscribedMentionPro === void 0 || _subscribedMentionPro.unsubscribe(_this2.subscriptionKey);
|
|
186
|
+
subscribedMentionProvider = undefined;
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}, {
|
|
190
|
+
key: "resolveMentionNodeDataFromCache",
|
|
191
|
+
value: function resolveMentionNodeDataFromCache(mention) {
|
|
192
|
+
var _this$resolveMentionN, _this$resolveMentionN2;
|
|
193
|
+
return (_this$resolveMentionN = (_this$resolveMentionN2 = this.resolveMentionNodeData) === null || _this$resolveMentionN2 === void 0 ? void 0 : _this$resolveMentionN2.call(this, mention)) !== null && _this$resolveMentionN !== void 0 ? _this$resolveMentionN : this.emittedMentionCache.get(mention.id);
|
|
194
|
+
}
|
|
135
195
|
}, {
|
|
136
196
|
key: "enqueueFetch",
|
|
137
197
|
value: function enqueueFetch(accountIds) {
|
|
138
|
-
var
|
|
198
|
+
var _this3 = this;
|
|
139
199
|
var result = new Promise(function (resolve, reject) {
|
|
140
|
-
|
|
200
|
+
_this3.queuedFetches.push({
|
|
141
201
|
accountIds: accountIds,
|
|
142
202
|
reject: reject,
|
|
143
203
|
resolve: resolve
|
|
@@ -146,7 +206,7 @@ export var MentionNodeDataProvider = /*#__PURE__*/function (_NodeDataProvider) {
|
|
|
146
206
|
if (!this.isFlushScheduled) {
|
|
147
207
|
this.isFlushScheduled = true;
|
|
148
208
|
void Promise.resolve().then(function () {
|
|
149
|
-
return
|
|
209
|
+
return _this3.flushFetches();
|
|
150
210
|
});
|
|
151
211
|
}
|
|
152
212
|
return result;
|
|
@@ -167,7 +227,7 @@ export var MentionNodeDataProvider = /*#__PURE__*/function (_NodeDataProvider) {
|
|
|
167
227
|
})));
|
|
168
228
|
_context2.prev = 1;
|
|
169
229
|
_context2.next = 2;
|
|
170
|
-
return this.fetchMentionNodeData(accountIds);
|
|
230
|
+
return this.fetchMentionNodeData(accountIds, this.abortControllerRef.current.signal);
|
|
171
231
|
case 2:
|
|
172
232
|
data = _context2.sent;
|
|
173
233
|
queuedFetches.forEach(function (_ref4) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { MentionDefinition } from '@atlaskit/adf-schema/mention';
|
|
2
2
|
import type { MentionNodeDataCallback, MentionNodeDataIdentifier, MentionNodeDataProvider as MentionNodeDataProviderContract } from '@atlaskit/editor-common/mention';
|
|
3
3
|
import type { JSONNode } from '@atlaskit/editor-json-transformer/types';
|
|
4
|
+
import type { MentionProvider } from '@atlaskit/mention/resource';
|
|
4
5
|
import type { MentionNodeData } from '@atlaskit/mention/types';
|
|
5
6
|
import { NodeDataProvider } from '@atlaskit/node-data-provider/node-data-provider';
|
|
6
|
-
export type FetchMentionNodeData = (accountIds: string[]) => Promise<Record<string, MentionNodeData>>;
|
|
7
|
+
export type FetchMentionNodeData = (accountIds: string[], signal?: AbortSignal) => Promise<Record<string, MentionNodeData>>;
|
|
7
8
|
export type ResolveMentionNodeData = (mention: MentionNodeDataIdentifier) => MentionNodeData | undefined;
|
|
8
9
|
/**
|
|
9
10
|
* Page-scoped data provider for mention avatars.
|
|
@@ -21,11 +22,18 @@ export type ResolveMentionNodeData = (mention: MentionNodeDataIdentifier) => Men
|
|
|
21
22
|
* invoked. A Relay adapter can query `users(accountIds:)`, then map each user's
|
|
22
23
|
* `picture` and app type to a `MentionNodeData` record keyed by account ID. The
|
|
23
24
|
* resolved result is cached by the underlying `NodeDataProvider`.
|
|
25
|
+
*
|
|
26
|
+
* Products that already have a `MentionProvider` result stream can call `connect`
|
|
27
|
+
* so emitted mention results populate a synchronous avatar cache.
|
|
24
28
|
*/
|
|
25
29
|
export declare class MentionNodeDataProvider extends NodeDataProvider<MentionDefinition, MentionNodeData> implements MentionNodeDataProviderContract {
|
|
26
30
|
private readonly fetchMentionNodeData;
|
|
27
31
|
private readonly resolveMentionNodeData;
|
|
28
32
|
readonly name = "mentionNodeDataProvider";
|
|
33
|
+
private readonly abortControllerRef;
|
|
34
|
+
private readonly emittedMentionCache;
|
|
35
|
+
private readonly subscriptionKey;
|
|
36
|
+
private lastMentionResource;
|
|
29
37
|
private queuedFetches;
|
|
30
38
|
private isFlushScheduled;
|
|
31
39
|
constructor(fetchMentionNodeData: FetchMentionNodeData, resolveMentionNodeData?: ResolveMentionNodeData | undefined);
|
|
@@ -34,6 +42,8 @@ export declare class MentionNodeDataProvider extends NodeDataProvider<MentionDef
|
|
|
34
42
|
fetchNodesData(nodes: MentionDefinition[]): Promise<MentionNodeData[]>;
|
|
35
43
|
getMentionData(mention: MentionNodeDataIdentifier, callback: MentionNodeDataCallback): void;
|
|
36
44
|
getMentionDataFromCache(mention: MentionNodeDataIdentifier): MentionNodeData | undefined;
|
|
45
|
+
connect(mentionResource: Promise<MentionProvider>): () => void;
|
|
46
|
+
private resolveMentionNodeDataFromCache;
|
|
37
47
|
private enqueueFetch;
|
|
38
48
|
private flushFetches;
|
|
39
49
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-mentions",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.3.1",
|
|
4
4
|
"description": "Mentions plugin for @atlaskit/editor-core",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -59,14 +59,14 @@
|
|
|
59
59
|
"uuid": "^11.1.1"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
|
-
"@atlaskit/editor-common": "^120.
|
|
62
|
+
"@atlaskit/editor-common": "^120.15.0",
|
|
63
63
|
"react": "^18.2.0 || ^19.2.0",
|
|
64
64
|
"react-dom": "^18.2.0 || ^19.2.0",
|
|
65
65
|
"react-intl": "^5.25.1 || ^6.0.0 || ^7.0.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@atlaskit/button": "^25.3.0",
|
|
69
|
-
"@atlaskit/editor-core": "^226.
|
|
69
|
+
"@atlaskit/editor-core": "^226.5.0",
|
|
70
70
|
"@testing-library/react": "^16.3.0",
|
|
71
71
|
"react": "^19.2.0",
|
|
72
72
|
"react-dom": "^19.2.0",
|