@atlaskit/editor-plugin-expand 1.3.0 → 1.3.2

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.
Files changed (77) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/legacyExpand/nodeviews/index.js +18 -5
  3. package/dist/cjs/singlePlayerExpand/commands.js +134 -0
  4. package/dist/cjs/singlePlayerExpand/node-views/index.js +381 -0
  5. package/dist/cjs/singlePlayerExpand/plugin.js +72 -9
  6. package/dist/cjs/singlePlayerExpand/pm-plugins/keymap.js +121 -0
  7. package/dist/cjs/singlePlayerExpand/pm-plugins/main.js +68 -0
  8. package/dist/cjs/singlePlayerExpand/toolbar.js +59 -0
  9. package/dist/cjs/singlePlayerExpand/ui/ExpandButton.js +87 -0
  10. package/dist/cjs/singlePlayerExpand/ui/NodeView.js +59 -0
  11. package/dist/cjs/singlePlayerExpand/utils.js +35 -0
  12. package/dist/es2019/index.js +0 -2
  13. package/dist/es2019/legacyExpand/nodeviews/index.js +18 -5
  14. package/dist/es2019/legacyExpand/pm-plugins/keymap.js +1 -2
  15. package/dist/es2019/singlePlayerExpand/commands.js +118 -0
  16. package/dist/es2019/singlePlayerExpand/node-views/index.js +370 -0
  17. package/dist/es2019/singlePlayerExpand/plugin.js +69 -10
  18. package/dist/es2019/singlePlayerExpand/pm-plugins/keymap.js +137 -0
  19. package/dist/es2019/singlePlayerExpand/pm-plugins/main.js +53 -0
  20. package/dist/es2019/singlePlayerExpand/toolbar.js +51 -0
  21. package/dist/es2019/singlePlayerExpand/ui/ExpandButton.js +77 -0
  22. package/dist/es2019/singlePlayerExpand/ui/NodeView.js +52 -0
  23. package/dist/es2019/singlePlayerExpand/utils.js +5 -0
  24. package/dist/esm/index.js +0 -2
  25. package/dist/esm/legacyExpand/nodeviews/index.js +18 -5
  26. package/dist/esm/legacyExpand/pm-plugins/keymap.js +1 -2
  27. package/dist/esm/singlePlayerExpand/commands.js +128 -0
  28. package/dist/esm/singlePlayerExpand/node-views/index.js +373 -0
  29. package/dist/esm/singlePlayerExpand/plugin.js +71 -10
  30. package/dist/esm/singlePlayerExpand/pm-plugins/keymap.js +115 -0
  31. package/dist/esm/singlePlayerExpand/pm-plugins/main.js +60 -0
  32. package/dist/esm/singlePlayerExpand/toolbar.js +52 -0
  33. package/dist/esm/singlePlayerExpand/ui/ExpandButton.js +77 -0
  34. package/dist/esm/singlePlayerExpand/ui/NodeView.js +53 -0
  35. package/dist/esm/singlePlayerExpand/utils.js +5 -0
  36. package/dist/types/index.d.ts +1 -1
  37. package/dist/types/legacyExpand/nodeviews/index.d.ts +1 -1
  38. package/dist/types/legacyExpand/plugin.d.ts +1 -1
  39. package/dist/types/legacyExpand/pm-plugins/keymap.d.ts +1 -1
  40. package/dist/types/legacyExpand/pm-plugins/main.d.ts +2 -2
  41. package/dist/types/legacyExpand/pm-plugins/plugin-factory.d.ts +1 -1
  42. package/dist/types/legacyExpand/reducer.d.ts +1 -1
  43. package/dist/types/legacyExpand/toolbar.d.ts +1 -1
  44. package/dist/types/plugin.d.ts +1 -1
  45. package/dist/types/singlePlayerExpand/commands.d.ts +15 -0
  46. package/dist/types/singlePlayerExpand/node-views/index.d.ts +51 -0
  47. package/dist/types/singlePlayerExpand/plugin.d.ts +1 -1
  48. package/dist/types/singlePlayerExpand/pm-plugins/keymap.d.ts +6 -0
  49. package/dist/types/singlePlayerExpand/pm-plugins/main.d.ts +9 -0
  50. package/dist/types/singlePlayerExpand/toolbar.d.ts +3 -0
  51. package/dist/types/singlePlayerExpand/ui/ExpandButton.d.ts +13 -0
  52. package/dist/types/singlePlayerExpand/ui/NodeView.d.ts +5 -0
  53. package/dist/types/singlePlayerExpand/utils.d.ts +3 -0
  54. package/dist/{types-ts4.5/legacyExpand → types}/types.d.ts +1 -1
  55. package/dist/types-ts4.5/index.d.ts +1 -1
  56. package/dist/types-ts4.5/legacyExpand/nodeviews/index.d.ts +1 -1
  57. package/dist/types-ts4.5/legacyExpand/plugin.d.ts +1 -1
  58. package/dist/types-ts4.5/legacyExpand/pm-plugins/keymap.d.ts +1 -1
  59. package/dist/types-ts4.5/legacyExpand/pm-plugins/main.d.ts +2 -2
  60. package/dist/types-ts4.5/legacyExpand/pm-plugins/plugin-factory.d.ts +1 -1
  61. package/dist/types-ts4.5/legacyExpand/reducer.d.ts +1 -1
  62. package/dist/types-ts4.5/legacyExpand/toolbar.d.ts +1 -1
  63. package/dist/types-ts4.5/plugin.d.ts +1 -1
  64. package/dist/types-ts4.5/singlePlayerExpand/commands.d.ts +15 -0
  65. package/dist/types-ts4.5/singlePlayerExpand/node-views/index.d.ts +51 -0
  66. package/dist/types-ts4.5/singlePlayerExpand/plugin.d.ts +1 -1
  67. package/dist/types-ts4.5/singlePlayerExpand/pm-plugins/keymap.d.ts +6 -0
  68. package/dist/types-ts4.5/singlePlayerExpand/pm-plugins/main.d.ts +9 -0
  69. package/dist/types-ts4.5/singlePlayerExpand/toolbar.d.ts +3 -0
  70. package/dist/types-ts4.5/singlePlayerExpand/ui/ExpandButton.d.ts +13 -0
  71. package/dist/types-ts4.5/singlePlayerExpand/ui/NodeView.d.ts +5 -0
  72. package/dist/types-ts4.5/singlePlayerExpand/utils.d.ts +3 -0
  73. package/dist/{types/legacyExpand → types-ts4.5}/types.d.ts +1 -1
  74. package/package.json +5 -5
  75. /package/dist/cjs/{legacyExpand/types.js → types.js} +0 -0
  76. /package/dist/es2019/{legacyExpand/types.js → types.js} +0 -0
  77. /package/dist/esm/{legacyExpand/types.js → types.js} +0 -0
