@atlaskit/editor-plugin-extension 10.1.5 → 10.1.7
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 +16 -0
- package/dist/cjs/pm-plugins/toolbar.js +18 -10
- package/dist/cjs/pm-plugins/utils.js +184 -23
- package/dist/cjs/ui/ConfigPanel/ConfigPanel.js +37 -26
- package/dist/cjs/ui/ConfigPanel/NestedForms/RemovableField.js +7 -4
- package/dist/es2019/pm-plugins/toolbar.js +17 -9
- package/dist/es2019/pm-plugins/utils.js +89 -5
- package/dist/es2019/ui/ConfigPanel/ConfigPanel.js +37 -26
- package/dist/es2019/ui/ConfigPanel/NestedForms/RemovableField.js +7 -4
- package/dist/esm/pm-plugins/toolbar.js +18 -10
- package/dist/esm/pm-plugins/utils.js +183 -23
- package/dist/esm/ui/ConfigPanel/ConfigPanel.js +37 -26
- package/dist/esm/ui/ConfigPanel/NestedForms/RemovableField.js +7 -4
- package/dist/types/extensionPluginType.d.ts +5 -1
- package/dist/types/pm-plugins/toolbar.d.ts +14 -2
- package/dist/types/pm-plugins/utils.d.ts +5 -2
- package/dist/types-ts4.5/extensionPluginType.d.ts +5 -1
- package/dist/types-ts4.5/pm-plugins/toolbar.d.ts +9 -2
- package/dist/types-ts4.5/pm-plugins/utils.d.ts +7 -2
- package/package.json +5 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-extension
|
|
2
2
|
|
|
3
|
+
## 10.1.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`d2f1426fe5b85`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d2f1426fe5b85) -
|
|
8
|
+
[ux] ENGHEALTH-46817 Add feature gated a11y eslint fixes across editor packages
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
|
|
11
|
+
## 10.1.6
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [`abdf6c5320b01`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/abdf6c5320b01) -
|
|
16
|
+
[EDITOR-5370] Support Unsupported Content: handle copy content from nodes like mention
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 10.1.5
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -268,10 +268,12 @@ var calculateToolbarPosition = function calculateToolbarPosition(editorView, nex
|
|
|
268
268
|
* if the current selected extension is an unsupported content extension.
|
|
269
269
|
*/
|
|
270
270
|
var createOnClickCopyButton = exports.createOnClickCopyButton = function createOnClickCopyButton(_ref) {
|
|
271
|
-
var
|
|
271
|
+
var formatMessage = _ref.formatMessage,
|
|
272
|
+
extensionApi = _ref.extensionApi,
|
|
272
273
|
extensionProvider = _ref.extensionProvider,
|
|
273
274
|
getUnsupportedContent = _ref.getUnsupportedContent,
|
|
274
|
-
state = _ref.state
|
|
275
|
+
state = _ref.state,
|
|
276
|
+
locale = _ref.locale;
|
|
275
277
|
if (!extensionProvider) {
|
|
276
278
|
return;
|
|
277
279
|
}
|
|
@@ -298,18 +300,21 @@ var createOnClickCopyButton = exports.createOnClickCopyButton = function createO
|
|
|
298
300
|
|
|
299
301
|
// this command copies the text content of the unsupported content extension to the clipboard
|
|
300
302
|
return function (editorState) {
|
|
301
|
-
|
|
303
|
+
(0, _utils3.copyUnsupportedContentToClipboard)({
|
|
304
|
+
locale: locale,
|
|
302
305
|
unsupportedContent: adf,
|
|
303
|
-
schema: state.schema
|
|
304
|
-
|
|
305
|
-
|
|
306
|
+
schema: state.schema,
|
|
307
|
+
api: extensionApi
|
|
308
|
+
}).then(function () {
|
|
309
|
+
var _extensionApi$copyBut;
|
|
310
|
+
extensionApi === null || extensionApi === void 0 || (_extensionApi$copyBut = extensionApi.copyButton) === null || _extensionApi$copyBut === void 0 || _extensionApi$copyBut.actions.afterCopy(formatMessage(_messages.default.copiedToClipboard));
|
|
311
|
+
}).catch(function (error) {
|
|
306
312
|
(0, _utils3.onCopyFailed)({
|
|
307
313
|
error: error,
|
|
308
314
|
extensionApi: extensionApi,
|
|
309
315
|
state: editorState
|
|
310
316
|
});
|
|
311
|
-
|
|
312
|
-
}
|
|
317
|
+
});
|
|
313
318
|
return true;
|
|
314
319
|
};
|
|
315
320
|
};
|
|
@@ -320,7 +325,8 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
|
|
|
320
325
|
getUnsupportedContent = _ref2.getUnsupportedContent;
|
|
321
326
|
return function (state, intl) {
|
|
322
327
|
var _extensionApi$decorat, _extensionApi$context, _extensionApi$analyti, _extensionApi$connect;
|
|
323
|
-
var formatMessage = intl.formatMessage
|
|
328
|
+
var formatMessage = intl.formatMessage,
|
|
329
|
+
locale = intl.locale;
|
|
324
330
|
var extensionState = (0, _pluginFactory.getPluginState)(state);
|
|
325
331
|
var extensionProvider = extensionState.extensionProvider;
|
|
326
332
|
var hoverDecoration = extensionApi === null || extensionApi === void 0 || (_extensionApi$decorat = extensionApi.decorations) === null || _extensionApi$decorat === void 0 ? void 0 : _extensionApi$decorat.actions.hoverDecoration;
|
|
@@ -391,10 +397,12 @@ var getToolbarConfig = exports.getToolbarConfig = function getToolbarConfig(_ref
|
|
|
391
397
|
formatMessage: intl.formatMessage,
|
|
392
398
|
nodeType: nodeType,
|
|
393
399
|
onClick: (0, _expValEquals.expValEquals)('platform_editor_ai_edit_unsupported_content', 'isEnabled', true) ? createOnClickCopyButton({
|
|
400
|
+
formatMessage: formatMessage,
|
|
394
401
|
extensionApi: extensionApi,
|
|
395
402
|
extensionProvider: extensionProvider,
|
|
396
403
|
getUnsupportedContent: getUnsupportedContent,
|
|
397
|
-
state: state
|
|
404
|
+
state: state,
|
|
405
|
+
locale: locale
|
|
398
406
|
}) : undefined
|
|
399
407
|
}]
|
|
400
408
|
}, shouldHideCopyButton && {
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
7
|
exports.onCopyFailed = exports.getSelectedExtension = exports.getSelectedDomElement = exports.getNodeTypesReferenced = exports.getDataConsumerMark = exports.findNodePosWithLocalId = exports.findExtensionWithLocalId = exports.copyUnsupportedContentToClipboard = void 0;
|
|
8
|
+
var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
|
|
9
|
+
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
|
|
7
10
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
8
11
|
var _clipboard = require("@atlaskit/editor-common/clipboard");
|
|
9
12
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
10
13
|
var _editorJsonTransformer = require("@atlaskit/editor-json-transformer");
|
|
11
14
|
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
|
|
15
|
+
var _resource = require("@atlaskit/mention/resource");
|
|
16
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
|
|
17
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
18
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
12
19
|
var getSelectedExtension = exports.getSelectedExtension = function getSelectedExtension(state) {
|
|
13
20
|
var searchParent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
14
21
|
var _state$schema$nodes = state.schema.nodes,
|
|
@@ -75,35 +82,189 @@ var findNodePosWithLocalId = exports.findNodePosWithLocalId = function findNodeP
|
|
|
75
82
|
return nodes.length >= 1 ? nodes[0] : undefined;
|
|
76
83
|
};
|
|
77
84
|
/**
|
|
78
|
-
*
|
|
85
|
+
* Converts a ProseMirror node to its text representation.
|
|
86
|
+
* Handles text nodes with marks (links) and inline nodes (status, mention, emoji).
|
|
87
|
+
* Returns the content for this node, with a trailing separator for text blocks.
|
|
79
88
|
*/
|
|
80
|
-
var
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
if (
|
|
85
|
-
|
|
89
|
+
var convertNodeToText = function convertNodeToText(node, mentionSet, parent, locale) {
|
|
90
|
+
if (node.isInline) {
|
|
91
|
+
var schema = node.type.schema;
|
|
92
|
+
var finalText = '';
|
|
93
|
+
if (node.isText) {
|
|
94
|
+
finalText = node.text || '';
|
|
95
|
+
if (node.marks.length > 0) {
|
|
96
|
+
var _iterator = _createForOfIteratorHelper(node.marks),
|
|
97
|
+
_step;
|
|
98
|
+
try {
|
|
99
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
100
|
+
var mark = _step.value;
|
|
101
|
+
// if it's link, include the href in the text
|
|
102
|
+
if (mark.type === schema.marks.link) {
|
|
103
|
+
var href = mark.attrs.href;
|
|
104
|
+
var text = node.text || '';
|
|
105
|
+
// If the text differs from the href, include both
|
|
106
|
+
if (text && text !== href) {
|
|
107
|
+
finalText = "".concat(text, " ").concat(href);
|
|
108
|
+
} else {
|
|
109
|
+
finalText = href;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} catch (err) {
|
|
114
|
+
_iterator.e(err);
|
|
115
|
+
} finally {
|
|
116
|
+
_iterator.f();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
switch (node.type) {
|
|
121
|
+
case schema.nodes.status:
|
|
122
|
+
finalText = node.attrs.text || '';
|
|
123
|
+
break;
|
|
124
|
+
case schema.nodes.mention:
|
|
125
|
+
mentionSet.add(node.attrs.id);
|
|
126
|
+
finalText = "@".concat(node.attrs.id);
|
|
127
|
+
break;
|
|
128
|
+
case schema.nodes.emoji:
|
|
129
|
+
finalText = node.attrs.shortName || '';
|
|
130
|
+
break;
|
|
131
|
+
case schema.nodes.date:
|
|
132
|
+
var timestamp = new Date(Number(node.attrs.timestamp));
|
|
133
|
+
finalText = !isNaN(timestamp.getTime()) ? timestamp.toLocaleDateString(locale !== null && locale !== void 0 ? locale : 'en-US') : String(node.attrs.timestamp);
|
|
134
|
+
break;
|
|
135
|
+
default:
|
|
136
|
+
finalText = node.textContent;
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
86
139
|
}
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
version: 1,
|
|
90
|
-
type: 'doc',
|
|
91
|
-
content: [unsupportedContent]
|
|
92
|
-
};
|
|
140
|
+
if (parent && parent.isTextblock && node === parent.lastChild && parent.childCount > 0) {
|
|
141
|
+
finalText += '\n\n';
|
|
93
142
|
}
|
|
94
|
-
|
|
95
|
-
var pmNode = transformer.parse(unsupportedContent);
|
|
96
|
-
var text = pmNode.textBetween(0, pmNode.content.size, '\n\n');
|
|
97
|
-
(0, _clipboard.copyToClipboard)(text);
|
|
98
|
-
} catch (error) {
|
|
99
|
-
return error instanceof Error ? error : new Error('Failed to copy content');
|
|
143
|
+
return finalText;
|
|
100
144
|
}
|
|
145
|
+
return '';
|
|
101
146
|
};
|
|
102
|
-
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Resolves mention IDs to their display names and replaces them in the text.
|
|
150
|
+
* Returns the text with resolved mentions, or the original text if the provider is unavailable.
|
|
151
|
+
*/
|
|
152
|
+
var resolveMentionsInText = /*#__PURE__*/function () {
|
|
153
|
+
var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(text, mentionSet, api) {
|
|
154
|
+
var _api$mention;
|
|
155
|
+
var mentionProvider, resolvedText, _iterator2, _step2, id, mention;
|
|
156
|
+
return _regenerator.default.wrap(function _callee$(_context) {
|
|
157
|
+
while (1) switch (_context.prev = _context.next) {
|
|
158
|
+
case 0:
|
|
159
|
+
mentionProvider = api === null || api === void 0 || (_api$mention = api.mention) === null || _api$mention === void 0 || (_api$mention = _api$mention.sharedState) === null || _api$mention === void 0 || (_api$mention = _api$mention.currentState()) === null || _api$mention === void 0 ? void 0 : _api$mention.mentionProvider;
|
|
160
|
+
if (!(!mentionProvider || !(0, _resource.isResolvingMentionProvider)(mentionProvider))) {
|
|
161
|
+
_context.next = 3;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
return _context.abrupt("return", text);
|
|
165
|
+
case 3:
|
|
166
|
+
resolvedText = text;
|
|
167
|
+
_iterator2 = _createForOfIteratorHelper(mentionSet);
|
|
168
|
+
_context.prev = 5;
|
|
169
|
+
_iterator2.s();
|
|
170
|
+
case 7:
|
|
171
|
+
if ((_step2 = _iterator2.n()).done) {
|
|
172
|
+
_context.next = 15;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
id = _step2.value;
|
|
176
|
+
_context.next = 11;
|
|
177
|
+
return mentionProvider.resolveMentionName(id);
|
|
178
|
+
case 11:
|
|
179
|
+
mention = _context.sent;
|
|
180
|
+
resolvedText = resolvedText.replace("@".concat(id), "@".concat(mention.name) || '@…');
|
|
181
|
+
case 13:
|
|
182
|
+
_context.next = 7;
|
|
183
|
+
break;
|
|
184
|
+
case 15:
|
|
185
|
+
_context.next = 20;
|
|
186
|
+
break;
|
|
187
|
+
case 17:
|
|
188
|
+
_context.prev = 17;
|
|
189
|
+
_context.t0 = _context["catch"](5);
|
|
190
|
+
_iterator2.e(_context.t0);
|
|
191
|
+
case 20:
|
|
192
|
+
_context.prev = 20;
|
|
193
|
+
_iterator2.f();
|
|
194
|
+
return _context.finish(20);
|
|
195
|
+
case 23:
|
|
196
|
+
return _context.abrupt("return", resolvedText);
|
|
197
|
+
case 24:
|
|
198
|
+
case "end":
|
|
199
|
+
return _context.stop();
|
|
200
|
+
}
|
|
201
|
+
}, _callee, null, [[5, 17, 20, 23]]);
|
|
202
|
+
}));
|
|
203
|
+
return function resolveMentionsInText(_x, _x2, _x3) {
|
|
204
|
+
return _ref2.apply(this, arguments);
|
|
205
|
+
};
|
|
206
|
+
}();
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* copying ADF from the unsupported content extension as text to clipboard
|
|
210
|
+
*/
|
|
211
|
+
var copyUnsupportedContentToClipboard = exports.copyUnsupportedContentToClipboard = /*#__PURE__*/function () {
|
|
212
|
+
var _ref4 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref3) {
|
|
213
|
+
var locale, schema, unsupportedContent, api, transformer, pmNode, text, mentionSet;
|
|
214
|
+
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
215
|
+
while (1) switch (_context2.prev = _context2.next) {
|
|
216
|
+
case 0:
|
|
217
|
+
locale = _ref3.locale, schema = _ref3.schema, unsupportedContent = _ref3.unsupportedContent, api = _ref3.api;
|
|
218
|
+
_context2.prev = 1;
|
|
219
|
+
if (unsupportedContent) {
|
|
220
|
+
_context2.next = 4;
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
throw new Error('No nested content found');
|
|
224
|
+
case 4:
|
|
225
|
+
if (unsupportedContent.type !== 'doc') {
|
|
226
|
+
unsupportedContent = {
|
|
227
|
+
version: 1,
|
|
228
|
+
type: 'doc',
|
|
229
|
+
content: [unsupportedContent]
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
transformer = new _editorJsonTransformer.JSONTransformer(schema);
|
|
233
|
+
pmNode = transformer.parse(unsupportedContent);
|
|
234
|
+
text = '';
|
|
235
|
+
mentionSet = new Set();
|
|
236
|
+
pmNode.nodesBetween(0, pmNode.content.size, function (node, _pos, parent) {
|
|
237
|
+
text += convertNodeToText(node, mentionSet, parent, locale);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// Trim leading/trailing whitespace from the collected text
|
|
241
|
+
text = text.trim();
|
|
242
|
+
_context2.next = 13;
|
|
243
|
+
return resolveMentionsInText(text, mentionSet, api);
|
|
244
|
+
case 13:
|
|
245
|
+
text = _context2.sent;
|
|
246
|
+
(0, _clipboard.copyToClipboard)(text);
|
|
247
|
+
_context2.next = 20;
|
|
248
|
+
break;
|
|
249
|
+
case 17:
|
|
250
|
+
_context2.prev = 17;
|
|
251
|
+
_context2.t0 = _context2["catch"](1);
|
|
252
|
+
throw _context2.t0 instanceof Error ? _context2.t0 : new Error('Failed to copy content');
|
|
253
|
+
case 20:
|
|
254
|
+
case "end":
|
|
255
|
+
return _context2.stop();
|
|
256
|
+
}
|
|
257
|
+
}, _callee2, null, [[1, 17]]);
|
|
258
|
+
}));
|
|
259
|
+
return function copyUnsupportedContentToClipboard(_x4) {
|
|
260
|
+
return _ref4.apply(this, arguments);
|
|
261
|
+
};
|
|
262
|
+
}();
|
|
263
|
+
var onCopyFailed = exports.onCopyFailed = function onCopyFailed(_ref5) {
|
|
103
264
|
var _extensionApi$analyti;
|
|
104
|
-
var error =
|
|
105
|
-
extensionApi =
|
|
106
|
-
state =
|
|
265
|
+
var error = _ref5.error,
|
|
266
|
+
extensionApi = _ref5.extensionApi,
|
|
267
|
+
state = _ref5.state;
|
|
107
268
|
var nodeWithPos = getSelectedExtension(state, true);
|
|
108
269
|
if (!nodeWithPos) {
|
|
109
270
|
return;
|
|
@@ -16,11 +16,13 @@ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/ge
|
|
|
16
16
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
17
17
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
18
18
|
var _react = _interopRequireWildcard(require("react"));
|
|
19
|
+
var _bindEventListener = require("bind-event-listener");
|
|
19
20
|
var _isEqual2 = _interopRequireDefault(require("lodash/isEqual"));
|
|
20
21
|
var _merge = _interopRequireDefault(require("lodash/merge"));
|
|
21
22
|
var _memoizeOne = _interopRequireDefault(require("memoize-one"));
|
|
22
23
|
var _reactIntlNext = require("react-intl-next");
|
|
23
24
|
var _analyticsNext = require("@atlaskit/analytics-next");
|
|
25
|
+
var _browserApis = require("@atlaskit/browser-apis");
|
|
24
26
|
var _buttonGroup = _interopRequireDefault(require("@atlaskit/button/button-group"));
|
|
25
27
|
var _new = _interopRequireDefault(require("@atlaskit/button/new"));
|
|
26
28
|
var _analytics = require("@atlaskit/editor-common/analytics");
|
|
@@ -28,6 +30,7 @@ var _extensions = require("@atlaskit/editor-common/extensions");
|
|
|
28
30
|
var _hooks = require("@atlaskit/editor-common/hooks");
|
|
29
31
|
var _form = _interopRequireWildcard(require("@atlaskit/form"));
|
|
30
32
|
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
33
|
+
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
31
34
|
var _experiments = require("@atlaskit/tmp-editor-statsig/experiments");
|
|
32
35
|
var _constants = require("./constants");
|
|
33
36
|
var _DescriptionSummary = require("./DescriptionSummary");
|
|
@@ -354,6 +357,7 @@ var ConfigPanel = /*#__PURE__*/function (_React$Component) {
|
|
|
354
357
|
firstVisibleFieldName: props.fields ? _this.getFirstVisibleFieldName(props.fields) : undefined
|
|
355
358
|
};
|
|
356
359
|
_this.onFieldChange = null;
|
|
360
|
+
_this.unbindKeyDownHandler = null;
|
|
357
361
|
return _this;
|
|
358
362
|
}
|
|
359
363
|
(0, _inherits2.default)(ConfigPanel, _React$Component);
|
|
@@ -364,15 +368,26 @@ var ConfigPanel = /*#__PURE__*/function (_React$Component) {
|
|
|
364
368
|
fields = _this$props3.fields,
|
|
365
369
|
parameters = _this$props3.parameters;
|
|
366
370
|
this.parseParameters(fields, parameters);
|
|
371
|
+
if ((0, _expValEquals.expValEquals)('platform_editor_a11y_eslint_fix', 'isEnabled', true)) {
|
|
372
|
+
var doc = (0, _browserApis.getDocument)();
|
|
373
|
+
if (doc) {
|
|
374
|
+
this.unbindKeyDownHandler = (0, _bindEventListener.bind)(doc, {
|
|
375
|
+
type: 'keydown',
|
|
376
|
+
listener: this.handleKeyDown
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
}
|
|
367
380
|
}
|
|
368
381
|
}, {
|
|
369
382
|
key: "componentWillUnmount",
|
|
370
383
|
value: function componentWillUnmount() {
|
|
384
|
+
var _this$unbindKeyDownHa;
|
|
371
385
|
var _this$props4 = this.props,
|
|
372
386
|
createAnalyticsEvent = _this$props4.createAnalyticsEvent,
|
|
373
387
|
extensionManifest = _this$props4.extensionManifest,
|
|
374
388
|
fields = _this$props4.fields;
|
|
375
389
|
var currentParameters = this.state.currentParameters;
|
|
390
|
+
(_this$unbindKeyDownHa = this.unbindKeyDownHandler) === null || _this$unbindKeyDownHa === void 0 || _this$unbindKeyDownHa.call(this);
|
|
376
391
|
(0, _analytics.fireAnalyticsEvent)(createAnalyticsEvent)({
|
|
377
392
|
payload: {
|
|
378
393
|
action: _analytics.ACTION.CLOSED,
|
|
@@ -456,32 +471,28 @@ var ConfigPanel = /*#__PURE__*/function (_React$Component) {
|
|
|
456
471
|
handleSubmit: handleSubmit
|
|
457
472
|
}, function (onFieldChange) {
|
|
458
473
|
_this2.onFieldChange = onFieldChange;
|
|
459
|
-
return (
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
featureFlags: featureFlags,
|
|
482
|
-
disableFields: _this2.props.disableFields
|
|
483
|
-
}))
|
|
484
|
-
);
|
|
474
|
+
return /*#__PURE__*/_react.default.createElement("form", (0, _extends2.default)({}, formProps, {
|
|
475
|
+
noValidate: true,
|
|
476
|
+
onKeyDown: (0, _expValEquals.expValEquals)('platform_editor_a11y_eslint_fix', 'isEnabled', true) ? undefined : handleKeyDown,
|
|
477
|
+
"data-testid": "extension-config-panel"
|
|
478
|
+
}), _this2.renderHeader(extensionManifest), (0, _platformFeatureFlags.fg)('platform_editor_ai_object_sidebar_injection') && /*#__PURE__*/_react.default.createElement(_DescriptionSummary.DescriptionSummary, {
|
|
479
|
+
extensionManifest: extensionManifest
|
|
480
|
+
}), /*#__PURE__*/_react.default.createElement(ConfigFormIntlWithBoundary, {
|
|
481
|
+
api: api,
|
|
482
|
+
canSave: false,
|
|
483
|
+
errorMessage: errorMessage,
|
|
484
|
+
extensionManifest: extensionManifest,
|
|
485
|
+
fields: fields !== null && fields !== void 0 ? fields : [],
|
|
486
|
+
firstVisibleFieldName: firstVisibleFieldName,
|
|
487
|
+
hasParsedParameters: hasParsedParameters,
|
|
488
|
+
isLoading: isLoading || false,
|
|
489
|
+
onCancel: onCancel,
|
|
490
|
+
onFieldChange: onFieldChange,
|
|
491
|
+
parameters: currentParameters,
|
|
492
|
+
submitting: submitting,
|
|
493
|
+
featureFlags: featureFlags,
|
|
494
|
+
disableFields: _this2.props.disableFields
|
|
495
|
+
}));
|
|
485
496
|
});
|
|
486
497
|
});
|
|
487
498
|
}
|
|
@@ -11,6 +11,7 @@ var _reactIntlNext = require("react-intl-next");
|
|
|
11
11
|
var _extensions = require("@atlaskit/editor-common/extensions");
|
|
12
12
|
var _crossCircle = _interopRequireDefault(require("@atlaskit/icon/core/cross-circle"));
|
|
13
13
|
var _colors = require("@atlaskit/theme/colors");
|
|
14
|
+
var _expValEquals = require("@atlaskit/tmp-editor-statsig/exp-val-equals");
|
|
14
15
|
var _tooltip = _interopRequireDefault(require("@atlaskit/tooltip"));
|
|
15
16
|
/**
|
|
16
17
|
* @jsxRuntime classic
|
|
@@ -53,12 +54,14 @@ var RemovableField = function RemovableField(_ref) {
|
|
|
53
54
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop -- Ignored via go/DSP-18766
|
|
54
55
|
,
|
|
55
56
|
className: className
|
|
56
|
-
}, children, canRemoveField &&
|
|
57
|
-
|
|
58
|
-
(0, _react2.jsx)("div", {
|
|
57
|
+
}, children, canRemoveField && (0, _react2.jsx)("div", {
|
|
58
|
+
role: (0, _expValEquals.expValEquals)('platform_editor_a11y_eslint_fix', 'isEnabled', true) ? 'button' : undefined,
|
|
59
59
|
css: removeButtonWrapperStyles,
|
|
60
60
|
"data-testid": "remove-field-".concat(name),
|
|
61
|
-
onClick: onClickCallback
|
|
61
|
+
onClick: onClickCallback,
|
|
62
|
+
onKeyDown: (0, _expValEquals.expValEquals)('platform_editor_a11y_eslint_fix', 'isEnabled', true) ? onClickCallback : undefined,
|
|
63
|
+
onFocus: (0, _expValEquals.expValEquals)('platform_editor_a11y_eslint_fix', 'isEnabled', true) ? onClickCallback : undefined,
|
|
64
|
+
tabIndex: (0, _expValEquals.expValEquals)('platform_editor_a11y_eslint_fix', 'isEnabled', true) ? 0 : undefined
|
|
62
65
|
}, (0, _react2.jsx)(_tooltip.default, {
|
|
63
66
|
content: intl.formatMessage(_extensions.configPanelMessages.removeField),
|
|
64
67
|
position: "left"
|
|
@@ -266,10 +266,12 @@ const calculateToolbarPosition = (editorView, nextPos, state, extensionNode) =>
|
|
|
266
266
|
* if the current selected extension is an unsupported content extension.
|
|
267
267
|
*/
|
|
268
268
|
export const createOnClickCopyButton = ({
|
|
269
|
+
formatMessage,
|
|
269
270
|
extensionApi,
|
|
270
271
|
extensionProvider,
|
|
271
272
|
getUnsupportedContent,
|
|
272
|
-
state
|
|
273
|
+
state,
|
|
274
|
+
locale
|
|
273
275
|
}) => {
|
|
274
276
|
if (!extensionProvider) {
|
|
275
277
|
return;
|
|
@@ -300,18 +302,21 @@ export const createOnClickCopyButton = ({
|
|
|
300
302
|
|
|
301
303
|
// this command copies the text content of the unsupported content extension to the clipboard
|
|
302
304
|
return editorState => {
|
|
303
|
-
|
|
305
|
+
copyUnsupportedContentToClipboard({
|
|
306
|
+
locale,
|
|
304
307
|
unsupportedContent: adf,
|
|
305
|
-
schema: state.schema
|
|
306
|
-
|
|
307
|
-
|
|
308
|
+
schema: state.schema,
|
|
309
|
+
api: extensionApi
|
|
310
|
+
}).then(() => {
|
|
311
|
+
var _extensionApi$copyBut;
|
|
312
|
+
extensionApi === null || extensionApi === void 0 ? void 0 : (_extensionApi$copyBut = extensionApi.copyButton) === null || _extensionApi$copyBut === void 0 ? void 0 : _extensionApi$copyBut.actions.afterCopy(formatMessage(commonMessages.copiedToClipboard));
|
|
313
|
+
}).catch(error => {
|
|
308
314
|
onCopyFailed({
|
|
309
315
|
error,
|
|
310
316
|
extensionApi,
|
|
311
317
|
state: editorState
|
|
312
318
|
});
|
|
313
|
-
|
|
314
|
-
}
|
|
319
|
+
});
|
|
315
320
|
return true;
|
|
316
321
|
};
|
|
317
322
|
};
|
|
@@ -322,7 +327,8 @@ export const getToolbarConfig = ({
|
|
|
322
327
|
}) => (state, intl) => {
|
|
323
328
|
var _extensionApi$decorat, _extensionApi$context, _extensionApi$analyti, _extensionApi$connect, _extensionApi$connect2, _extensionApi$connect3;
|
|
324
329
|
const {
|
|
325
|
-
formatMessage
|
|
330
|
+
formatMessage,
|
|
331
|
+
locale
|
|
326
332
|
} = intl;
|
|
327
333
|
const extensionState = getPluginState(state);
|
|
328
334
|
const {
|
|
@@ -387,10 +393,12 @@ export const getToolbarConfig = ({
|
|
|
387
393
|
formatMessage: intl.formatMessage,
|
|
388
394
|
nodeType,
|
|
389
395
|
onClick: expValEquals('platform_editor_ai_edit_unsupported_content', 'isEnabled', true) ? createOnClickCopyButton({
|
|
396
|
+
formatMessage,
|
|
390
397
|
extensionApi,
|
|
391
398
|
extensionProvider,
|
|
392
399
|
getUnsupportedContent,
|
|
393
|
-
state
|
|
400
|
+
state,
|
|
401
|
+
locale
|
|
394
402
|
}) : undefined
|
|
395
403
|
}],
|
|
396
404
|
...(shouldHideCopyButton && {
|
|
@@ -3,6 +3,7 @@ import { copyToClipboard } from '@atlaskit/editor-common/clipboard';
|
|
|
3
3
|
import { closestElement, findNodePosByLocalIds } from '@atlaskit/editor-common/utils';
|
|
4
4
|
import { JSONTransformer } from '@atlaskit/editor-json-transformer';
|
|
5
5
|
import { findDomRefAtPos, findParentNodeOfType, findSelectedNodeOfType } from '@atlaskit/editor-prosemirror/utils';
|
|
6
|
+
import { isResolvingMentionProvider } from '@atlaskit/mention/resource';
|
|
6
7
|
export const getSelectedExtension = (state, searchParent = false) => {
|
|
7
8
|
const {
|
|
8
9
|
inlineExtension,
|
|
@@ -66,16 +67,91 @@ export const findNodePosWithLocalId = (state, localId) => {
|
|
|
66
67
|
const nodes = findNodePosByLocalIds(state, [localId]);
|
|
67
68
|
return nodes.length >= 1 ? nodes[0] : undefined;
|
|
68
69
|
};
|
|
70
|
+
/**
|
|
71
|
+
* Converts a ProseMirror node to its text representation.
|
|
72
|
+
* Handles text nodes with marks (links) and inline nodes (status, mention, emoji).
|
|
73
|
+
* Returns the content for this node, with a trailing separator for text blocks.
|
|
74
|
+
*/
|
|
75
|
+
const convertNodeToText = (node, mentionSet, parent, locale) => {
|
|
76
|
+
if (node.isInline) {
|
|
77
|
+
const schema = node.type.schema;
|
|
78
|
+
let finalText = '';
|
|
79
|
+
if (node.isText) {
|
|
80
|
+
finalText = node.text || '';
|
|
81
|
+
if (node.marks.length > 0) {
|
|
82
|
+
for (const mark of node.marks) {
|
|
83
|
+
// if it's link, include the href in the text
|
|
84
|
+
if (mark.type === schema.marks.link) {
|
|
85
|
+
const href = mark.attrs.href;
|
|
86
|
+
const text = node.text || '';
|
|
87
|
+
// If the text differs from the href, include both
|
|
88
|
+
if (text && text !== href) {
|
|
89
|
+
finalText = `${text} ${href}`;
|
|
90
|
+
} else {
|
|
91
|
+
finalText = href;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
switch (node.type) {
|
|
98
|
+
case schema.nodes.status:
|
|
99
|
+
finalText = node.attrs.text || '';
|
|
100
|
+
break;
|
|
101
|
+
case schema.nodes.mention:
|
|
102
|
+
mentionSet.add(node.attrs.id);
|
|
103
|
+
finalText = `@${node.attrs.id}`;
|
|
104
|
+
break;
|
|
105
|
+
case schema.nodes.emoji:
|
|
106
|
+
finalText = node.attrs.shortName || '';
|
|
107
|
+
break;
|
|
108
|
+
case schema.nodes.date:
|
|
109
|
+
const timestamp = new Date(Number(node.attrs.timestamp));
|
|
110
|
+
finalText = !isNaN(timestamp.getTime()) ? timestamp.toLocaleDateString(locale !== null && locale !== void 0 ? locale : 'en-US') : String(node.attrs.timestamp);
|
|
111
|
+
break;
|
|
112
|
+
default:
|
|
113
|
+
finalText = node.textContent;
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
if (parent && parent.isTextblock && node === parent.lastChild && parent.childCount > 0) {
|
|
118
|
+
finalText += '\n\n';
|
|
119
|
+
}
|
|
120
|
+
return finalText;
|
|
121
|
+
}
|
|
122
|
+
return '';
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Resolves mention IDs to their display names and replaces them in the text.
|
|
127
|
+
* Returns the text with resolved mentions, or the original text if the provider is unavailable.
|
|
128
|
+
*/
|
|
129
|
+
const resolveMentionsInText = async (text, mentionSet, api) => {
|
|
130
|
+
var _api$mention, _api$mention$sharedSt, _api$mention$sharedSt2;
|
|
131
|
+
const mentionProvider = api === null || api === void 0 ? void 0 : (_api$mention = api.mention) === null || _api$mention === void 0 ? void 0 : (_api$mention$sharedSt = _api$mention.sharedState) === null || _api$mention$sharedSt === void 0 ? void 0 : (_api$mention$sharedSt2 = _api$mention$sharedSt.currentState()) === null || _api$mention$sharedSt2 === void 0 ? void 0 : _api$mention$sharedSt2.mentionProvider;
|
|
132
|
+
if (!mentionProvider || !isResolvingMentionProvider(mentionProvider)) {
|
|
133
|
+
return text;
|
|
134
|
+
}
|
|
135
|
+
let resolvedText = text;
|
|
136
|
+
for (const id of mentionSet) {
|
|
137
|
+
const mention = await mentionProvider.resolveMentionName(id);
|
|
138
|
+
resolvedText = resolvedText.replace(`@${id}`, `@${mention.name}` || '@…');
|
|
139
|
+
}
|
|
140
|
+
return resolvedText;
|
|
141
|
+
};
|
|
142
|
+
|
|
69
143
|
/**
|
|
70
144
|
* copying ADF from the unsupported content extension as text to clipboard
|
|
71
145
|
*/
|
|
72
|
-
export const copyUnsupportedContentToClipboard = ({
|
|
146
|
+
export const copyUnsupportedContentToClipboard = async ({
|
|
147
|
+
locale,
|
|
73
148
|
schema,
|
|
74
|
-
unsupportedContent
|
|
149
|
+
unsupportedContent,
|
|
150
|
+
api
|
|
75
151
|
}) => {
|
|
76
152
|
try {
|
|
77
153
|
if (!unsupportedContent) {
|
|
78
|
-
|
|
154
|
+
throw new Error('No nested content found');
|
|
79
155
|
}
|
|
80
156
|
if (unsupportedContent.type !== 'doc') {
|
|
81
157
|
unsupportedContent = {
|
|
@@ -86,10 +162,18 @@ export const copyUnsupportedContentToClipboard = ({
|
|
|
86
162
|
}
|
|
87
163
|
const transformer = new JSONTransformer(schema);
|
|
88
164
|
const pmNode = transformer.parse(unsupportedContent);
|
|
89
|
-
|
|
165
|
+
let text = '';
|
|
166
|
+
const mentionSet = new Set();
|
|
167
|
+
pmNode.nodesBetween(0, pmNode.content.size, (node, _pos, parent) => {
|
|
168
|
+
text += convertNodeToText(node, mentionSet, parent, locale);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Trim leading/trailing whitespace from the collected text
|
|
172
|
+
text = text.trim();
|
|
173
|
+
text = await resolveMentionsInText(text, mentionSet, api);
|
|
90
174
|
copyToClipboard(text);
|
|
91
175
|
} catch (error) {
|
|
92
|
-
|
|
176
|
+
throw error instanceof Error ? error : new Error('Failed to copy content');
|
|
93
177
|
}
|
|
94
178
|
};
|
|
95
179
|
export const onCopyFailed = ({
|