@atlaskit/editor-plugin-insert-block 8.4.4 → 8.5.0
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 +19 -0
- package/dist/cjs/insertBlockPlugin.js +17 -0
- package/dist/cjs/pm-plugins/experiences/toolbar-action-experiences.js +183 -0
- package/dist/cjs/pm-plugins/experiences/toolbar-experience-utils.js +409 -0
- package/dist/cjs/ui/ElementBrowser/InsertMenu.js +18 -5
- package/dist/cjs/ui/toolbar-components/EmojiButton.js +3 -1
- package/dist/cjs/ui/toolbar-components/ImageButton.js +2 -1
- package/dist/cjs/ui/toolbar-components/InsertButton.js +2 -1
- package/dist/cjs/ui/toolbar-components/LayoutButton.js +2 -1
- package/dist/cjs/ui/toolbar-components/MediaButton.js +3 -1
- package/dist/cjs/ui/toolbar-components/MentionButton.js +3 -1
- package/dist/cjs/ui/toolbar-components/TableButton.js +1 -1
- package/dist/cjs/ui/toolbar-components/TableSizePicker.js +3 -1
- package/dist/cjs/ui/toolbar-components/TaskListButton.js +2 -1
- package/dist/es2019/insertBlockPlugin.js +15 -0
- package/dist/es2019/pm-plugins/experiences/toolbar-action-experiences.js +173 -0
- package/dist/es2019/pm-plugins/experiences/toolbar-experience-utils.js +279 -0
- package/dist/es2019/ui/ElementBrowser/InsertMenu.js +15 -4
- package/dist/es2019/ui/toolbar-components/EmojiButton.js +3 -1
- package/dist/es2019/ui/toolbar-components/ImageButton.js +3 -2
- package/dist/es2019/ui/toolbar-components/InsertButton.js +3 -2
- package/dist/es2019/ui/toolbar-components/LayoutButton.js +3 -2
- package/dist/es2019/ui/toolbar-components/MediaButton.js +3 -1
- package/dist/es2019/ui/toolbar-components/MentionButton.js +3 -1
- package/dist/es2019/ui/toolbar-components/TableButton.js +2 -2
- package/dist/es2019/ui/toolbar-components/TableSizePicker.js +3 -1
- package/dist/es2019/ui/toolbar-components/TaskListButton.js +3 -2
- package/dist/esm/insertBlockPlugin.js +17 -0
- package/dist/esm/pm-plugins/experiences/toolbar-action-experiences.js +177 -0
- package/dist/esm/pm-plugins/experiences/toolbar-experience-utils.js +403 -0
- package/dist/esm/ui/ElementBrowser/InsertMenu.js +17 -4
- package/dist/esm/ui/toolbar-components/EmojiButton.js +3 -1
- package/dist/esm/ui/toolbar-components/ImageButton.js +3 -2
- package/dist/esm/ui/toolbar-components/InsertButton.js +3 -2
- package/dist/esm/ui/toolbar-components/LayoutButton.js +3 -2
- package/dist/esm/ui/toolbar-components/MediaButton.js +3 -1
- package/dist/esm/ui/toolbar-components/MentionButton.js +3 -1
- package/dist/esm/ui/toolbar-components/TableButton.js +2 -2
- package/dist/esm/ui/toolbar-components/TableSizePicker.js +3 -1
- package/dist/esm/ui/toolbar-components/TaskListButton.js +3 -2
- package/dist/types/pm-plugins/experiences/toolbar-action-experiences.d.ts +10 -0
- package/dist/types/pm-plugins/experiences/toolbar-experience-utils.d.ts +57 -0
- package/dist/types/ui/ElementBrowser/InsertMenu.d.ts +5 -2
- package/dist/types-ts4.5/pm-plugins/experiences/toolbar-action-experiences.d.ts +10 -0
- package/dist/types-ts4.5/pm-plugins/experiences/toolbar-experience-utils.d.ts +57 -0
- package/dist/types-ts4.5/ui/ElementBrowser/InsertMenu.d.ts +5 -2
- package/package.json +6 -2
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
|
|
2
|
+
import _createClass from "@babel/runtime/helpers/createClass";
|
|
3
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
4
|
+
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; } } }; }
|
|
5
|
+
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; } }
|
|
6
|
+
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; }
|
|
7
|
+
import { getDocument } from '@atlaskit/browser-apis';
|
|
8
|
+
import { EXPERIENCE_FAILURE_REASON, popupWithNestedElement } from '@atlaskit/editor-common/experiences';
|
|
9
|
+
/**
|
|
10
|
+
* DOM marker selectors for node types inserted via toolbar actions.
|
|
11
|
+
* Matches outermost wrapper elements set synchronously by ReactNodeView
|
|
12
|
+
* (`{nodeTypeName}View-content-wrap`) or schema `toDOM` attributes.
|
|
13
|
+
*/
|
|
14
|
+
export var NODE_INSERT_MARKERS = {
|
|
15
|
+
TABLE: '.tableView-content-wrap',
|
|
16
|
+
LAYOUT: '.layoutSectionView-content-wrap',
|
|
17
|
+
LAYOUT_COLUMN: '.layoutColumnView-content-wrap',
|
|
18
|
+
TASK_LIST: '[data-node-type="actionList"]',
|
|
19
|
+
TASK_ITEM: '.taskItemView-content-wrap'
|
|
20
|
+
};
|
|
21
|
+
var COMBINED_NODE_INSERT_SELECTOR = [NODE_INSERT_MARKERS.TABLE, NODE_INSERT_MARKERS.LAYOUT, NODE_INSERT_MARKERS.LAYOUT_COLUMN, NODE_INSERT_MARKERS.TASK_LIST, NODE_INSERT_MARKERS.TASK_ITEM].join(', ');
|
|
22
|
+
export var isToolbarButtonClick = function isToolbarButtonClick(target, testId) {
|
|
23
|
+
var button = target.closest("button[data-testid=\"".concat(testId, "\"]"));
|
|
24
|
+
if (!button) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return !button.disabled && button.getAttribute('aria-disabled') !== 'true';
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* ExperienceCheck that observes popup mount point and all its
|
|
32
|
+
* `[data-editor-popup]` children with `{ childList: true }` (no subtree).
|
|
33
|
+
*
|
|
34
|
+
* Detects when a popup containing the given nested element is added to the
|
|
35
|
+
* DOM — either as a new `[data-editor-popup]` direct child, or as content
|
|
36
|
+
* rendered inside an existing `[data-editor-popup]` wrapper.
|
|
37
|
+
*/
|
|
38
|
+
export var TYPEAHEAD_DECORATION_SELECTOR = '[data-type-ahead="typeaheadDecoration"]';
|
|
39
|
+
export var handleTypeAheadOpenDomMutation = function handleTypeAheadOpenDomMutation(_ref) {
|
|
40
|
+
var mutations = _ref.mutations;
|
|
41
|
+
var _iterator = _createForOfIteratorHelper(mutations),
|
|
42
|
+
_step;
|
|
43
|
+
try {
|
|
44
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
45
|
+
var mutation = _step.value;
|
|
46
|
+
if (mutation.type !== 'childList') {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
var _iterator2 = _createForOfIteratorHelper(mutation.addedNodes),
|
|
50
|
+
_step2;
|
|
51
|
+
try {
|
|
52
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
53
|
+
var node = _step2.value;
|
|
54
|
+
if (!(node instanceof HTMLElement)) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (node.matches(TYPEAHEAD_DECORATION_SELECTOR) || node.querySelector(TYPEAHEAD_DECORATION_SELECTOR)) {
|
|
58
|
+
return {
|
|
59
|
+
status: 'success'
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
} catch (err) {
|
|
64
|
+
_iterator2.e(err);
|
|
65
|
+
} finally {
|
|
66
|
+
_iterator2.f();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} catch (err) {
|
|
70
|
+
_iterator.e(err);
|
|
71
|
+
} finally {
|
|
72
|
+
_iterator.f();
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
};
|
|
76
|
+
export var ExperienceCheckPopupMutation = /*#__PURE__*/function () {
|
|
77
|
+
function ExperienceCheckPopupMutation(nestedElementQuery, getTarget, getEditorDom) {
|
|
78
|
+
_classCallCheck(this, ExperienceCheckPopupMutation);
|
|
79
|
+
_defineProperty(this, "observers", []);
|
|
80
|
+
this.nestedElementQuery = nestedElementQuery;
|
|
81
|
+
this.getTarget = getTarget;
|
|
82
|
+
this.getEditorDom = getEditorDom;
|
|
83
|
+
}
|
|
84
|
+
return _createClass(ExperienceCheckPopupMutation, [{
|
|
85
|
+
key: "start",
|
|
86
|
+
value: function start(callback) {
|
|
87
|
+
var _this = this;
|
|
88
|
+
this.stop();
|
|
89
|
+
var target = this.getTarget();
|
|
90
|
+
if (!target) {
|
|
91
|
+
callback({
|
|
92
|
+
status: 'failure',
|
|
93
|
+
reason: EXPERIENCE_FAILURE_REASON.DOM_MUTATION_TARGET_NOT_FOUND
|
|
94
|
+
});
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
var doc = getDocument();
|
|
98
|
+
if (!doc) {
|
|
99
|
+
callback({
|
|
100
|
+
status: 'failure',
|
|
101
|
+
reason: EXPERIENCE_FAILURE_REASON.DOM_MUTATION_TARGET_NOT_FOUND
|
|
102
|
+
});
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
var query = this.nestedElementQuery;
|
|
106
|
+
var onMutation = function onMutation(mutations) {
|
|
107
|
+
var _iterator3 = _createForOfIteratorHelper(mutations),
|
|
108
|
+
_step3;
|
|
109
|
+
try {
|
|
110
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
111
|
+
var mutation = _step3.value;
|
|
112
|
+
if (mutation.type !== 'childList') {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
var _iterator4 = _createForOfIteratorHelper(mutation.addedNodes),
|
|
116
|
+
_step4;
|
|
117
|
+
try {
|
|
118
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
119
|
+
var node = _step4.value;
|
|
120
|
+
if (!(node instanceof HTMLElement)) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
if (popupWithNestedElement(node, query) || node.matches(query) || !!node.querySelector(query)) {
|
|
124
|
+
_this.stop();
|
|
125
|
+
callback({
|
|
126
|
+
status: 'success'
|
|
127
|
+
});
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
} catch (err) {
|
|
132
|
+
_iterator4.e(err);
|
|
133
|
+
} finally {
|
|
134
|
+
_iterator4.f();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch (err) {
|
|
138
|
+
_iterator3.e(err);
|
|
139
|
+
} finally {
|
|
140
|
+
_iterator3.f();
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
var observe = function observe(el) {
|
|
144
|
+
var observer = new MutationObserver(onMutation);
|
|
145
|
+
observer.observe(el, {
|
|
146
|
+
childList: true
|
|
147
|
+
});
|
|
148
|
+
_this.observers.push(observer);
|
|
149
|
+
};
|
|
150
|
+
observe(target);
|
|
151
|
+
var _iterator5 = _createForOfIteratorHelper(target.querySelectorAll('[data-editor-popup]')),
|
|
152
|
+
_step5;
|
|
153
|
+
try {
|
|
154
|
+
for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
|
|
155
|
+
var wrapper = _step5.value;
|
|
156
|
+
observe(wrapper);
|
|
157
|
+
}
|
|
158
|
+
} catch (err) {
|
|
159
|
+
_iterator5.e(err);
|
|
160
|
+
} finally {
|
|
161
|
+
_iterator5.f();
|
|
162
|
+
}
|
|
163
|
+
var portalContainer = doc.querySelector('.atlaskit-portal-container');
|
|
164
|
+
if (portalContainer instanceof HTMLElement) {
|
|
165
|
+
var observePortal = function observePortal(portal) {
|
|
166
|
+
observe(portal);
|
|
167
|
+
var _iterator6 = _createForOfIteratorHelper(portal.children),
|
|
168
|
+
_step6;
|
|
169
|
+
try {
|
|
170
|
+
for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
|
|
171
|
+
var child = _step6.value;
|
|
172
|
+
if (child instanceof HTMLElement) {
|
|
173
|
+
observe(child);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
} catch (err) {
|
|
177
|
+
_iterator6.e(err);
|
|
178
|
+
} finally {
|
|
179
|
+
_iterator6.f();
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
var containerObserver = new MutationObserver(function (mutations) {
|
|
183
|
+
var _iterator7 = _createForOfIteratorHelper(mutations),
|
|
184
|
+
_step7;
|
|
185
|
+
try {
|
|
186
|
+
for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
|
|
187
|
+
var mutation = _step7.value;
|
|
188
|
+
if (mutation.type !== 'childList') {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
var _iterator8 = _createForOfIteratorHelper(mutation.addedNodes),
|
|
192
|
+
_step8;
|
|
193
|
+
try {
|
|
194
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
195
|
+
var node = _step8.value;
|
|
196
|
+
if (node instanceof HTMLElement) {
|
|
197
|
+
observePortal(node);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
} catch (err) {
|
|
201
|
+
_iterator8.e(err);
|
|
202
|
+
} finally {
|
|
203
|
+
_iterator8.f();
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
} catch (err) {
|
|
207
|
+
_iterator7.e(err);
|
|
208
|
+
} finally {
|
|
209
|
+
_iterator7.f();
|
|
210
|
+
}
|
|
211
|
+
onMutation(mutations);
|
|
212
|
+
});
|
|
213
|
+
containerObserver.observe(portalContainer, {
|
|
214
|
+
childList: true
|
|
215
|
+
});
|
|
216
|
+
this.observers.push(containerObserver);
|
|
217
|
+
var _iterator9 = _createForOfIteratorHelper(portalContainer.querySelectorAll('.atlaskit-portal')),
|
|
218
|
+
_step9;
|
|
219
|
+
try {
|
|
220
|
+
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
221
|
+
var portal = _step9.value;
|
|
222
|
+
observePortal(portal);
|
|
223
|
+
}
|
|
224
|
+
} catch (err) {
|
|
225
|
+
_iterator9.e(err);
|
|
226
|
+
} finally {
|
|
227
|
+
_iterator9.f();
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
var editorDom = this.getEditorDom();
|
|
231
|
+
if (editorDom !== null && editorDom !== void 0 && editorDom.parentElement) {
|
|
232
|
+
observe(editorDom.parentElement);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Two-frame DOM check to handle cases where rendering happens before
|
|
236
|
+
// observers are attached.
|
|
237
|
+
var checkDom = function checkDom() {
|
|
238
|
+
if (doc.querySelector(query)) {
|
|
239
|
+
_this.stop();
|
|
240
|
+
callback({
|
|
241
|
+
status: 'success'
|
|
242
|
+
});
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
requestAnimationFrame(function () {
|
|
246
|
+
if (doc.querySelector(query)) {
|
|
247
|
+
_this.stop();
|
|
248
|
+
callback({
|
|
249
|
+
status: 'success'
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
};
|
|
254
|
+
requestAnimationFrame(checkDom);
|
|
255
|
+
}
|
|
256
|
+
}, {
|
|
257
|
+
key: "stop",
|
|
258
|
+
value: function stop() {
|
|
259
|
+
var _iterator0 = _createForOfIteratorHelper(this.observers),
|
|
260
|
+
_step0;
|
|
261
|
+
try {
|
|
262
|
+
for (_iterator0.s(); !(_step0 = _iterator0.n()).done;) {
|
|
263
|
+
var observer = _step0.value;
|
|
264
|
+
observer.disconnect();
|
|
265
|
+
}
|
|
266
|
+
} catch (err) {
|
|
267
|
+
_iterator0.e(err);
|
|
268
|
+
} finally {
|
|
269
|
+
_iterator0.f();
|
|
270
|
+
}
|
|
271
|
+
this.observers = [];
|
|
272
|
+
}
|
|
273
|
+
}]);
|
|
274
|
+
}();
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Returns the narrow parent DOM element at the current selection, suitable
|
|
278
|
+
* for observing with `{ childList: true }` (no subtree).
|
|
279
|
+
*
|
|
280
|
+
* Uses the resolved position's depth to find the block node at the cursor
|
|
281
|
+
* via `nodeDOM`, then returns its `parentElement` — the container whose
|
|
282
|
+
* direct children change when content is inserted at this position.
|
|
283
|
+
*
|
|
284
|
+
* Falls back to `domAtPos` if `nodeDOM` is unavailable.
|
|
285
|
+
*/
|
|
286
|
+
export var getParentDOMAtSelection = function getParentDOMAtSelection(editorView) {
|
|
287
|
+
if (!editorView) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
290
|
+
try {
|
|
291
|
+
var selection = editorView.state.selection;
|
|
292
|
+
var $from = selection.$from;
|
|
293
|
+
var parentDepth = Math.max(1, $from.depth);
|
|
294
|
+
var parentPos = $from.before(parentDepth);
|
|
295
|
+
var parentDom = editorView.nodeDOM(parentPos);
|
|
296
|
+
if (parentDom instanceof HTMLElement && parentDom.parentElement) {
|
|
297
|
+
return parentDom.parentElement;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// Fallback: use domAtPos
|
|
301
|
+
var _editorView$domAtPos = editorView.domAtPos(selection.from),
|
|
302
|
+
node = _editorView$domAtPos.node;
|
|
303
|
+
var element = null;
|
|
304
|
+
if (node instanceof HTMLElement) {
|
|
305
|
+
element = node;
|
|
306
|
+
} else if (node instanceof Text) {
|
|
307
|
+
element = node.parentElement;
|
|
308
|
+
}
|
|
309
|
+
if (!element) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
var proseMirrorRoot = editorView.dom;
|
|
313
|
+
if (!(proseMirrorRoot instanceof HTMLElement)) {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
if (element === proseMirrorRoot) {
|
|
317
|
+
return proseMirrorRoot;
|
|
318
|
+
}
|
|
319
|
+
if (element.parentElement && proseMirrorRoot.contains(element.parentElement)) {
|
|
320
|
+
return element.parentElement;
|
|
321
|
+
}
|
|
322
|
+
return proseMirrorRoot;
|
|
323
|
+
} catch (_unused) {
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Checks whether a DOM node matches any known node insert marker,
|
|
330
|
+
* either directly or via a nested element (e.g. breakout mark wrapper).
|
|
331
|
+
*/
|
|
332
|
+
var matchesNodeInsertMarker = function matchesNodeInsertMarker(node) {
|
|
333
|
+
if (!(node instanceof HTMLElement)) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
return node.matches(COMBINED_NODE_INSERT_SELECTOR) || !!node.querySelector(COMBINED_NODE_INSERT_SELECTOR);
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Evaluates DOM mutations to detect a node insert action.
|
|
341
|
+
*
|
|
342
|
+
* Uses two strategies:
|
|
343
|
+
* 1. Marker-based: checks `addedNodes` against known node insert selectors.
|
|
344
|
+
* 2. Structure-based: detects element add+remove (block-level replacement).
|
|
345
|
+
*/
|
|
346
|
+
export var handleEditorNodeInsertDomMutation = function handleEditorNodeInsertDomMutation(_ref2) {
|
|
347
|
+
var mutations = _ref2.mutations;
|
|
348
|
+
var hasAddedElement = false;
|
|
349
|
+
var hasRemovedElement = false;
|
|
350
|
+
var _iterator1 = _createForOfIteratorHelper(mutations),
|
|
351
|
+
_step1;
|
|
352
|
+
try {
|
|
353
|
+
for (_iterator1.s(); !(_step1 = _iterator1.n()).done;) {
|
|
354
|
+
var mutation = _step1.value;
|
|
355
|
+
if (mutation.type !== 'childList') {
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
var _iterator10 = _createForOfIteratorHelper(mutation.addedNodes),
|
|
359
|
+
_step10;
|
|
360
|
+
try {
|
|
361
|
+
for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
|
|
362
|
+
var node = _step10.value;
|
|
363
|
+
if (matchesNodeInsertMarker(node)) {
|
|
364
|
+
return {
|
|
365
|
+
status: 'success'
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
if (node instanceof HTMLElement) {
|
|
369
|
+
hasAddedElement = true;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
} catch (err) {
|
|
373
|
+
_iterator10.e(err);
|
|
374
|
+
} finally {
|
|
375
|
+
_iterator10.f();
|
|
376
|
+
}
|
|
377
|
+
var _iterator11 = _createForOfIteratorHelper(mutation.removedNodes),
|
|
378
|
+
_step11;
|
|
379
|
+
try {
|
|
380
|
+
for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
|
|
381
|
+
var _node = _step11.value;
|
|
382
|
+
if (_node instanceof HTMLElement) {
|
|
383
|
+
hasRemovedElement = true;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
} catch (err) {
|
|
387
|
+
_iterator11.e(err);
|
|
388
|
+
} finally {
|
|
389
|
+
_iterator11.f();
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
} catch (err) {
|
|
393
|
+
_iterator1.e(err);
|
|
394
|
+
} finally {
|
|
395
|
+
_iterator1.f();
|
|
396
|
+
}
|
|
397
|
+
if (hasAddedElement && hasRemovedElement) {
|
|
398
|
+
return {
|
|
399
|
+
status: 'success'
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
return undefined;
|
|
403
|
+
};
|
|
@@ -24,15 +24,28 @@ import { messages, IconCode, IconDate, IconDecision, IconDivider, IconExpand, Ic
|
|
|
24
24
|
import { OutsideClickTargetRefContext, withReactEditorViewOuterListeners as withOuterListeners } from '@atlaskit/editor-common/ui-react';
|
|
25
25
|
import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
26
26
|
import { N0, N30A, N60A } from '@atlaskit/theme/colors';
|
|
27
|
+
import { expVal } from '@atlaskit/tmp-editor-statsig/expVal';
|
|
27
28
|
export var DEFAULT_HEIGHT = 560;
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
|
-
* Exported helper to allow testing of InsertMenu
|
|
31
|
+
* Exported helper to allow testing of InsertMenu pinning logic. NOTE: this is
|
|
31
32
|
*not* the ideal way to approach this, quickinsert plugin provides a `getSuggestions`
|
|
32
33
|
method that can be used to get suggestions -> once all experiments are cleaned up,
|
|
33
34
|
they should be unified through `pluginInjectionApi?.quickInsert?.actions.getSuggestions`
|
|
35
|
+
|
|
36
|
+
`cc_fd_db_top_editor_toolbar` experiment adds new logic to sort elements by `priority`
|
|
37
|
+
this newer implementation matches how the "quick insert menu" sorts elements
|
|
34
38
|
*/
|
|
35
|
-
export var
|
|
39
|
+
export var sortPrioritizedElements = function sortPrioritizedElements(featuredItems, formatMessage) {
|
|
40
|
+
if (['new-description', 'orig-description'].includes(expVal('cc_fd_db_top_editor_toolbar', 'cohort', 'control'))) {
|
|
41
|
+
// Sort by priority (lower first) on the concatenated list so items
|
|
42
|
+
// with "priority" are at the top (e.g. Whiteboard before Database)
|
|
43
|
+
return featuredItems.slice(0).sort(function (a, b) {
|
|
44
|
+
return (a.priority || Number.POSITIVE_INFINITY) - (b.priority || Number.POSITIVE_INFINITY);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// old logic sort whiteboards to top
|
|
36
49
|
var DIAGRAM_KEY = 'whiteboard-extension:create-diagram';
|
|
37
50
|
var isDiagram = function isDiagram(item) {
|
|
38
51
|
return item.key === DIAGRAM_KEY;
|
|
@@ -167,8 +180,8 @@ var InsertMenu = function InsertMenu(_ref) {
|
|
|
167
180
|
}) : item;
|
|
168
181
|
})) !== null && _pluginInjectionApi$q4 !== void 0 ? _pluginInjectionApi$q4 : [];
|
|
169
182
|
var unfilteredResult = quickInsertDropdownItems.concat(featuredQuickInsertSuggestions);
|
|
170
|
-
// need to
|
|
171
|
-
result =
|
|
183
|
+
// need to sort on the concatenated list so desired elements are at the top
|
|
184
|
+
result = sortPrioritizedElements(unfilteredResult, formatMessage);
|
|
172
185
|
}
|
|
173
186
|
setItemCount(result.length);
|
|
174
187
|
return result;
|
|
@@ -3,6 +3,7 @@ import { useIntl } from 'react-intl-next';
|
|
|
3
3
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
4
4
|
import { ToolTipContent, insertEmoji } from '@atlaskit/editor-common/keymaps';
|
|
5
5
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
6
|
+
import { TOOLBAR_BUTTON_TEST_ID } from '@atlaskit/editor-common/toolbar';
|
|
6
7
|
import { ToolbarButton, ToolbarTooltip, EmojiIcon, useToolbarUI } from '@atlaskit/editor-toolbar';
|
|
7
8
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
8
9
|
import { useEmojiPickerPopup } from './hooks/useEmojiPickerPopup';
|
|
@@ -67,6 +68,7 @@ export var EmojiButton = function EmojiButton(_ref) {
|
|
|
67
68
|
return emojiPickerPopup.toggle();
|
|
68
69
|
},
|
|
69
70
|
isSelected: emojiPickerPopup.isOpen,
|
|
70
|
-
isDisabled: !isTypeAheadAllowed || !emojiProvider
|
|
71
|
+
isDisabled: !isTypeAheadAllowed || !emojiProvider,
|
|
72
|
+
testId: TOOLBAR_BUTTON_TEST_ID.EMOJI
|
|
71
73
|
})));
|
|
72
74
|
};
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { useIntl } from 'react-intl-next';
|
|
3
3
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
4
4
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
5
|
-
import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
|
|
5
|
+
import { useEditorToolbar, TOOLBAR_BUTTON_TEST_ID } from '@atlaskit/editor-common/toolbar';
|
|
6
6
|
import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
7
7
|
import { ToolbarButton, ToolbarTooltip, ImageIcon } from '@atlaskit/editor-toolbar';
|
|
8
8
|
export var ImageButton = function ImageButton(_ref) {
|
|
@@ -37,6 +37,7 @@ export var ImageButton = function ImageButton(_ref) {
|
|
|
37
37
|
size: "small"
|
|
38
38
|
}),
|
|
39
39
|
onClick: onClick,
|
|
40
|
-
isDisabled: !imageUploadEnabled || isOffline
|
|
40
|
+
isDisabled: !imageUploadEnabled || isOffline,
|
|
41
|
+
testId: TOOLBAR_BUTTON_TEST_ID.IMAGE
|
|
41
42
|
}));
|
|
42
43
|
};
|
|
@@ -4,7 +4,7 @@ import { useIntl } from 'react-intl-next';
|
|
|
4
4
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
5
5
|
import { getAriaKeyshortcuts, insertElements, ToolTipContent } from '@atlaskit/editor-common/keymaps';
|
|
6
6
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
7
|
-
import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
|
|
7
|
+
import { TOOLBAR_BUTTON_TEST_ID, useEditorToolbar } from '@atlaskit/editor-common/toolbar';
|
|
8
8
|
import { Popup } from '@atlaskit/editor-common/ui';
|
|
9
9
|
import { useSharedPluginStateSelector } from '@atlaskit/editor-common/use-shared-plugin-state-selector';
|
|
10
10
|
import { akEditorMenuZIndex } from '@atlaskit/editor-shared-styles';
|
|
@@ -241,6 +241,7 @@ export var InsertButton = function InsertButton(_ref) {
|
|
|
241
241
|
ref: insertButtonRef,
|
|
242
242
|
onClick: onClick,
|
|
243
243
|
isSelected: insertMenuOpen,
|
|
244
|
-
isDisabled: !isTypeAheadAllowed || isDisabled
|
|
244
|
+
isDisabled: !isTypeAheadAllowed || isDisabled,
|
|
245
|
+
testId: TOOLBAR_BUTTON_TEST_ID.INSERT
|
|
245
246
|
})));
|
|
246
247
|
};
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { useIntl } from 'react-intl-next';
|
|
3
3
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
5
|
-
import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
|
|
5
|
+
import { useEditorToolbar, TOOLBAR_BUTTON_TEST_ID } from '@atlaskit/editor-common/toolbar';
|
|
6
6
|
import { ToolbarButton, ToolbarTooltip, LayoutIcon } from '@atlaskit/editor-toolbar';
|
|
7
7
|
export var LayoutButton = function LayoutButton(_ref) {
|
|
8
8
|
var api = _ref.api;
|
|
@@ -28,6 +28,7 @@ export var LayoutButton = function LayoutButton(_ref) {
|
|
|
28
28
|
label: formatMessage(messages.columns),
|
|
29
29
|
size: "small"
|
|
30
30
|
}),
|
|
31
|
-
onClick: onClick
|
|
31
|
+
onClick: onClick,
|
|
32
|
+
testId: TOOLBAR_BUTTON_TEST_ID.LAYOUT
|
|
32
33
|
}));
|
|
33
34
|
};
|
|
@@ -3,6 +3,7 @@ import { useIntl } from 'react-intl-next';
|
|
|
3
3
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
5
5
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
6
|
+
import { TOOLBAR_BUTTON_TEST_ID } from '@atlaskit/editor-common/toolbar';
|
|
6
7
|
import { isOfflineMode } from '@atlaskit/editor-plugin-connectivity';
|
|
7
8
|
import { ToolbarButton, ToolbarTooltip, ImageIcon } from '@atlaskit/editor-toolbar';
|
|
8
9
|
export var MediaButton = function MediaButton(_ref) {
|
|
@@ -59,6 +60,7 @@ export var MediaButton = function MediaButton(_ref) {
|
|
|
59
60
|
}),
|
|
60
61
|
onClick: onClick,
|
|
61
62
|
ref: mediaButtonRef,
|
|
62
|
-
isDisabled: isOffline || !allowsUploads
|
|
63
|
+
isDisabled: isOffline || !allowsUploads,
|
|
64
|
+
testId: TOOLBAR_BUTTON_TEST_ID.MEDIA
|
|
63
65
|
}));
|
|
64
66
|
};
|
|
@@ -4,6 +4,7 @@ import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
|
4
4
|
import { useSharedPluginStateWithSelector } from '@atlaskit/editor-common/hooks';
|
|
5
5
|
import { ToolTipContent, insertMention } from '@atlaskit/editor-common/keymaps';
|
|
6
6
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
7
|
+
import { TOOLBAR_BUTTON_TEST_ID } from '@atlaskit/editor-common/toolbar';
|
|
7
8
|
import { ToolbarButton, ToolbarTooltip, MentionIcon } from '@atlaskit/editor-toolbar';
|
|
8
9
|
export var MentionButton = function MentionButton(_ref) {
|
|
9
10
|
var api = _ref.api;
|
|
@@ -39,6 +40,7 @@ export var MentionButton = function MentionButton(_ref) {
|
|
|
39
40
|
}),
|
|
40
41
|
onClick: onClick,
|
|
41
42
|
ariaKeyshortcuts: "Shift+2 Space",
|
|
42
|
-
isDisabled: !canInsertMention || !mentionProvider || !isTypeAheadAllowed
|
|
43
|
+
isDisabled: !canInsertMention || !mentionProvider || !isTypeAheadAllowed,
|
|
44
|
+
testId: TOOLBAR_BUTTON_TEST_ID.MENTION
|
|
43
45
|
}));
|
|
44
46
|
};
|
|
@@ -3,7 +3,7 @@ import { useIntl } from 'react-intl-next';
|
|
|
3
3
|
import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { ToolTipContent, getAriaKeyshortcuts, toggleTable } from '@atlaskit/editor-common/keymaps';
|
|
5
5
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
6
|
-
import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
|
|
6
|
+
import { useEditorToolbar, TOOLBAR_BUTTON_TEST_ID } from '@atlaskit/editor-common/toolbar';
|
|
7
7
|
import { ToolbarButton, ToolbarTooltip, TableIcon } from '@atlaskit/editor-toolbar';
|
|
8
8
|
export var TableButton = function TableButton(_ref) {
|
|
9
9
|
var api = _ref.api;
|
|
@@ -45,6 +45,6 @@ export var TableButton = function TableButton(_ref) {
|
|
|
45
45
|
}),
|
|
46
46
|
onClick: onClick,
|
|
47
47
|
ariaKeyshortcuts: getAriaKeyshortcuts(toggleTable),
|
|
48
|
-
testId:
|
|
48
|
+
testId: TOOLBAR_BUTTON_TEST_ID.TABLE
|
|
49
49
|
}));
|
|
50
50
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useRef } from 'react';
|
|
2
2
|
import { useIntl } from 'react-intl-next';
|
|
3
3
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
4
|
+
import { TOOLBAR_BUTTON_TEST_ID } from '@atlaskit/editor-common/toolbar';
|
|
4
5
|
import { MoreItemsIcon, ToolbarButton, ToolbarTooltip, useToolbarUI } from '@atlaskit/editor-toolbar';
|
|
5
6
|
import { useTableSelectorPopup } from './hooks/useTableSelectorPopup';
|
|
6
7
|
import { TableSelectorPopupWrapper } from './popups/TableSelectorPopupWrapper';
|
|
@@ -46,6 +47,7 @@ export var TableSizePicker = function TableSizePicker(_ref) {
|
|
|
46
47
|
}),
|
|
47
48
|
onClick: onClick,
|
|
48
49
|
isSelected: tableSelectorPopup.isOpen,
|
|
49
|
-
ref: tableSizePickerRef
|
|
50
|
+
ref: tableSizePickerRef,
|
|
51
|
+
testId: TOOLBAR_BUTTON_TEST_ID.TABLE_SELECTOR
|
|
50
52
|
})));
|
|
51
53
|
};
|
|
@@ -3,7 +3,7 @@ import { useIntl } from 'react-intl-next';
|
|
|
3
3
|
import { INPUT_METHOD } from '@atlaskit/editor-common/analytics';
|
|
4
4
|
import { ToolTipContent, insertTaskList } from '@atlaskit/editor-common/keymaps';
|
|
5
5
|
import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
|
|
6
|
-
import { useEditorToolbar } from '@atlaskit/editor-common/toolbar';
|
|
6
|
+
import { TOOLBAR_BUTTON_TEST_ID, useEditorToolbar } from '@atlaskit/editor-common/toolbar';
|
|
7
7
|
import { ToolbarButton, ToolbarTooltip, TaskIcon } from '@atlaskit/editor-toolbar';
|
|
8
8
|
export var TaskListButton = function TaskListButton(_ref) {
|
|
9
9
|
var api = _ref.api;
|
|
@@ -33,6 +33,7 @@ export var TaskListButton = function TaskListButton(_ref) {
|
|
|
33
33
|
size: "small"
|
|
34
34
|
}),
|
|
35
35
|
onClick: onClick,
|
|
36
|
-
ariaKeyshortcuts: "[ ] Space"
|
|
36
|
+
ariaKeyshortcuts: "[ ] Space",
|
|
37
|
+
testId: TOOLBAR_BUTTON_TEST_ID.TASK_LIST
|
|
37
38
|
}));
|
|
38
39
|
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type DispatchAnalyticsEvent } from '@atlaskit/editor-common/analytics';
|
|
2
|
+
import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
|
|
3
|
+
type ToolbarActionExperienceOptions = {
|
|
4
|
+
dispatchAnalyticsEvent: DispatchAnalyticsEvent;
|
|
5
|
+
refs: {
|
|
6
|
+
popupsMountPoint?: HTMLElement;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export declare const getToolbarActionExperiencesPlugin: ({ refs, dispatchAnalyticsEvent, }: ToolbarActionExperienceOptions) => SafePlugin<any>;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { ExperienceCheck, ExperienceCheckCallback, ExperienceCheckResult } from '@atlaskit/editor-common/experiences';
|
|
2
|
+
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
3
|
+
/**
|
|
4
|
+
* DOM marker selectors for node types inserted via toolbar actions.
|
|
5
|
+
* Matches outermost wrapper elements set synchronously by ReactNodeView
|
|
6
|
+
* (`{nodeTypeName}View-content-wrap`) or schema `toDOM` attributes.
|
|
7
|
+
*/
|
|
8
|
+
export declare const NODE_INSERT_MARKERS: {
|
|
9
|
+
readonly TABLE: ".tableView-content-wrap";
|
|
10
|
+
readonly LAYOUT: ".layoutSectionView-content-wrap";
|
|
11
|
+
readonly LAYOUT_COLUMN: ".layoutColumnView-content-wrap";
|
|
12
|
+
readonly TASK_LIST: "[data-node-type=\"actionList\"]";
|
|
13
|
+
readonly TASK_ITEM: ".taskItemView-content-wrap";
|
|
14
|
+
};
|
|
15
|
+
export declare const isToolbarButtonClick: (target: HTMLElement, testId: string) => boolean;
|
|
16
|
+
/**
|
|
17
|
+
* ExperienceCheck that observes popup mount point and all its
|
|
18
|
+
* `[data-editor-popup]` children with `{ childList: true }` (no subtree).
|
|
19
|
+
*
|
|
20
|
+
* Detects when a popup containing the given nested element is added to the
|
|
21
|
+
* DOM — either as a new `[data-editor-popup]` direct child, or as content
|
|
22
|
+
* rendered inside an existing `[data-editor-popup]` wrapper.
|
|
23
|
+
*/
|
|
24
|
+
export declare const TYPEAHEAD_DECORATION_SELECTOR = "[data-type-ahead=\"typeaheadDecoration\"]";
|
|
25
|
+
export declare const handleTypeAheadOpenDomMutation: ({ mutations, }: {
|
|
26
|
+
mutations: MutationRecord[];
|
|
27
|
+
}) => ExperienceCheckResult | undefined;
|
|
28
|
+
export declare class ExperienceCheckPopupMutation implements ExperienceCheck {
|
|
29
|
+
private nestedElementQuery;
|
|
30
|
+
private getTarget;
|
|
31
|
+
private getEditorDom;
|
|
32
|
+
private observers;
|
|
33
|
+
constructor(nestedElementQuery: string, getTarget: () => HTMLElement | undefined | null, getEditorDom: () => HTMLElement | undefined | null);
|
|
34
|
+
start(callback: ExperienceCheckCallback): void;
|
|
35
|
+
stop(): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Returns the narrow parent DOM element at the current selection, suitable
|
|
39
|
+
* for observing with `{ childList: true }` (no subtree).
|
|
40
|
+
*
|
|
41
|
+
* Uses the resolved position's depth to find the block node at the cursor
|
|
42
|
+
* via `nodeDOM`, then returns its `parentElement` — the container whose
|
|
43
|
+
* direct children change when content is inserted at this position.
|
|
44
|
+
*
|
|
45
|
+
* Falls back to `domAtPos` if `nodeDOM` is unavailable.
|
|
46
|
+
*/
|
|
47
|
+
export declare const getParentDOMAtSelection: (editorView?: EditorView) => HTMLElement | null;
|
|
48
|
+
/**
|
|
49
|
+
* Evaluates DOM mutations to detect a node insert action.
|
|
50
|
+
*
|
|
51
|
+
* Uses two strategies:
|
|
52
|
+
* 1. Marker-based: checks `addedNodes` against known node insert selectors.
|
|
53
|
+
* 2. Structure-based: detects element add+remove (block-level replacement).
|
|
54
|
+
*/
|
|
55
|
+
export declare const handleEditorNodeInsertDomMutation: ({ mutations, }: {
|
|
56
|
+
mutations: MutationRecord[];
|
|
57
|
+
}) => ExperienceCheckResult | undefined;
|