@@ -0,0 +1,373 @@
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
+ import ReactDOM from 'react-dom';
5
+ import { keyName } from 'w3c-keyname';
6
+ import { GapCursorSelection, RelativeSelectionPos, Side } from '@atlaskit/editor-common/selection';
7
+ import { expandClassNames } from '@atlaskit/editor-common/styles';
8
+ import { closestElement, isEmptyNode } from '@atlaskit/editor-common/utils';
9
+ import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
10
+ import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
11
+ import { deleteExpand, setSelectionInsideExpand, updateExpandTitle } from '../commands';
12
+ import { renderIcon, toDOM } from '../ui/NodeView';
13
+ export var ExpandNodeView = /*#__PURE__*/function () {
14
+ function ExpandNodeView(node, view, getPos, getIntl, isMobile, selectNearNode, api) {
15
+ var _this = this;
16
+ var allowInteractiveExpand = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : true;
17
+ var __livePage = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : false;
18
+ _classCallCheck(this, ExpandNodeView);
19
+ _defineProperty(this, "allowInteractiveExpand", true);
20
+ _defineProperty(this, "isMobile", false);
21
+ _defineProperty(this, "focusTitle", function () {
22
+ if (_this.input) {
23
+ var _this$view = _this.view,
24
+ state = _this$view.state,
25
+ dispatch = _this$view.dispatch;
26
+ if (_this.selectNearNode) {
27
+ var tr = _this.selectNearNode({
28
+ selectionRelativeToNode: RelativeSelectionPos.Start
29
+ })(state);
30
+ if (dispatch) {
31
+ dispatch(tr);
32
+ }
33
+ }
34
+ var pos = _this.getPos();
35
+ if (typeof pos === 'number') {
36
+ setSelectionInsideExpand(pos)(state, dispatch, _this.view);
37
+ }
38
+ _this.input.focus();
39
+ }
40
+ });
41
+ _defineProperty(this, "handleIconKeyDown", function (event) {
42
+ switch (keyName(event)) {
43
+ case 'Tab':
44
+ event.preventDefault();
45
+ _this.focusTitle();
46
+ break;
47
+ case 'Enter':
48
+ event.preventDefault();
49
+ _this.handleClick(event);
50
+ break;
51
+ }
52
+ });
53
+ _defineProperty(this, "handleClick", function (event) {
54
+ var pos = _this.getPos();
55
+ if (typeof pos !== 'number') {
56
+ return;
57
+ }
58
+ var target = event.target;
59
+ if (closestElement(target, ".".concat(expandClassNames.icon))) {
60
+ if (!_this.allowInteractiveExpand) {
61
+ return;
62
+ }
63
+ event.stopPropagation();
64
+
65
+ // We blur the editorView, to prevent any keyboard showing on mobile
66
+ // When we're interacting with the expand toggle
67
+ if (_this.view.dom instanceof HTMLElement) {
68
+ _this.view.dom.blur();
69
+ }
70
+
71
+ // TODO https://product-fabric.atlassian.net/browse/ED-22841
72
+ // call toggleExpandExpanded
73
+
74
+ return;
75
+ }
76
+ if (target === _this.input) {
77
+ event.stopPropagation();
78
+ _this.focusTitle();
79
+ return;
80
+ }
81
+ });
82
+ _defineProperty(this, "handleInput", function (event) {
83
+ var pos = _this.getPos();
84
+ if (typeof pos !== 'number') {
85
+ return;
86
+ }
87
+ var target = event.target;
88
+ if (target === _this.input) {
89
+ event.stopPropagation();
90
+ var _this$view2 = _this.view,
91
+ state = _this$view2.state,
92
+ dispatch = _this$view2.dispatch;
93
+ updateExpandTitle({
94
+ title: target.value,
95
+ pos: pos,
96
+ nodeType: _this.node.type
97
+ })(state, dispatch);
98
+ }
99
+ });
100
+ _defineProperty(this, "handleFocus", function (event) {
101
+ event.stopImmediatePropagation();
102
+ });
103
+ _defineProperty(this, "handleTitleKeydown", function (event) {
104
+ switch (keyName(event)) {
105
+ case 'Enter':
106
+ // TO-DO
107
+ break;
108
+ case 'Tab':
109
+ case 'ArrowDown':
110
+ _this.moveToOutsideOfTitle(event);
111
+ break;
112
+ case 'ArrowRight':
113
+ _this.handleArrowRightFromTitle(event);
114
+ break;
115
+ case 'ArrowLeft':
116
+ _this.handleArrowLeftFromTitle(event);
117
+ break;
118
+ case 'ArrowUp':
119
+ _this.setLeftGapCursor(event);
120
+ break;
121
+ case 'Backspace':
122
+ _this.deleteEmptyExpand();
123
+ break;
124
+ }
125
+ });
126
+ _defineProperty(this, "deleteEmptyExpand", function () {
127
+ var state = _this.view.state;
128
+ var expandNode = _this.node;
129
+ if (expandNode && isEmptyNode(state.schema)(expandNode)) {
130
+ var _this$api;
131
+ deleteExpand((_this$api = _this.api) === null || _this$api === void 0 || (_this$api = _this$api.analytics) === null || _this$api === void 0 ? void 0 : _this$api.actions)(state, _this.view.dispatch);
132
+ }
133
+ });
134
+ _defineProperty(this, "moveToOutsideOfTitle", function (event) {
135
+ event.preventDefault();
136
+ var _this$view3 = _this.view,
137
+ state = _this$view3.state,
138
+ dispatch = _this$view3.dispatch;
139
+ var expandPos = _this.getPos();
140
+ if (typeof expandPos !== 'number') {
141
+ return;
142
+ }
143
+ var pos = expandPos;
144
+ if (_this.isCollapsed()) {
145
+ pos = expandPos + _this.node.nodeSize;
146
+ }
147
+ var resolvedPos = state.doc.resolve(pos);
148
+ if (!resolvedPos) {
149
+ return;
150
+ }
151
+ if (_this.isCollapsed() && resolvedPos.nodeAfter && ['expand', 'nestedExpand'].indexOf(resolvedPos.nodeAfter.type.name) > -1) {
152
+ return _this.setRightGapCursor(event);
153
+ }
154
+ var sel = Selection.findFrom(resolvedPos, 1, true);
155
+ if (sel) {
156
+ // If the input has focus, ProseMirror doesn't
157
+ // Give PM focus back before changing our selection
158
+ _this.view.focus();
159
+ dispatch(state.tr.setSelection(sel));
160
+ }
161
+ });
162
+ // TODO: https://product-fabric.atlassian.net/browse/ED-22841
163
+ _defineProperty(this, "isCollapsed", function () {
164
+ return false;
165
+ });
166
+ _defineProperty(this, "setRightGapCursor", function (event) {
167
+ if (!_this.input) {
168
+ return;
169
+ }
170
+ var pos = _this.getPos();
171
+ if (typeof pos !== 'number') {
172
+ return;
173
+ }
174
+ var _this$input = _this.input,
175
+ value = _this$input.value,
176
+ selectionStart = _this$input.selectionStart,
177
+ selectionEnd = _this$input.selectionEnd;
178
+ if (selectionStart === selectionEnd && selectionStart === value.length) {
179
+ var _this$view4 = _this.view,
180
+ state = _this$view4.state,
181
+ dispatch = _this$view4.dispatch;
182
+ event.preventDefault();
183
+ _this.view.focus();
184
+ dispatch(state.tr.setSelection(new GapCursorSelection(state.doc.resolve(_this.node.nodeSize + pos), Side.RIGHT)));
185
+ }
186
+ });
187
+ _defineProperty(this, "setLeftGapCursor", function (event) {
188
+ if (!_this.input) {
189
+ return;
190
+ }
191
+ var pos = _this.getPos();
192
+ if (typeof pos !== 'number') {
193
+ return;
194
+ }
195
+ var _this$input2 = _this.input,
196
+ selectionStart = _this$input2.selectionStart,
197
+ selectionEnd = _this$input2.selectionEnd;
198
+ if (selectionStart === selectionEnd && selectionStart === 0) {
199
+ event.preventDefault();
200
+ var _this$view5 = _this.view,
201
+ state = _this$view5.state,
202
+ dispatch = _this$view5.dispatch;
203
+ _this.view.focus();
204
+ dispatch(state.tr.setSelection(new GapCursorSelection(state.doc.resolve(pos), Side.LEFT)));
205
+ }
206
+ });
207
+ _defineProperty(this, "handleArrowRightFromTitle", function (event) {
208
+ if (!_this.input || !_this.selectNearNode) {
209
+ return;
210
+ }
211
+ var pos = _this.getPos();
212
+ if (typeof pos !== 'number') {
213
+ return;
214
+ }
215
+ var _this$input3 = _this.input,
216
+ value = _this$input3.value,
217
+ selectionStart = _this$input3.selectionStart,
218
+ selectionEnd = _this$input3.selectionEnd;
219
+ if (selectionStart === selectionEnd && selectionStart === value.length) {
220
+ event.preventDefault();
221
+ var _this$view6 = _this.view,
222
+ state = _this$view6.state,
223
+ dispatch = _this$view6.dispatch;
224
+ _this.view.focus();
225
+ var tr = _this.selectNearNode({
226
+ selectionRelativeToNode: RelativeSelectionPos.End,
227
+ selection: NodeSelection.create(state.doc, pos)
228
+ })(state);
229
+ if (dispatch) {
230
+ dispatch(tr);
231
+ }
232
+ }
233
+ });
234
+ _defineProperty(this, "handleArrowLeftFromTitle", function (event) {
235
+ if (!_this.input || !_this.selectNearNode) {
236
+ return;
237
+ }
238
+ var pos = _this.getPos();
239
+ if (typeof pos !== 'number') {
240
+ return;
241
+ }
242
+ var _this$input4 = _this.input,
243
+ selectionStart = _this$input4.selectionStart,
244
+ selectionEnd = _this$input4.selectionEnd;
245
+ if (selectionStart === selectionEnd && selectionStart === 0) {
246
+ var _this$api2;
247
+ event.preventDefault();
248
+ var _this$view7 = _this.view,
249
+ state = _this$view7.state,
250
+ dispatch = _this$view7.dispatch;
251
+ _this.view.focus();
252
+ var selectionSharedState = ((_this$api2 = _this.api) === null || _this$api2 === void 0 || (_this$api2 = _this$api2.selection) === null || _this$api2 === void 0 ? void 0 : _this$api2.sharedState.currentState()) || {};
253
+ // selectionRelativeToNode is undefined when user clicked to select node, then hit left to get focus in title
254
+ // This is a special case where we want to bypass node selection and jump straight to gap cursor
255
+ if ((selectionSharedState === null || selectionSharedState === void 0 ? void 0 : selectionSharedState.selectionRelativeToNode) === undefined) {
256
+ var tr = _this.selectNearNode({
257
+ selectionRelativeToNode: undefined,
258
+ selection: new GapCursorSelection(state.doc.resolve(pos), Side.LEFT)
259
+ })(state);
260
+ if (dispatch) {
261
+ dispatch(tr);
262
+ }
263
+ } else {
264
+ var _tr = _this.selectNearNode({
265
+ selectionRelativeToNode: RelativeSelectionPos.Start,
266
+ selection: NodeSelection.create(state.doc, pos)
267
+ })(state);
268
+ if (dispatch) {
269
+ dispatch(_tr);
270
+ }
271
+ }
272
+ }
273
+ });
274
+ this.selectNearNode = selectNearNode;
275
+ this.__livePage = __livePage;
276
+ this.intl = getIntl();
277
+ var _DOMSerializer$render = DOMSerializer.renderSpec(document, toDOM(node, this.__livePage, this.intl)),
278
+ dom = _DOMSerializer$render.dom,
279
+ contentDOM = _DOMSerializer$render.contentDOM;
280
+ this.allowInteractiveExpand = allowInteractiveExpand;
281
+ this.getPos = getPos;
282
+ this.view = view;
283
+ this.node = node;
284
+ this.dom = dom;
285
+ this.contentDOM = contentDOM;
286
+ this.isMobile = isMobile;
287
+ this.api = api;
288
+ this.icon = this.dom.querySelector(".".concat(expandClassNames.icon));
289
+ this.input = this.dom.querySelector(".".concat(expandClassNames.titleInput));
290
+ this.titleContainer = this.dom.querySelector(".".concat(expandClassNames.titleContainer));
291
+ renderIcon(this.icon, this.allowInteractiveExpand, this.intl);
292
+ if (!this.input || !this.titleContainer || !this.icon) {
293
+ return;
294
+ }
295
+
296
+ // Add event listeners
297
+ /* eslint-disable @repo/internal/dom-events/no-unsafe-event-listeners*/
298
+ this.dom.addEventListener('click', this.handleClick);
299
+ this.dom.addEventListener('input', this.handleInput);
300
+ this.input.addEventListener('keydown', this.handleTitleKeydown);
301
+ // If the user interacts in our title bar (either toggle or input)
302
+ // Prevent ProseMirror from getting a focus event (causes weird selection issues).
303
+ this.titleContainer.addEventListener('focus', this.handleFocus);
304
+ this.icon.addEventListener('keydown', this.handleIconKeyDown);
305
+ }
306
+ _createClass(ExpandNodeView, [{
307
+ key: "stopEvent",
308
+ value: function stopEvent(event) {
309
+ var target = event.target;
310
+ return target === this.input || target === this.icon || !!closestElement(target, ".".concat(expandClassNames.icon));
311
+ }
312
+ }, {
313
+ key: "ignoreMutation",
314
+ value: function ignoreMutation(mutationRecord) {
315
+ // ME-1931: Mobile relies on composition which creates dom mutations. If we ignore them, prosemirror
316
+ // does not recognise the changes and reverts them.
317
+ if (this.isMobile && (mutationRecord.type === 'characterData' || mutationRecord.type === 'childList')) {
318
+ return false;
319
+ }
320
+ if (mutationRecord.type === 'selection') {
321
+ return false;
322
+ }
323
+ return true;
324
+ }
325
+ }, {
326
+ key: "update",
327
+ value: function update(node, _decorations) {
328
+ var _this2 = this;
329
+ if (this.node.type === node.type) {
330
+ // TODO: https://product-fabric.atlassian.net/browse/ED-22841
331
+ // Handle toggling of the expand on update here
332
+
333
+ // During a collab session the title doesn't sync with other users
334
+ // since we're intentionally being less aggressive about re-rendering.
335
+ // We also apply a rAF to avoid abrupt continuous replacement of the title.
336
+ window.requestAnimationFrame(function () {
337
+ if (_this2.input && _this2.node.attrs.title !== _this2.input.value) {
338
+ _this2.input.value = _this2.node.attrs.title;
339
+ }
340
+ });
341
+ this.node = node;
342
+ return true;
343
+ }
344
+ return false;
345
+ }
346
+ }, {
347
+ key: "destroy",
348
+ value: function destroy() {
349
+ if (!this.dom || !this.input || !this.titleContainer || !this.icon) {
350
+ return;
351
+ }
352
+ this.dom.removeEventListener('click', this.handleClick);
353
+ this.dom.removeEventListener('input', this.handleInput);
354
+ this.input.removeEventListener('keydown', this.handleTitleKeydown);
355
+ this.titleContainer.removeEventListener('focus', this.handleFocus);
356
+ this.icon.removeEventListener('keydown', this.handleIconKeyDown);
357
+ ReactDOM.unmountComponentAtNode(this.icon);
358
+ }
359
+ }]);
360
+ return ExpandNodeView;
361
+ }();
362
+ export default function (_ref) {
363
+ var getIntl = _ref.getIntl,
364
+ isMobile = _ref.isMobile,
365
+ api = _ref.api,
366
+ _ref$allowInteractive = _ref.allowInteractiveExpand,
367
+ allowInteractiveExpand = _ref$allowInteractive === void 0 ? true : _ref$allowInteractive,
368
+ __livePage = _ref.__livePage;
369
+ return function (node, view, getPos) {
370
+ var _api$selection;
371
+ return new ExpandNodeView(node, view, getPos, getIntl, isMobile, api === null || api === void 0 || (_api$selection = api.selection) === null || _api$selection === void 0 || (_api$selection = _api$selection.actions) === null || _api$selection === void 0 ? void 0 : _api$selection.selectNearNode, api, allowInteractiveExpand, __livePage);
372
+ };
373
+ }
@@ -1,10 +1,19 @@
1
+ import React from 'react';
1
2
  import { expand, extendedNestedExpand, nestedExpand } from '@atlaskit/adf-schema';
3
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
4
+ import { toolbarInsertBlockMessages as messages } from '@atlaskit/editor-common/messages';
5
+ import { IconExpand } from '@atlaskit/editor-common/quick-insert';
6
+ import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
2
7
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
3
-
4
- // TODO: https://product-fabric.atlassian.net/browse/ED-22840
5
- // In ED-22840 make sure we update the ExpandPlugin type to use singlePlayerExpands own types
6
-
7
- export var expandPlugin = function expandPlugin() {
8
+ import { createExpandNode, insertExpand } from './commands';
9
+ import { expandKeymap } from './pm-plugins/keymap';
10
+ import { createPlugin } from './pm-plugins/main';
11
+ import { getToolbarConfig } from './toolbar';
12
+ export var expandPlugin = function expandPlugin(_ref) {
13
+ var _api$analytics;
14
+ var _ref$config = _ref.config,
15
+ options = _ref$config === void 0 ? {} : _ref$config,
16
+ api = _ref.api;
8
17
  return {
9
18
  name: 'expand',
10
19
  nodes: function nodes() {
@@ -18,13 +27,65 @@ export var expandPlugin = function expandPlugin() {
18
27
  }];
19
28
  },
20
29
  actions: {
21
- insertExpand: function insertExpand() {
22
- return false;
23
- }
30
+ insertExpand: insertExpand(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions)
24
31
  },
25
32
  pmPlugins: function pmPlugins() {
26
- return [];
33
+ return [{
34
+ name: 'expand',
35
+ plugin: function plugin(_ref2) {
36
+ var _options$allowInterac;
37
+ var dispatch = _ref2.dispatch,
38
+ getIntl = _ref2.getIntl;
39
+ return createPlugin(dispatch, getIntl, options.appearance, options.useLongPressSelection, api, (_options$allowInterac = options.allowInteractiveExpand) !== null && _options$allowInterac !== void 0 ? _options$allowInterac : true, options.__livePage);
40
+ }
41
+ }, {
42
+ name: 'expandKeymap',
43
+ plugin: function plugin() {
44
+ return expandKeymap(api, {
45
+ __livePage: options.__livePage
46
+ });
47
+ }
48
+ }];
27
49
  },
28
- pluginsOptions: {}
50
+ pluginsOptions: {
51
+ floatingToolbar: getToolbarConfig(api),
52
+ quickInsert: function quickInsert(_ref3) {
53
+ var formatMessage = _ref3.formatMessage;
54
+ if (options && options.allowInsertion !== true) {
55
+ return [];
56
+ }
57
+ return [{
58
+ id: 'expand',
59
+ title: formatMessage(messages.expand),
60
+ description: formatMessage(messages.expandDescription),
61
+ keywords: ['accordion', 'collapse'],
62
+ priority: 600,
63
+ icon: function icon() {
64
+ return /*#__PURE__*/React.createElement(IconExpand, null);
65
+ },
66
+ action: function action(insert, state) {
67
+ var _api$analytics2;
68
+ var node = createExpandNode(state);
69
+ if (!node) {
70
+ return false;
71
+ }
72
+ var tr = state.selection.empty ? insert(node) : createWrapSelectionTransaction({
73
+ state: state,
74
+ type: node.type
75
+ });
76
+ api === null || api === void 0 || (_api$analytics2 = api.analytics) === null || _api$analytics2 === void 0 || _api$analytics2.actions.attachAnalyticsEvent({
77
+ action: ACTION.INSERTED,
78
+ actionSubject: ACTION_SUBJECT.DOCUMENT,
79
+ actionSubjectId: node.type === state.schema.nodes.nestedExpand ? ACTION_SUBJECT_ID.NESTED_EXPAND : ACTION_SUBJECT_ID.EXPAND,
80
+ attributes: {
81
+ inputMethod: INPUT_METHOD.QUICK_INSERT
82
+ },
83
+ eventType: EVENT_TYPE.TRACK
84
+ })(tr);
85
+ return tr;
86
+ }
87
+ }];
88
+ }
89
+ }
29
90
  };
30
91
  };
@@ -0,0 +1,115 @@
1
+ import { backspace, bindKeymapWithCommand, moveDown, moveUp } from '@atlaskit/editor-common/keymaps';
2
+ import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
3
+ import { findExpand } from '@atlaskit/editor-common/transforms';
4
+ import { isEmptyNode, isPositionNearTableRow } from '@atlaskit/editor-common/utils';
5
+ import { keymap } from '@atlaskit/editor-prosemirror/keymap';
6
+ import { Selection } from '@atlaskit/editor-prosemirror/state';
7
+ import { deleteExpand, focusTitle } from '../commands';
8
+ var isExpandNode = function isExpandNode(node) {
9
+ return (node === null || node === void 0 ? void 0 : node.type.name) === 'expand' || (node === null || node === void 0 ? void 0 : node.type.name) === 'nestedExpand';
10
+ };
11
+ export function expandKeymap(api, options) {
12
+ var list = {};
13
+ bindKeymapWithCommand(moveUp.common, function (state, dispatch, editorView) {
14
+ if (!editorView) {
15
+ return false;
16
+ }
17
+ var selection = state.selection,
18
+ schema = state.schema;
19
+ var nodeBefore = selection.$from.nodeBefore;
20
+ if (selection instanceof GapCursorSelection && selection.side === Side.RIGHT && nodeBefore && (nodeBefore.type === schema.nodes.expand || nodeBefore.type === schema.nodes.nestedExpand)
21
+ // TO-DO: add back in expanded logic
22
+ ) {
23
+ var _$from = selection.$from;
24
+ return focusTitle(Math.max(_$from.pos - 1, 0))(state, dispatch, editorView);
25
+ }
26
+ var $from = state.selection.$from;
27
+ if (editorView.endOfTextblock('up')) {
28
+ var expand = findExpand(state);
29
+
30
+ // Moving UP in a table should move the cursor to the row above
31
+ // however when an expand is in a table cell to the left of the
32
+ // current table cell, arrow UP moves the cursor to the left
33
+ // see ED-15425
34
+ if (isPositionNearTableRow($from, schema, 'before') && !expand) {
35
+ return false;
36
+ }
37
+ var prevCursorPos = Math.max($from.pos - $from.parentOffset - 1, 0);
38
+ // move cursor from expand's content to its title
39
+ if (expand && expand.start === prevCursorPos) {
40
+ return focusTitle(expand.start)(state, dispatch, editorView);
41
+ }
42
+ var sel = Selection.findFrom(state.doc.resolve(prevCursorPos), -1);
43
+ var expandBefore = findExpand(state, sel);
44
+ if (sel && expandBefore) {
45
+ // moving cursor from outside of an expand to the title when it is collapsed
46
+
47
+ // TO-DO: Bring back expanded logic
48
+ return focusTitle(expandBefore.start)(state, dispatch, editorView);
49
+ }
50
+ }
51
+ return false;
52
+ }, list);
53
+ bindKeymapWithCommand(moveDown.common, function (state, dispatch, editorView) {
54
+ if (!editorView) {
55
+ return false;
56
+ }
57
+ var _state$schema$nodes = state.schema.nodes,
58
+ expand = _state$schema$nodes.expand,
59
+ nestedExpand = _state$schema$nodes.nestedExpand;
60
+ var selection = state.selection;
61
+ var nodeAfter = selection.$from.nodeAfter;
62
+ if (selection instanceof GapCursorSelection && selection.side === Side.LEFT && nodeAfter && (nodeAfter.type === expand || nodeAfter.type === nestedExpand)
63
+ // TO-DO: Bring back expanded logic
64
+ ) {
65
+ var $from = selection.$from;
66
+ return focusTitle($from.pos + 1)(state, dispatch, editorView);
67
+ }
68
+ if (editorView.endOfTextblock('down')) {
69
+ var _$from2 = state.selection.$from;
70
+ if (_$from2.depth === 0) {
71
+ return false;
72
+ }
73
+ var $after = state.doc.resolve(_$from2.after());
74
+ if ($after.nodeAfter && ($after.nodeAfter.type === expand || $after.nodeAfter.type === nestedExpand)) {
75
+ return focusTitle($after.pos + 1)(state, dispatch, editorView);
76
+ }
77
+ }
78
+ return false;
79
+ }, list);
80
+ bindKeymapWithCommand(backspace.common, function (state, dispatch, editorView) {
81
+ var selection = state.selection;
82
+ var $from = selection.$from;
83
+ if (!editorView || !selection.empty) {
84
+ return false;
85
+ }
86
+ var _state$schema$nodes2 = state.schema.nodes,
87
+ expand = _state$schema$nodes2.expand,
88
+ nestedExpand = _state$schema$nodes2.nestedExpand;
89
+ var expandNode = findExpand(state);
90
+ if (!expandNode) {
91
+ // @see ED-7977
92
+ var sel = Selection.findFrom(state.doc.resolve(Math.max(selection.$from.pos - 1, 0)), -1);
93
+ var expandBefore = findExpand(state, sel);
94
+ if (expandBefore && (expandBefore.node.type === expand || expandBefore.node.type === nestedExpand)
95
+ // TO-DO: Bring back expanded logic
96
+ ) {
97
+ return focusTitle(expandBefore.start)(state, dispatch, editorView);
98
+ }
99
+ return false;
100
+ }
101
+ var parentNode = state.doc.nodeAt($from.before(Math.max($from.depth - 1, 1)));
102
+ // ED-10012 catch cases where the expand has another node nested within it and
103
+ // the backspace should be applied only to the inner node instead of the expand
104
+ if (parentNode && !isExpandNode(parentNode)) {
105
+ return false;
106
+ }
107
+ var textSel = Selection.findFrom(state.doc.resolve(expandNode.pos), 1, true);
108
+ if (textSel && selection.$from.pos === textSel.$from.pos && isEmptyNode(state.schema)(expandNode.node) && dispatch) {
109
+ var _api$analytics;
110
+ return deleteExpand(api === null || api === void 0 || (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : _api$analytics.actions)(state, dispatch);
111
+ }
112
+ return false;
113
+ }, list);
114
+ return keymap(list);
115
+ }
@@ -0,0 +1,60 @@
1
+ import { SafePlugin } from '@atlaskit/editor-common/safe-plugin';
2
+ import { createSelectionClickHandler } from '@atlaskit/editor-common/selection';
3
+ import { expandClassNames } from '@atlaskit/editor-common/styles';
4
+ import { PluginKey } from '@atlaskit/editor-prosemirror/state';
5
+ import ExpandNodeView from '../node-views';
6
+ export var pluginKey = new PluginKey('expandPlugin');
7
+ export function containsClass(element, className) {
8
+ var _element$classList;
9
+ return Boolean(element === null || element === void 0 || (_element$classList = element.classList) === null || _element$classList === void 0 ? void 0 : _element$classList.contains(className));
10
+ }
11
+ export var createPlugin = function createPlugin(dispatch, getIntl) {
12
+ var appearance = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'full-page';
13
+ var useLongPressSelection = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
14
+ var api = arguments.length > 4 ? arguments[4] : undefined;
15
+ var allowInteractiveExpand = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
16
+ var __livePage = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;
17
+ var isMobile = appearance === 'mobile';
18
+ return new SafePlugin({
19
+ key: pluginKey,
20
+ props: {
21
+ nodeViews: {
22
+ expand: ExpandNodeView({
23
+ getIntl: getIntl,
24
+ isMobile: isMobile,
25
+ api: api,
26
+ allowInteractiveExpand: allowInteractiveExpand,
27
+ __livePage: __livePage
28
+ }),
29
+ nestedExpand: ExpandNodeView({
30
+ getIntl: getIntl,
31
+ isMobile: isMobile,
32
+ api: api,
33
+ allowInteractiveExpand: allowInteractiveExpand,
34
+ __livePage: __livePage
35
+ })
36
+ },
37
+ handleKeyDown: function handleKeyDown(_view, event) {
38
+ return containsClass(event.target, expandClassNames.titleContainer);
39
+ },
40
+ handleKeyPress: function handleKeyPress(_view, event) {
41
+ return containsClass(event.target, expandClassNames.titleContainer);
42
+ },
43
+ handleScrollToSelection: function handleScrollToSelection() {
44
+ return containsClass(document.activeElement, expandClassNames.titleInput);
45
+ },
46
+ handleClickOn: createSelectionClickHandler(['expand', 'nestedExpand'], function (target) {
47
+ return target.classList.contains(expandClassNames.prefix);
48
+ }, {
49
+ useLongPressSelection: useLongPressSelection
50
+ })
51
+ },
52
+ // @see ED-8027 to follow up on this work-around
53
+ filterTransaction: function filterTransaction(tr) {
54
+ if (containsClass(document.activeElement, expandClassNames.titleInput) && tr.selectionSet && (!tr.steps.length || tr.isGeneric)) {
55
+ return false;
56
+ }
57
+ return true;
58
+ }
59
+ });
60
+ };