@atlaskit/editor-plugin-expand 1.4.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @atlaskit/editor-plugin-expand
2
2
 
3
+ ## 1.4.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#90897](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/90897) [`6a1d609df65e`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/6a1d609df65e) - [ux] [ED-22841] Implement new state management for the single player expand and handle the expanding behaviour based on this. Single player expand will only be used if `platform.editor.single-player-expand` is true and livePage is enabled.
8
+
3
9
  ## 1.4.0
4
10
 
5
11
  ### Minor Changes
@@ -4,10 +4,12 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.updateExpandTitle = exports.setSelectionInsideExpand = exports.insertExpand = exports.focusTitle = exports.deleteExpandAtPos = exports.deleteExpand = exports.createExpandNode = void 0;
7
+ exports.updateExpandTitle = exports.toggleExpandExpanded = exports.setSelectionInsideExpand = exports.insertExpand = exports.focusTitle = exports.deleteExpandAtPos = exports.deleteExpand = exports.createExpandNode = void 0;
8
8
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
9
  var _steps = require("@atlaskit/adf-schema/steps");
10
10
  var _analytics = require("@atlaskit/editor-common/analytics");
11
+ var _expand = require("@atlaskit/editor-common/expand");
12
+ var _selection = require("@atlaskit/editor-common/selection");
11
13
  var _transforms = require("@atlaskit/editor-common/transforms");
12
14
  var _utils = require("@atlaskit/editor-common/utils");
13
15
  var _state = require("@atlaskit/editor-prosemirror/state");
@@ -21,7 +23,9 @@ var createExpandNode = exports.createExpandNode = function createExpandNode(stat
21
23
  expand = _state$schema$nodes.expand,
22
24
  nestedExpand = _state$schema$nodes.nestedExpand;
23
25
  var expandType = (0, _utils3.findTable)(state.selection) ? nestedExpand : expand;
24
- return expandType.createAndFill({});
26
+ var expandNode = expandType.createAndFill({});
27
+ _expand.expandedState.set(expandNode, true);
28
+ return expandNode;
25
29
  };
26
30
  var insertExpand = exports.insertExpand = function insertExpand(editorAnalyticsAPI) {
27
31
  return function (state, dispatch) {
@@ -99,10 +103,47 @@ var setSelectionInsideExpand = exports.setSelectionInsideExpand = function setSe
99
103
  return false;
100
104
  };
101
105
  };
102
- var updateExpandTitle = exports.updateExpandTitle = function updateExpandTitle(_ref) {
103
- var title = _ref.title,
104
- nodeType = _ref.nodeType,
105
- pos = _ref.pos;
106
+ var toggleExpandExpanded = exports.toggleExpandExpanded = function toggleExpandExpanded(_ref) {
107
+ var editorAnalyticsAPI = _ref.editorAnalyticsAPI,
108
+ pos = _ref.pos,
109
+ node = _ref.node;
110
+ return function (state, dispatch) {
111
+ if (node && dispatch) {
112
+ var _expandedState$get;
113
+ var tr = state.tr;
114
+ var expanded = (_expandedState$get = _expand.expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false;
115
+ var isExpandedNext = !expanded;
116
+ _expand.expandedState.set(node, isExpandedNext);
117
+
118
+ // If we're going to collapse the expand and our cursor is currently inside
119
+ // Move to a right gap cursor, if the toolbar is interacted (or an API),
120
+ // it will insert below rather than inside (which will be invisible).
121
+ if (isExpandedNext === true) {
122
+ tr.setSelection(new _selection.GapCursorSelection(tr.doc.resolve(pos + node.nodeSize), _selection.Side.RIGHT));
123
+ }
124
+
125
+ // log when people open/close expands
126
+ // TODO: ED-8523 make platform/mode global attributes?
127
+ var payload = {
128
+ action: _analytics.ACTION.TOGGLE_EXPAND,
129
+ actionSubject: node.type === state.schema.nodes.expand ? _analytics.ACTION_SUBJECT.EXPAND : _analytics.ACTION_SUBJECT.NESTED_EXPAND,
130
+ attributes: {
131
+ platform: _analytics.PLATFORMS.WEB,
132
+ mode: _analytics.MODE.EDITOR,
133
+ expanded: isExpandedNext
134
+ },
135
+ eventType: _analytics.EVENT_TYPE.TRACK
136
+ };
137
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
138
+ dispatch(tr);
139
+ }
140
+ return true;
141
+ };
142
+ };
143
+ var updateExpandTitle = exports.updateExpandTitle = function updateExpandTitle(_ref2) {
144
+ var title = _ref2.title,
145
+ nodeType = _ref2.nodeType,
146
+ pos = _ref2.pos;
106
147
  return function (state, dispatch) {
107
148
  var node = state.doc.nodeAt(pos);
108
149
  if (node && node.type === nodeType && dispatch) {
@@ -11,6 +11,7 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
11
11
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
12
12
  var _reactDom = _interopRequireDefault(require("react-dom"));
13
13
  var _w3cKeyname = require("w3c-keyname");
14
+ var _expand = require("@atlaskit/editor-common/expand");
14
15
  var _selection = require("@atlaskit/editor-common/selection");
15
16
  var _styles = require("@atlaskit/editor-common/styles");
16
17
  var _utils = require("@atlaskit/editor-common/utils");
@@ -67,6 +68,7 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
67
68
  }
68
69
  var target = event.target;
69
70
  if ((0, _utils.closestElement)(target, ".".concat(_styles.expandClassNames.icon))) {
71
+ var _this$api2;
70
72
  if (!_this.allowInteractiveExpand) {
71
73
  return;
72
74
  }
@@ -77,10 +79,12 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
77
79
  if (_this.view.dom instanceof HTMLElement) {
78
80
  _this.view.dom.blur();
79
81
  }
80
-
81
- // TODO https://product-fabric.atlassian.net/browse/ED-22841
82
- // call toggleExpandExpanded
83
-
82
+ (0, _commands.toggleExpandExpanded)({
83
+ editorAnalyticsAPI: (_this$api2 = _this.api) === null || _this$api2 === void 0 || (_this$api2 = _this$api2.analytics) === null || _this$api2 === void 0 ? void 0 : _this$api2.actions,
84
+ pos: pos,
85
+ node: _this.node
86
+ })(_this.view.state, _this.view.dispatch);
87
+ _this.updateExpandClassName();
84
88
  return;
85
89
  }
86
90
  if (target === _this.input) {
@@ -117,7 +121,7 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
117
121
  (0, _defineProperty2.default)(this, "handleTitleKeydown", function (event) {
118
122
  switch ((0, _w3cKeyname.keyName)(event)) {
119
123
  case 'Enter':
120
- // TO-DO
124
+ _this.toggleExpand();
121
125
  break;
122
126
  case 'Tab':
123
127
  case 'ArrowDown':
@@ -150,15 +154,33 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
150
154
  return;
151
155
  }
152
156
  if (expandNode && (0, _utils.isEmptyNode)(state.schema)(expandNode)) {
153
- var _this$api2;
154
- (0, _commands.deleteExpand)((_this$api2 = _this.api) === null || _this$api2 === void 0 || (_this$api2 = _this$api2.analytics) === null || _this$api2 === void 0 ? void 0 : _this$api2.actions)(state, _this.view.dispatch);
157
+ var _this$api3;
158
+ (0, _commands.deleteExpand)((_this$api3 = _this.api) === null || _this$api3 === void 0 || (_this$api3 = _this$api3.analytics) === null || _this$api3 === void 0 ? void 0 : _this$api3.actions)(state, _this.view.dispatch);
159
+ }
160
+ });
161
+ (0, _defineProperty2.default)(this, "toggleExpand", function () {
162
+ var pos = _this.getPos();
163
+ if (typeof pos !== 'number') {
164
+ return;
165
+ }
166
+ if (_this.allowInteractiveExpand) {
167
+ var _this$api4;
168
+ var _this$view3 = _this.view,
169
+ state = _this$view3.state,
170
+ dispatch = _this$view3.dispatch;
171
+ (0, _commands.toggleExpandExpanded)({
172
+ editorAnalyticsAPI: (_this$api4 = _this.api) === null || _this$api4 === void 0 || (_this$api4 = _this$api4.analytics) === null || _this$api4 === void 0 ? void 0 : _this$api4.actions,
173
+ pos: pos,
174
+ node: _this.node
175
+ })(state, dispatch);
176
+ _this.updateExpandClassName();
155
177
  }
156
178
  });
157
179
  (0, _defineProperty2.default)(this, "moveToOutsideOfTitle", function (event) {
158
180
  event.preventDefault();
159
- var _this$view3 = _this.view,
160
- state = _this$view3.state,
161
- dispatch = _this$view3.dispatch;
181
+ var _this$view4 = _this.view,
182
+ state = _this$view4.state,
183
+ dispatch = _this$view4.dispatch;
162
184
  var expandPos = _this.getPos();
163
185
  if (typeof expandPos !== 'number') {
164
186
  return;
@@ -182,9 +204,8 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
182
204
  dispatch(state.tr.setSelection(sel));
183
205
  }
184
206
  });
185
- // TODO: https://product-fabric.atlassian.net/browse/ED-22841
186
207
  (0, _defineProperty2.default)(this, "isCollapsed", function () {
187
- return false;
208
+ return !_expand.expandedState.get(_this.node);
188
209
  });
189
210
  (0, _defineProperty2.default)(this, "setRightGapCursor", function (event) {
190
211
  if (!_this.input) {
@@ -199,9 +220,9 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
199
220
  selectionStart = _this$input2.selectionStart,
200
221
  selectionEnd = _this$input2.selectionEnd;
201
222
  if (selectionStart === selectionEnd && selectionStart === value.length) {
202
- var _this$view4 = _this.view,
203
- state = _this$view4.state,
204
- dispatch = _this$view4.dispatch;
223
+ var _this$view5 = _this.view,
224
+ state = _this$view5.state,
225
+ dispatch = _this$view5.dispatch;
205
226
  event.preventDefault();
206
227
  _this.view.focus();
207
228
  dispatch(state.tr.setSelection(new _selection.GapCursorSelection(state.doc.resolve(_this.node.nodeSize + pos), _selection.Side.RIGHT)));
@@ -220,9 +241,9 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
220
241
  selectionEnd = _this$input3.selectionEnd;
221
242
  if (selectionStart === selectionEnd && selectionStart === 0) {
222
243
  event.preventDefault();
223
- var _this$view5 = _this.view,
224
- state = _this$view5.state,
225
- dispatch = _this$view5.dispatch;
244
+ var _this$view6 = _this.view,
245
+ state = _this$view6.state,
246
+ dispatch = _this$view6.dispatch;
226
247
  _this.view.focus();
227
248
  dispatch(state.tr.setSelection(new _selection.GapCursorSelection(state.doc.resolve(pos), _selection.Side.LEFT)));
228
249
  }
@@ -241,9 +262,9 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
241
262
  selectionEnd = _this$input4.selectionEnd;
242
263
  if (selectionStart === selectionEnd && selectionStart === value.length) {
243
264
  event.preventDefault();
244
- var _this$view6 = _this.view,
245
- state = _this$view6.state,
246
- dispatch = _this$view6.dispatch;
265
+ var _this$view7 = _this.view,
266
+ state = _this$view7.state,
267
+ dispatch = _this$view7.dispatch;
247
268
  _this.view.focus();
248
269
  var tr = _this.selectNearNode({
249
270
  selectionRelativeToNode: _selection.RelativeSelectionPos.End,
@@ -266,13 +287,13 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
266
287
  selectionStart = _this$input5.selectionStart,
267
288
  selectionEnd = _this$input5.selectionEnd;
268
289
  if (selectionStart === selectionEnd && selectionStart === 0) {
269
- var _this$api3;
290
+ var _this$api5;
270
291
  event.preventDefault();
271
- var _this$view7 = _this.view,
272
- state = _this$view7.state,
273
- dispatch = _this$view7.dispatch;
292
+ var _this$view8 = _this.view,
293
+ state = _this$view8.state,
294
+ dispatch = _this$view8.dispatch;
274
295
  _this.view.focus();
275
- var selectionSharedState = ((_this$api3 = _this.api) === null || _this$api3 === void 0 || (_this$api3 = _this$api3.selection) === null || _this$api3 === void 0 ? void 0 : _this$api3.sharedState.currentState()) || {};
296
+ var selectionSharedState = ((_this$api5 = _this.api) === null || _this$api5 === void 0 || (_this$api5 = _this$api5.selection) === null || _this$api5 === void 0 ? void 0 : _this$api5.sharedState.currentState()) || {};
276
297
  // selectionRelativeToNode is undefined when user clicked to select node, then hit left to get focus in title
277
298
  // This is a special case where we want to bypass node selection and jump straight to gap cursor
278
299
  if ((selectionSharedState === null || selectionSharedState === void 0 ? void 0 : selectionSharedState.selectionRelativeToNode) === undefined) {
@@ -297,13 +318,13 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
297
318
  this.selectNearNode = selectNearNode;
298
319
  this.__livePage = __livePage;
299
320
  this.intl = getIntl();
300
- var _DOMSerializer$render = _model.DOMSerializer.renderSpec(document, (0, _NodeView.toDOM)(node, this.__livePage, this.intl)),
301
- dom = _DOMSerializer$render.dom,
302
- contentDOM = _DOMSerializer$render.contentDOM;
303
321
  this.allowInteractiveExpand = allowInteractiveExpand;
304
322
  this.getPos = getPos;
305
323
  this.view = view;
306
324
  this.node = node;
325
+ var _DOMSerializer$render = _model.DOMSerializer.renderSpec(document, (0, _NodeView.toDOM)(node, this.__livePage, this.intl)),
326
+ dom = _DOMSerializer$render.dom,
327
+ contentDOM = _DOMSerializer$render.contentDOM;
307
328
  this.dom = dom;
308
329
  this.contentDOM = contentDOM;
309
330
  this.isMobile = isMobile;
@@ -312,6 +333,9 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
312
333
  this.input = this.dom.querySelector(".".concat(_styles.expandClassNames.titleInput));
313
334
  this.titleContainer = this.dom.querySelector(".".concat(_styles.expandClassNames.titleContainer));
314
335
  (0, _NodeView.renderIcon)(this.icon, this.allowInteractiveExpand, this.intl);
336
+ if (!_expand.expandedState.has(this.node)) {
337
+ _expand.expandedState.set(this.node, false);
338
+ }
315
339
  if (!this.input || !this.titleContainer || !this.icon) {
316
340
  return;
317
341
  }
@@ -351,9 +375,6 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
351
375
  value: function update(node, _decorations) {
352
376
  var _this2 = this;
353
377
  if (this.node.type === node.type) {
354
- // TODO: https://product-fabric.atlassian.net/browse/ED-22841
355
- // Handle toggling of the expand on update here
356
-
357
378
  // During a collab session the title doesn't sync with other users
358
379
  // since we're intentionally being less aggressive about re-rendering.
359
380
  // We also apply a rAF to avoid abrupt continuous replacement of the title.
@@ -362,11 +383,27 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
362
383
  _this2.input.value = _this2.node.attrs.title;
363
384
  }
364
385
  });
386
+ if (this.node !== node) {
387
+ var previousExpandedState = _expand.expandedState.get(this.node);
388
+ if (previousExpandedState === undefined) {
389
+ previousExpandedState = true;
390
+ }
391
+ _expand.expandedState.set(node, previousExpandedState);
392
+ _expand.expandedState.delete(this.node);
393
+ }
365
394
  this.node = node;
366
395
  return true;
367
396
  }
368
397
  return false;
369
398
  }
399
+ }, {
400
+ key: "updateExpandClassName",
401
+ value: function updateExpandClassName() {
402
+ var expanded = _expand.expandedState.get(this.node) ? _expand.expandedState.get(this.node) : false;
403
+ if (this.dom && expanded !== undefined) {
404
+ this.dom.className = (0, _NodeView.buildExpandClassName)(this.node.type.name, expanded);
405
+ }
406
+ }
370
407
  }, {
371
408
  key: "destroy",
372
409
  value: function destroy() {
@@ -382,6 +419,7 @@ var ExpandNodeView = exports.ExpandNodeView = /*#__PURE__*/function () {
382
419
  this.icon.removeEventListener('keydown', this.handleIconKeyDown);
383
420
  (_this$decorationClean2 = this.decorationCleanup) === null || _this$decorationClean2 === void 0 || _this$decorationClean2.call(this);
384
421
  _reactDom.default.unmountComponentAtNode(this.icon);
422
+ _expand.expandedState.delete(this.node);
385
423
  }
386
424
  }]);
387
425
  return ExpandNodeView;
@@ -24,7 +24,8 @@ function expandKeymap(api, options) {
24
24
  schema = state.schema;
25
25
  var nodeBefore = selection.$from.nodeBefore;
26
26
  if (selection instanceof _selection.GapCursorSelection && selection.side === _selection.Side.RIGHT && nodeBefore && (nodeBefore.type === schema.nodes.expand || nodeBefore.type === schema.nodes.nestedExpand)
27
- // TO-DO: add back in expanded logic
27
+ // https://product-fabric.atlassian.net/browse/ED-22991
28
+ // TODO: add back in expanded logic
28
29
  ) {
29
30
  var _$from = selection.$from;
30
31
  return (0, _commands.focusTitle)(Math.max(_$from.pos - 1, 0))(state, dispatch, editorView);
@@ -50,7 +51,8 @@ function expandKeymap(api, options) {
50
51
  if (sel && expandBefore) {
51
52
  // moving cursor from outside of an expand to the title when it is collapsed
52
53
 
53
- // TO-DO: Bring back expanded logic
54
+ // https://product-fabric.atlassian.net/browse/ED-22991
55
+ // TODO: add back in expanded logic
54
56
  return (0, _commands.focusTitle)(expandBefore.start)(state, dispatch, editorView);
55
57
  }
56
58
  }
@@ -66,7 +68,8 @@ function expandKeymap(api, options) {
66
68
  var selection = state.selection;
67
69
  var nodeAfter = selection.$from.nodeAfter;
68
70
  if (selection instanceof _selection.GapCursorSelection && selection.side === _selection.Side.LEFT && nodeAfter && (nodeAfter.type === expand || nodeAfter.type === nestedExpand)
69
- // TO-DO: Bring back expanded logic
71
+ // https://product-fabric.atlassian.net/browse/ED-22991
72
+ // TODO: add back in expanded logic
70
73
  ) {
71
74
  var $from = selection.$from;
72
75
  return (0, _commands.focusTitle)($from.pos + 1)(state, dispatch, editorView);
@@ -98,7 +101,8 @@ function expandKeymap(api, options) {
98
101
  var sel = _state.Selection.findFrom(state.doc.resolve(Math.max(selection.$from.pos - 1, 0)), -1);
99
102
  var expandBefore = (0, _transforms.findExpand)(state, sel);
100
103
  if (expandBefore && (expandBefore.node.type === expand || expandBefore.node.type === nestedExpand)
101
- // TO-DO: Bring back expanded logic
104
+ // https://product-fabric.atlassian.net/browse/ED-22991
105
+ // TODO: add back in expanded logic
102
106
  ) {
103
107
  return (0, _commands.focusTitle)(expandBefore.start)(state, dispatch, editorView);
104
108
  }
@@ -7,17 +7,18 @@ Object.defineProperty(exports, "__esModule", {
7
7
  exports.toDOM = exports.renderIcon = exports.buildExpandClassName = void 0;
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
  var _reactDom = _interopRequireDefault(require("react-dom"));
10
+ var _expand = require("@atlaskit/editor-common/expand");
10
11
  var _styles = require("@atlaskit/editor-common/styles");
11
12
  var _ui = require("@atlaskit/editor-common/ui");
12
13
  var _ExpandButton = require("../ui/ExpandButton");
13
- // TODO: https://product-fabric.atlassian.net/browse/ED-22841
14
- var buildExpandClassName = exports.buildExpandClassName = function buildExpandClassName(type) {
15
- return "".concat(_styles.expandClassNames.prefix, " ").concat(_styles.expandClassNames.type(type), "\n ").concat(_styles.expandClassNames.expanded);
14
+ var buildExpandClassName = exports.buildExpandClassName = function buildExpandClassName(type, expanded) {
15
+ return "".concat(_styles.expandClassNames.prefix, " ").concat(_styles.expandClassNames.type(type), " ").concat(expanded ? _styles.expandClassNames.expanded : '');
16
16
  };
17
17
  var toDOM = exports.toDOM = function toDOM(node, __livePage, intl) {
18
+ var _expandedState$get;
18
19
  return ['div', {
19
20
  // prettier-ignore
20
- 'class': buildExpandClassName(node.type.name),
21
+ 'class': buildExpandClassName(node.type.name, (_expandedState$get = _expand.expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false),
21
22
  'data-node-type': node.type.name,
22
23
  'data-title': node.attrs.title
23
24
  }, ['div', {
@@ -39,7 +40,7 @@ var toDOM = exports.toDOM = function toDOM(node, __livePage, intl) {
39
40
  // prettier-ignore
40
41
  'class': _styles.expandClassNames.titleInput,
41
42
  value: node.attrs.title,
42
- placeholder: intl && intl.formatMessage(_ui.expandMessages.expandPlaceholderText) || _ui.expandMessages.expandPlaceholderText.defaultMessage,
43
+ placeholder: intl && typeof intl.formatMessage === 'function' && intl.formatMessage(_ui.expandMessages.expandPlaceholderText) || _ui.expandMessages.expandPlaceholderText.defaultMessage,
43
44
  type: 'text'
44
45
  }]]],
45
46
  // prettier-ignore
@@ -51,9 +52,13 @@ var renderIcon = exports.renderIcon = function renderIcon(icon, allowInteractive
51
52
  if (!icon) {
52
53
  return;
53
54
  }
55
+ var expanded = node ? _expand.expandedState.get(node) : true;
56
+ if (expanded === undefined) {
57
+ expanded = false;
58
+ }
54
59
  _reactDom.default.render( /*#__PURE__*/_react.default.createElement(_ExpandButton.ExpandButton, {
55
60
  intl: intl,
56
61
  allowInteractiveExpand: allowInteractiveExpand,
57
- expanded: true // TO-DO https://product-fabric.atlassian.net/browse/ED-22841
62
+ expanded: expanded
58
63
  }), icon);
59
64
  };
@@ -1,5 +1,7 @@
1
1
  import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
2
- import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
2
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD, MODE, PLATFORMS } from '@atlaskit/editor-common/analytics';
3
+ import { expandedState } from '@atlaskit/editor-common/expand';
4
+ import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
3
5
  import { findExpand } from '@atlaskit/editor-common/transforms';
4
6
  import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
5
7
  import { Selection } from '@atlaskit/editor-prosemirror/state';
@@ -13,7 +15,9 @@ export const createExpandNode = state => {
13
15
  nestedExpand
14
16
  } = state.schema.nodes;
15
17
  const expandType = findTable(state.selection) ? nestedExpand : expand;
16
- return expandType.createAndFill({});
18
+ const expandNode = expandType.createAndFill({});
19
+ expandedState.set(expandNode, true);
20
+ return expandNode;
17
21
  };
18
22
  export const insertExpand = editorAnalyticsAPI => (state, dispatch) => {
19
23
  const expandNode = createExpandNode(state);
@@ -83,6 +87,44 @@ export const setSelectionInsideExpand = expandPos => (state, dispatch, editorVie
83
87
  }
84
88
  return false;
85
89
  };
90
+ export const toggleExpandExpanded = ({
91
+ editorAnalyticsAPI,
92
+ pos,
93
+ node
94
+ }) => (state, dispatch) => {
95
+ if (node && dispatch) {
96
+ var _expandedState$get;
97
+ const {
98
+ tr
99
+ } = state;
100
+ const expanded = (_expandedState$get = expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false;
101
+ const isExpandedNext = !expanded;
102
+ expandedState.set(node, isExpandedNext);
103
+
104
+ // If we're going to collapse the expand and our cursor is currently inside
105
+ // Move to a right gap cursor, if the toolbar is interacted (or an API),
106
+ // it will insert below rather than inside (which will be invisible).
107
+ if (isExpandedNext === true) {
108
+ tr.setSelection(new GapCursorSelection(tr.doc.resolve(pos + node.nodeSize), Side.RIGHT));
109
+ }
110
+
111
+ // log when people open/close expands
112
+ // TODO: ED-8523 make platform/mode global attributes?
113
+ const payload = {
114
+ action: ACTION.TOGGLE_EXPAND,
115
+ actionSubject: node.type === state.schema.nodes.expand ? ACTION_SUBJECT.EXPAND : ACTION_SUBJECT.NESTED_EXPAND,
116
+ attributes: {
117
+ platform: PLATFORMS.WEB,
118
+ mode: MODE.EDITOR,
119
+ expanded: isExpandedNext
120
+ },
121
+ eventType: EVENT_TYPE.TRACK
122
+ };
123
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 ? void 0 : editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
124
+ dispatch(tr);
125
+ }
126
+ return true;
127
+ };
86
128
  export const updateExpandTitle = ({
87
129
  title,
88
130
  nodeType,
@@ -1,13 +1,14 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import ReactDOM from 'react-dom';
3
3
  import { keyName } from 'w3c-keyname';
4
+ import { expandedState } from '@atlaskit/editor-common/expand';
4
5
  import { GapCursorSelection, RelativeSelectionPos, Side } from '@atlaskit/editor-common/selection';
5
6
  import { expandClassNames } from '@atlaskit/editor-common/styles';
6
7
  import { closestElement, isEmptyNode } from '@atlaskit/editor-common/utils';
7
8
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
8
9
  import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
9
- import { deleteExpand, setSelectionInsideExpand, updateExpandTitle } from '../commands';
10
- import { renderIcon, toDOM } from '../ui/NodeView';
10
+ import { deleteExpand, setSelectionInsideExpand, toggleExpandExpanded, updateExpandTitle } from '../commands';
11
+ import { buildExpandClassName, renderIcon, toDOM } from '../ui/NodeView';
11
12
  export class ExpandNodeView {
12
13
  constructor(node, view, getPos, getIntl, isMobile, selectNearNode, api, allowInteractiveExpand = true, __livePage = false) {
13
14
  _defineProperty(this, "allowInteractiveExpand", true);
@@ -54,6 +55,7 @@ export class ExpandNodeView {
54
55
  }
55
56
  const target = event.target;
56
57
  if (closestElement(target, `.${expandClassNames.icon}`)) {
58
+ var _this$api2, _this$api2$analytics;
57
59
  if (!this.allowInteractiveExpand) {
58
60
  return;
59
61
  }
@@ -64,10 +66,12 @@ export class ExpandNodeView {
64
66
  if (this.view.dom instanceof HTMLElement) {
65
67
  this.view.dom.blur();
66
68
  }
67
-
68
- // TODO https://product-fabric.atlassian.net/browse/ED-22841
69
- // call toggleExpandExpanded
70
-
69
+ toggleExpandExpanded({
70
+ editorAnalyticsAPI: (_this$api2 = this.api) === null || _this$api2 === void 0 ? void 0 : (_this$api2$analytics = _this$api2.analytics) === null || _this$api2$analytics === void 0 ? void 0 : _this$api2$analytics.actions,
71
+ pos,
72
+ node: this.node
73
+ })(this.view.state, this.view.dispatch);
74
+ this.updateExpandClassName();
71
75
  return;
72
76
  }
73
77
  if (target === this.input) {
@@ -105,7 +109,7 @@ export class ExpandNodeView {
105
109
  _defineProperty(this, "handleTitleKeydown", event => {
106
110
  switch (keyName(event)) {
107
111
  case 'Enter':
108
- // TO-DO
112
+ this.toggleExpand();
109
113
  break;
110
114
  case 'Tab':
111
115
  case 'ArrowDown':
@@ -141,8 +145,27 @@ export class ExpandNodeView {
141
145
  return;
142
146
  }
143
147
  if (expandNode && isEmptyNode(state.schema)(expandNode)) {
144
- var _this$api2, _this$api2$analytics;
145
- deleteExpand((_this$api2 = this.api) === null || _this$api2 === void 0 ? void 0 : (_this$api2$analytics = _this$api2.analytics) === null || _this$api2$analytics === void 0 ? void 0 : _this$api2$analytics.actions)(state, this.view.dispatch);
148
+ var _this$api3, _this$api3$analytics;
149
+ deleteExpand((_this$api3 = this.api) === null || _this$api3 === void 0 ? void 0 : (_this$api3$analytics = _this$api3.analytics) === null || _this$api3$analytics === void 0 ? void 0 : _this$api3$analytics.actions)(state, this.view.dispatch);
150
+ }
151
+ });
152
+ _defineProperty(this, "toggleExpand", () => {
153
+ const pos = this.getPos();
154
+ if (typeof pos !== 'number') {
155
+ return;
156
+ }
157
+ if (this.allowInteractiveExpand) {
158
+ var _this$api4, _this$api4$analytics;
159
+ const {
160
+ state,
161
+ dispatch
162
+ } = this.view;
163
+ toggleExpandExpanded({
164
+ editorAnalyticsAPI: (_this$api4 = this.api) === null || _this$api4 === void 0 ? void 0 : (_this$api4$analytics = _this$api4.analytics) === null || _this$api4$analytics === void 0 ? void 0 : _this$api4$analytics.actions,
165
+ pos,
166
+ node: this.node
167
+ })(state, dispatch);
168
+ this.updateExpandClassName();
146
169
  }
147
170
  });
148
171
  _defineProperty(this, "moveToOutsideOfTitle", event => {
@@ -174,9 +197,8 @@ export class ExpandNodeView {
174
197
  dispatch(state.tr.setSelection(sel));
175
198
  }
176
199
  });
177
- // TODO: https://product-fabric.atlassian.net/browse/ED-22841
178
200
  _defineProperty(this, "isCollapsed", () => {
179
- return false;
201
+ return !expandedState.get(this.node);
180
202
  });
181
203
  _defineProperty(this, "setRightGapCursor", event => {
182
204
  if (!this.input) {
@@ -265,14 +287,14 @@ export class ExpandNodeView {
265
287
  selectionEnd
266
288
  } = this.input;
267
289
  if (selectionStart === selectionEnd && selectionStart === 0) {
268
- var _this$api3, _this$api3$selection;
290
+ var _this$api5, _this$api5$selection;
269
291
  event.preventDefault();
270
292
  const {
271
293
  state,
272
294
  dispatch
273
295
  } = this.view;
274
296
  this.view.focus();
275
- const selectionSharedState = ((_this$api3 = this.api) === null || _this$api3 === void 0 ? void 0 : (_this$api3$selection = _this$api3.selection) === null || _this$api3$selection === void 0 ? void 0 : _this$api3$selection.sharedState.currentState()) || {};
297
+ const selectionSharedState = ((_this$api5 = this.api) === null || _this$api5 === void 0 ? void 0 : (_this$api5$selection = _this$api5.selection) === null || _this$api5$selection === void 0 ? void 0 : _this$api5$selection.sharedState.currentState()) || {};
276
298
  // selectionRelativeToNode is undefined when user clicked to select node, then hit left to get focus in title
277
299
  // This is a special case where we want to bypass node selection and jump straight to gap cursor
278
300
  if ((selectionSharedState === null || selectionSharedState === void 0 ? void 0 : selectionSharedState.selectionRelativeToNode) === undefined) {
@@ -297,14 +319,14 @@ export class ExpandNodeView {
297
319
  this.selectNearNode = selectNearNode;
298
320
  this.__livePage = __livePage;
299
321
  this.intl = getIntl();
300
- const {
301
- dom,
302
- contentDOM
303
- } = DOMSerializer.renderSpec(document, toDOM(node, this.__livePage, this.intl));
304
322
  this.allowInteractiveExpand = allowInteractiveExpand;
305
323
  this.getPos = getPos;
306
324
  this.view = view;
307
325
  this.node = node;
326
+ const {
327
+ dom,
328
+ contentDOM
329
+ } = DOMSerializer.renderSpec(document, toDOM(node, this.__livePage, this.intl));
308
330
  this.dom = dom;
309
331
  this.contentDOM = contentDOM;
310
332
  this.isMobile = isMobile;
@@ -313,6 +335,9 @@ export class ExpandNodeView {
313
335
  this.input = this.dom.querySelector(`.${expandClassNames.titleInput}`);
314
336
  this.titleContainer = this.dom.querySelector(`.${expandClassNames.titleContainer}`);
315
337
  renderIcon(this.icon, this.allowInteractiveExpand, this.intl);
338
+ if (!expandedState.has(this.node)) {
339
+ expandedState.set(this.node, false);
340
+ }
316
341
  if (!this.input || !this.titleContainer || !this.icon) {
317
342
  return;
318
343
  }
@@ -345,9 +370,6 @@ export class ExpandNodeView {
345
370
  }
346
371
  update(node, _decorations) {
347
372
  if (this.node.type === node.type) {
348
- // TODO: https://product-fabric.atlassian.net/browse/ED-22841
349
- // Handle toggling of the expand on update here
350
-
351
373
  // During a collab session the title doesn't sync with other users
352
374
  // since we're intentionally being less aggressive about re-rendering.
353
375
  // We also apply a rAF to avoid abrupt continuous replacement of the title.
@@ -356,11 +378,25 @@ export class ExpandNodeView {
356
378
  this.input.value = this.node.attrs.title;
357
379
  }
358
380
  });
381
+ if (this.node !== node) {
382
+ let previousExpandedState = expandedState.get(this.node);
383
+ if (previousExpandedState === undefined) {
384
+ previousExpandedState = true;
385
+ }
386
+ expandedState.set(node, previousExpandedState);
387
+ expandedState.delete(this.node);
388
+ }
359
389
  this.node = node;
360
390
  return true;
361
391
  }
362
392
  return false;
363
393
  }
394
+ updateExpandClassName() {
395
+ const expanded = expandedState.get(this.node) ? expandedState.get(this.node) : false;
396
+ if (this.dom && expanded !== undefined) {
397
+ this.dom.className = buildExpandClassName(this.node.type.name, expanded);
398
+ }
399
+ }
364
400
  destroy() {
365
401
  var _this$decorationClean2;
366
402
  if (!this.dom || !this.input || !this.titleContainer || !this.icon) {
@@ -374,6 +410,7 @@ export class ExpandNodeView {
374
410
  this.icon.removeEventListener('keydown', this.handleIconKeyDown);
375
411
  (_this$decorationClean2 = this.decorationCleanup) === null || _this$decorationClean2 === void 0 ? void 0 : _this$decorationClean2.call(this);
376
412
  ReactDOM.unmountComponentAtNode(this.icon);
413
+ expandedState.delete(this.node);
377
414
  }
378
415
  }
379
416
  export default function ({
@@ -22,7 +22,8 @@ export function expandKeymap(api, options) {
22
22
  nodeBefore
23
23
  } = selection.$from;
24
24
  if (selection instanceof GapCursorSelection && selection.side === Side.RIGHT && nodeBefore && (nodeBefore.type === schema.nodes.expand || nodeBefore.type === schema.nodes.nestedExpand)
25
- // TO-DO: add back in expanded logic
25
+ // https://product-fabric.atlassian.net/browse/ED-22991
26
+ // TODO: add back in expanded logic
26
27
  ) {
27
28
  const {
28
29
  $from
@@ -52,7 +53,8 @@ export function expandKeymap(api, options) {
52
53
  if (sel && expandBefore) {
53
54
  // moving cursor from outside of an expand to the title when it is collapsed
54
55
 
55
- // TO-DO: Bring back expanded logic
56
+ // https://product-fabric.atlassian.net/browse/ED-22991
57
+ // TODO: add back in expanded logic
56
58
  return focusTitle(expandBefore.start)(state, dispatch, editorView);
57
59
  }
58
60
  }
@@ -73,7 +75,8 @@ export function expandKeymap(api, options) {
73
75
  nodeAfter
74
76
  } = selection.$from;
75
77
  if (selection instanceof GapCursorSelection && selection.side === Side.LEFT && nodeAfter && (nodeAfter.type === expand || nodeAfter.type === nestedExpand)
76
- // TO-DO: Bring back expanded logic
78
+ // https://product-fabric.atlassian.net/browse/ED-22991
79
+ // TODO: add back in expanded logic
77
80
  ) {
78
81
  const {
79
82
  $from
@@ -114,7 +117,8 @@ export function expandKeymap(api, options) {
114
117
  const sel = Selection.findFrom(state.doc.resolve(Math.max(selection.$from.pos - 1, 0)), -1);
115
118
  const expandBefore = findExpand(state, sel);
116
119
  if (expandBefore && (expandBefore.node.type === expand || expandBefore.node.type === nestedExpand)
117
- // TO-DO: Bring back expanded logic
120
+ // https://product-fabric.atlassian.net/browse/ED-22991
121
+ // TODO: add back in expanded logic
118
122
  ) {
119
123
  return focusTitle(expandBefore.start)(state, dispatch, editorView);
120
124
  }
@@ -1,52 +1,57 @@
1
1
  import React from 'react';
2
2
  import ReactDOM from 'react-dom';
3
+ import { expandedState } from '@atlaskit/editor-common/expand';
3
4
  import { expandClassNames } from '@atlaskit/editor-common/styles';
4
5
  import { expandMessages } from '@atlaskit/editor-common/ui';
5
6
  import { ExpandButton } from '../ui/ExpandButton';
6
-
7
- // TODO: https://product-fabric.atlassian.net/browse/ED-22841
8
- export const buildExpandClassName = type => {
9
- return `${expandClassNames.prefix} ${expandClassNames.type(type)}
10
- ${expandClassNames.expanded}`;
7
+ export const buildExpandClassName = (type, expanded) => {
8
+ return `${expandClassNames.prefix} ${expandClassNames.type(type)} ${expanded ? expandClassNames.expanded : ''}`;
11
9
  };
12
- export const toDOM = (node, __livePage, intl) => ['div', {
10
+ export const toDOM = (node, __livePage, intl) => {
11
+ var _expandedState$get;
12
+ return ['div', {
13
+ // prettier-ignore
14
+ 'class': buildExpandClassName(node.type.name, (_expandedState$get = expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false),
15
+ 'data-node-type': node.type.name,
16
+ 'data-title': node.attrs.title
17
+ }, ['div', {
18
+ // prettier-ignore
19
+ 'class': expandClassNames.titleContainer,
20
+ contenteditable: 'false',
21
+ // Element gains access to focus events.
22
+ // This is needed to prevent PM gaining access
23
+ // on interacting with our controls.
24
+ tabindex: '-1'
25
+ },
13
26
  // prettier-ignore
14
- 'class': buildExpandClassName(node.type.name),
15
- 'data-node-type': node.type.name,
16
- 'data-title': node.attrs.title
17
- }, ['div', {
27
+ ['div', {
28
+ 'class': expandClassNames.icon
29
+ }], ['div', {
30
+ // prettier-ignore
31
+ 'class': expandClassNames.inputContainer
32
+ }, ['input', {
33
+ // prettier-ignore
34
+ 'class': expandClassNames.titleInput,
35
+ value: node.attrs.title,
36
+ placeholder: intl && typeof intl.formatMessage === 'function' && intl.formatMessage(expandMessages.expandPlaceholderText) || expandMessages.expandPlaceholderText.defaultMessage,
37
+ type: 'text'
38
+ }]]],
18
39
  // prettier-ignore
19
- 'class': expandClassNames.titleContainer,
20
- contenteditable: 'false',
21
- // Element gains access to focus events.
22
- // This is needed to prevent PM gaining access
23
- // on interacting with our controls.
24
- tabindex: '-1'
25
- },
26
- // prettier-ignore
27
- ['div', {
28
- 'class': expandClassNames.icon
29
- }], ['div', {
30
- // prettier-ignore
31
- 'class': expandClassNames.inputContainer
32
- }, ['input', {
33
- // prettier-ignore
34
- 'class': expandClassNames.titleInput,
35
- value: node.attrs.title,
36
- placeholder: intl && intl.formatMessage(expandMessages.expandPlaceholderText) || expandMessages.expandPlaceholderText.defaultMessage,
37
- type: 'text'
38
- }]]],
39
- // prettier-ignore
40
- ['div', {
41
- 'class': expandClassNames.content
42
- }, 0]];
40
+ ['div', {
41
+ 'class': expandClassNames.content
42
+ }, 0]];
43
+ };
43
44
  export const renderIcon = (icon, allowInteractiveExpand, intl, node) => {
44
45
  if (!icon) {
45
46
  return;
46
47
  }
48
+ let expanded = node ? expandedState.get(node) : true;
49
+ if (expanded === undefined) {
50
+ expanded = false;
51
+ }
47
52
  ReactDOM.render( /*#__PURE__*/React.createElement(ExpandButton, {
48
53
  intl: intl,
49
54
  allowInteractiveExpand: allowInteractiveExpand,
50
- expanded: true // TO-DO https://product-fabric.atlassian.net/browse/ED-22841
55
+ expanded: expanded
51
56
  }), icon);
52
57
  };
@@ -2,7 +2,9 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
4
  import { SetAttrsStep } from '@atlaskit/adf-schema/steps';
5
- import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD } from '@atlaskit/editor-common/analytics';
5
+ import { ACTION, ACTION_SUBJECT, ACTION_SUBJECT_ID, EVENT_TYPE, INPUT_METHOD, MODE, PLATFORMS } from '@atlaskit/editor-common/analytics';
6
+ import { expandedState } from '@atlaskit/editor-common/expand';
7
+ import { GapCursorSelection, Side } from '@atlaskit/editor-common/selection';
6
8
  import { findExpand } from '@atlaskit/editor-common/transforms';
7
9
  import { createWrapSelectionTransaction } from '@atlaskit/editor-common/utils';
8
10
  import { Selection } from '@atlaskit/editor-prosemirror/state';
@@ -15,7 +17,9 @@ export var createExpandNode = function createExpandNode(state) {
15
17
  expand = _state$schema$nodes.expand,
16
18
  nestedExpand = _state$schema$nodes.nestedExpand;
17
19
  var expandType = findTable(state.selection) ? nestedExpand : expand;
18
- return expandType.createAndFill({});
20
+ var expandNode = expandType.createAndFill({});
21
+ expandedState.set(expandNode, true);
22
+ return expandNode;
19
23
  };
20
24
  export var insertExpand = function insertExpand(editorAnalyticsAPI) {
21
25
  return function (state, dispatch) {
@@ -93,10 +97,47 @@ export var setSelectionInsideExpand = function setSelectionInsideExpand(expandPo
93
97
  return false;
94
98
  };
95
99
  };
96
- export var updateExpandTitle = function updateExpandTitle(_ref) {
97
- var title = _ref.title,
98
- nodeType = _ref.nodeType,
99
- pos = _ref.pos;
100
+ export var toggleExpandExpanded = function toggleExpandExpanded(_ref) {
101
+ var editorAnalyticsAPI = _ref.editorAnalyticsAPI,
102
+ pos = _ref.pos,
103
+ node = _ref.node;
104
+ return function (state, dispatch) {
105
+ if (node && dispatch) {
106
+ var _expandedState$get;
107
+ var tr = state.tr;
108
+ var expanded = (_expandedState$get = expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false;
109
+ var isExpandedNext = !expanded;
110
+ expandedState.set(node, isExpandedNext);
111
+
112
+ // If we're going to collapse the expand and our cursor is currently inside
113
+ // Move to a right gap cursor, if the toolbar is interacted (or an API),
114
+ // it will insert below rather than inside (which will be invisible).
115
+ if (isExpandedNext === true) {
116
+ tr.setSelection(new GapCursorSelection(tr.doc.resolve(pos + node.nodeSize), Side.RIGHT));
117
+ }
118
+
119
+ // log when people open/close expands
120
+ // TODO: ED-8523 make platform/mode global attributes?
121
+ var payload = {
122
+ action: ACTION.TOGGLE_EXPAND,
123
+ actionSubject: node.type === state.schema.nodes.expand ? ACTION_SUBJECT.EXPAND : ACTION_SUBJECT.NESTED_EXPAND,
124
+ attributes: {
125
+ platform: PLATFORMS.WEB,
126
+ mode: MODE.EDITOR,
127
+ expanded: isExpandedNext
128
+ },
129
+ eventType: EVENT_TYPE.TRACK
130
+ };
131
+ editorAnalyticsAPI === null || editorAnalyticsAPI === void 0 || editorAnalyticsAPI.attachAnalyticsEvent(payload)(tr);
132
+ dispatch(tr);
133
+ }
134
+ return true;
135
+ };
136
+ };
137
+ export var updateExpandTitle = function updateExpandTitle(_ref2) {
138
+ var title = _ref2.title,
139
+ nodeType = _ref2.nodeType,
140
+ pos = _ref2.pos;
100
141
  return function (state, dispatch) {
101
142
  var node = state.doc.nodeAt(pos);
102
143
  if (node && node.type === nodeType && dispatch) {
@@ -3,13 +3,14 @@ import _createClass from "@babel/runtime/helpers/createClass";
3
3
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
4
  import ReactDOM from 'react-dom';
5
5
  import { keyName } from 'w3c-keyname';
6
+ import { expandedState } from '@atlaskit/editor-common/expand';
6
7
  import { GapCursorSelection, RelativeSelectionPos, Side } from '@atlaskit/editor-common/selection';
7
8
  import { expandClassNames } from '@atlaskit/editor-common/styles';
8
9
  import { closestElement, isEmptyNode } from '@atlaskit/editor-common/utils';
9
10
  import { DOMSerializer } from '@atlaskit/editor-prosemirror/model';
10
11
  import { NodeSelection, Selection } from '@atlaskit/editor-prosemirror/state';
11
- import { deleteExpand, setSelectionInsideExpand, updateExpandTitle } from '../commands';
12
- import { renderIcon, toDOM } from '../ui/NodeView';
12
+ import { deleteExpand, setSelectionInsideExpand, toggleExpandExpanded, updateExpandTitle } from '../commands';
13
+ import { buildExpandClassName, renderIcon, toDOM } from '../ui/NodeView';
13
14
  export var ExpandNodeView = /*#__PURE__*/function () {
14
15
  function ExpandNodeView(node, view, getPos, getIntl, isMobile, selectNearNode, api) {
15
16
  var _this = this;
@@ -59,6 +60,7 @@ export var ExpandNodeView = /*#__PURE__*/function () {
59
60
  }
60
61
  var target = event.target;
61
62
  if (closestElement(target, ".".concat(expandClassNames.icon))) {
63
+ var _this$api2;
62
64
  if (!_this.allowInteractiveExpand) {
63
65
  return;
64
66
  }
@@ -69,10 +71,12 @@ export var ExpandNodeView = /*#__PURE__*/function () {
69
71
  if (_this.view.dom instanceof HTMLElement) {
70
72
  _this.view.dom.blur();
71
73
  }
72
-
73
- // TODO https://product-fabric.atlassian.net/browse/ED-22841
74
- // call toggleExpandExpanded
75
-
74
+ toggleExpandExpanded({
75
+ editorAnalyticsAPI: (_this$api2 = _this.api) === null || _this$api2 === void 0 || (_this$api2 = _this$api2.analytics) === null || _this$api2 === void 0 ? void 0 : _this$api2.actions,
76
+ pos: pos,
77
+ node: _this.node
78
+ })(_this.view.state, _this.view.dispatch);
79
+ _this.updateExpandClassName();
76
80
  return;
77
81
  }
78
82
  if (target === _this.input) {
@@ -109,7 +113,7 @@ export var ExpandNodeView = /*#__PURE__*/function () {
109
113
  _defineProperty(this, "handleTitleKeydown", function (event) {
110
114
  switch (keyName(event)) {
111
115
  case 'Enter':
112
- // TO-DO
116
+ _this.toggleExpand();
113
117
  break;
114
118
  case 'Tab':
115
119
  case 'ArrowDown':
@@ -142,15 +146,33 @@ export var ExpandNodeView = /*#__PURE__*/function () {
142
146
  return;
143
147
  }
144
148
  if (expandNode && isEmptyNode(state.schema)(expandNode)) {
145
- var _this$api2;
146
- deleteExpand((_this$api2 = _this.api) === null || _this$api2 === void 0 || (_this$api2 = _this$api2.analytics) === null || _this$api2 === void 0 ? void 0 : _this$api2.actions)(state, _this.view.dispatch);
149
+ var _this$api3;
150
+ deleteExpand((_this$api3 = _this.api) === null || _this$api3 === void 0 || (_this$api3 = _this$api3.analytics) === null || _this$api3 === void 0 ? void 0 : _this$api3.actions)(state, _this.view.dispatch);
151
+ }
152
+ });
153
+ _defineProperty(this, "toggleExpand", function () {
154
+ var pos = _this.getPos();
155
+ if (typeof pos !== 'number') {
156
+ return;
157
+ }
158
+ if (_this.allowInteractiveExpand) {
159
+ var _this$api4;
160
+ var _this$view3 = _this.view,
161
+ state = _this$view3.state,
162
+ dispatch = _this$view3.dispatch;
163
+ toggleExpandExpanded({
164
+ editorAnalyticsAPI: (_this$api4 = _this.api) === null || _this$api4 === void 0 || (_this$api4 = _this$api4.analytics) === null || _this$api4 === void 0 ? void 0 : _this$api4.actions,
165
+ pos: pos,
166
+ node: _this.node
167
+ })(state, dispatch);
168
+ _this.updateExpandClassName();
147
169
  }
148
170
  });
149
171
  _defineProperty(this, "moveToOutsideOfTitle", function (event) {
150
172
  event.preventDefault();
151
- var _this$view3 = _this.view,
152
- state = _this$view3.state,
153
- dispatch = _this$view3.dispatch;
173
+ var _this$view4 = _this.view,
174
+ state = _this$view4.state,
175
+ dispatch = _this$view4.dispatch;
154
176
  var expandPos = _this.getPos();
155
177
  if (typeof expandPos !== 'number') {
156
178
  return;
@@ -174,9 +196,8 @@ export var ExpandNodeView = /*#__PURE__*/function () {
174
196
  dispatch(state.tr.setSelection(sel));
175
197
  }
176
198
  });
177
- // TODO: https://product-fabric.atlassian.net/browse/ED-22841
178
199
  _defineProperty(this, "isCollapsed", function () {
179
- return false;
200
+ return !expandedState.get(_this.node);
180
201
  });
181
202
  _defineProperty(this, "setRightGapCursor", function (event) {
182
203
  if (!_this.input) {
@@ -191,9 +212,9 @@ export var ExpandNodeView = /*#__PURE__*/function () {
191
212
  selectionStart = _this$input2.selectionStart,
192
213
  selectionEnd = _this$input2.selectionEnd;
193
214
  if (selectionStart === selectionEnd && selectionStart === value.length) {
194
- var _this$view4 = _this.view,
195
- state = _this$view4.state,
196
- dispatch = _this$view4.dispatch;
215
+ var _this$view5 = _this.view,
216
+ state = _this$view5.state,
217
+ dispatch = _this$view5.dispatch;
197
218
  event.preventDefault();
198
219
  _this.view.focus();
199
220
  dispatch(state.tr.setSelection(new GapCursorSelection(state.doc.resolve(_this.node.nodeSize + pos), Side.RIGHT)));
@@ -212,9 +233,9 @@ export var ExpandNodeView = /*#__PURE__*/function () {
212
233
  selectionEnd = _this$input3.selectionEnd;
213
234
  if (selectionStart === selectionEnd && selectionStart === 0) {
214
235
  event.preventDefault();
215
- var _this$view5 = _this.view,
216
- state = _this$view5.state,
217
- dispatch = _this$view5.dispatch;
236
+ var _this$view6 = _this.view,
237
+ state = _this$view6.state,
238
+ dispatch = _this$view6.dispatch;
218
239
  _this.view.focus();
219
240
  dispatch(state.tr.setSelection(new GapCursorSelection(state.doc.resolve(pos), Side.LEFT)));
220
241
  }
@@ -233,9 +254,9 @@ export var ExpandNodeView = /*#__PURE__*/function () {
233
254
  selectionEnd = _this$input4.selectionEnd;
234
255
  if (selectionStart === selectionEnd && selectionStart === value.length) {
235
256
  event.preventDefault();
236
- var _this$view6 = _this.view,
237
- state = _this$view6.state,
238
- dispatch = _this$view6.dispatch;
257
+ var _this$view7 = _this.view,
258
+ state = _this$view7.state,
259
+ dispatch = _this$view7.dispatch;
239
260
  _this.view.focus();
240
261
  var tr = _this.selectNearNode({
241
262
  selectionRelativeToNode: RelativeSelectionPos.End,
@@ -258,13 +279,13 @@ export var ExpandNodeView = /*#__PURE__*/function () {
258
279
  selectionStart = _this$input5.selectionStart,
259
280
  selectionEnd = _this$input5.selectionEnd;
260
281
  if (selectionStart === selectionEnd && selectionStart === 0) {
261
- var _this$api3;
282
+ var _this$api5;
262
283
  event.preventDefault();
263
- var _this$view7 = _this.view,
264
- state = _this$view7.state,
265
- dispatch = _this$view7.dispatch;
284
+ var _this$view8 = _this.view,
285
+ state = _this$view8.state,
286
+ dispatch = _this$view8.dispatch;
266
287
  _this.view.focus();
267
- var selectionSharedState = ((_this$api3 = _this.api) === null || _this$api3 === void 0 || (_this$api3 = _this$api3.selection) === null || _this$api3 === void 0 ? void 0 : _this$api3.sharedState.currentState()) || {};
288
+ var selectionSharedState = ((_this$api5 = _this.api) === null || _this$api5 === void 0 || (_this$api5 = _this$api5.selection) === null || _this$api5 === void 0 ? void 0 : _this$api5.sharedState.currentState()) || {};
268
289
  // selectionRelativeToNode is undefined when user clicked to select node, then hit left to get focus in title
269
290
  // This is a special case where we want to bypass node selection and jump straight to gap cursor
270
291
  if ((selectionSharedState === null || selectionSharedState === void 0 ? void 0 : selectionSharedState.selectionRelativeToNode) === undefined) {
@@ -289,13 +310,13 @@ export var ExpandNodeView = /*#__PURE__*/function () {
289
310
  this.selectNearNode = selectNearNode;
290
311
  this.__livePage = __livePage;
291
312
  this.intl = getIntl();
292
- var _DOMSerializer$render = DOMSerializer.renderSpec(document, toDOM(node, this.__livePage, this.intl)),
293
- dom = _DOMSerializer$render.dom,
294
- contentDOM = _DOMSerializer$render.contentDOM;
295
313
  this.allowInteractiveExpand = allowInteractiveExpand;
296
314
  this.getPos = getPos;
297
315
  this.view = view;
298
316
  this.node = node;
317
+ var _DOMSerializer$render = DOMSerializer.renderSpec(document, toDOM(node, this.__livePage, this.intl)),
318
+ dom = _DOMSerializer$render.dom,
319
+ contentDOM = _DOMSerializer$render.contentDOM;
299
320
  this.dom = dom;
300
321
  this.contentDOM = contentDOM;
301
322
  this.isMobile = isMobile;
@@ -304,6 +325,9 @@ export var ExpandNodeView = /*#__PURE__*/function () {
304
325
  this.input = this.dom.querySelector(".".concat(expandClassNames.titleInput));
305
326
  this.titleContainer = this.dom.querySelector(".".concat(expandClassNames.titleContainer));
306
327
  renderIcon(this.icon, this.allowInteractiveExpand, this.intl);
328
+ if (!expandedState.has(this.node)) {
329
+ expandedState.set(this.node, false);
330
+ }
307
331
  if (!this.input || !this.titleContainer || !this.icon) {
308
332
  return;
309
333
  }
@@ -343,9 +367,6 @@ export var ExpandNodeView = /*#__PURE__*/function () {
343
367
  value: function update(node, _decorations) {
344
368
  var _this2 = this;
345
369
  if (this.node.type === node.type) {
346
- // TODO: https://product-fabric.atlassian.net/browse/ED-22841
347
- // Handle toggling of the expand on update here
348
-
349
370
  // During a collab session the title doesn't sync with other users
350
371
  // since we're intentionally being less aggressive about re-rendering.
351
372
  // We also apply a rAF to avoid abrupt continuous replacement of the title.
@@ -354,11 +375,27 @@ export var ExpandNodeView = /*#__PURE__*/function () {
354
375
  _this2.input.value = _this2.node.attrs.title;
355
376
  }
356
377
  });
378
+ if (this.node !== node) {
379
+ var previousExpandedState = expandedState.get(this.node);
380
+ if (previousExpandedState === undefined) {
381
+ previousExpandedState = true;
382
+ }
383
+ expandedState.set(node, previousExpandedState);
384
+ expandedState.delete(this.node);
385
+ }
357
386
  this.node = node;
358
387
  return true;
359
388
  }
360
389
  return false;
361
390
  }
391
+ }, {
392
+ key: "updateExpandClassName",
393
+ value: function updateExpandClassName() {
394
+ var expanded = expandedState.get(this.node) ? expandedState.get(this.node) : false;
395
+ if (this.dom && expanded !== undefined) {
396
+ this.dom.className = buildExpandClassName(this.node.type.name, expanded);
397
+ }
398
+ }
362
399
  }, {
363
400
  key: "destroy",
364
401
  value: function destroy() {
@@ -374,6 +411,7 @@ export var ExpandNodeView = /*#__PURE__*/function () {
374
411
  this.icon.removeEventListener('keydown', this.handleIconKeyDown);
375
412
  (_this$decorationClean2 = this.decorationCleanup) === null || _this$decorationClean2 === void 0 || _this$decorationClean2.call(this);
376
413
  ReactDOM.unmountComponentAtNode(this.icon);
414
+ expandedState.delete(this.node);
377
415
  }
378
416
  }]);
379
417
  return ExpandNodeView;
@@ -18,7 +18,8 @@ export function expandKeymap(api, options) {
18
18
  schema = state.schema;
19
19
  var nodeBefore = selection.$from.nodeBefore;
20
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
21
+ // https://product-fabric.atlassian.net/browse/ED-22991
22
+ // TODO: add back in expanded logic
22
23
  ) {
23
24
  var _$from = selection.$from;
24
25
  return focusTitle(Math.max(_$from.pos - 1, 0))(state, dispatch, editorView);
@@ -44,7 +45,8 @@ export function expandKeymap(api, options) {
44
45
  if (sel && expandBefore) {
45
46
  // moving cursor from outside of an expand to the title when it is collapsed
46
47
 
47
- // TO-DO: Bring back expanded logic
48
+ // https://product-fabric.atlassian.net/browse/ED-22991
49
+ // TODO: add back in expanded logic
48
50
  return focusTitle(expandBefore.start)(state, dispatch, editorView);
49
51
  }
50
52
  }
@@ -60,7 +62,8 @@ export function expandKeymap(api, options) {
60
62
  var selection = state.selection;
61
63
  var nodeAfter = selection.$from.nodeAfter;
62
64
  if (selection instanceof GapCursorSelection && selection.side === Side.LEFT && nodeAfter && (nodeAfter.type === expand || nodeAfter.type === nestedExpand)
63
- // TO-DO: Bring back expanded logic
65
+ // https://product-fabric.atlassian.net/browse/ED-22991
66
+ // TODO: add back in expanded logic
64
67
  ) {
65
68
  var $from = selection.$from;
66
69
  return focusTitle($from.pos + 1)(state, dispatch, editorView);
@@ -92,7 +95,8 @@ export function expandKeymap(api, options) {
92
95
  var sel = Selection.findFrom(state.doc.resolve(Math.max(selection.$from.pos - 1, 0)), -1);
93
96
  var expandBefore = findExpand(state, sel);
94
97
  if (expandBefore && (expandBefore.node.type === expand || expandBefore.node.type === nestedExpand)
95
- // TO-DO: Bring back expanded logic
98
+ // https://product-fabric.atlassian.net/browse/ED-22991
99
+ // TODO: add back in expanded logic
96
100
  ) {
97
101
  return focusTitle(expandBefore.start)(state, dispatch, editorView);
98
102
  }
@@ -1,17 +1,17 @@
1
1
  import React from 'react';
2
2
  import ReactDOM from 'react-dom';
3
+ import { expandedState } from '@atlaskit/editor-common/expand';
3
4
  import { expandClassNames } from '@atlaskit/editor-common/styles';
4
5
  import { expandMessages } from '@atlaskit/editor-common/ui';
5
6
  import { ExpandButton } from '../ui/ExpandButton';
6
-
7
- // TODO: https://product-fabric.atlassian.net/browse/ED-22841
8
- export var buildExpandClassName = function buildExpandClassName(type) {
9
- return "".concat(expandClassNames.prefix, " ").concat(expandClassNames.type(type), "\n ").concat(expandClassNames.expanded);
7
+ export var buildExpandClassName = function buildExpandClassName(type, expanded) {
8
+ return "".concat(expandClassNames.prefix, " ").concat(expandClassNames.type(type), " ").concat(expanded ? expandClassNames.expanded : '');
10
9
  };
11
10
  export var toDOM = function toDOM(node, __livePage, intl) {
11
+ var _expandedState$get;
12
12
  return ['div', {
13
13
  // prettier-ignore
14
- 'class': buildExpandClassName(node.type.name),
14
+ 'class': buildExpandClassName(node.type.name, (_expandedState$get = expandedState.get(node)) !== null && _expandedState$get !== void 0 ? _expandedState$get : false),
15
15
  'data-node-type': node.type.name,
16
16
  'data-title': node.attrs.title
17
17
  }, ['div', {
@@ -33,7 +33,7 @@ export var toDOM = function toDOM(node, __livePage, intl) {
33
33
  // prettier-ignore
34
34
  'class': expandClassNames.titleInput,
35
35
  value: node.attrs.title,
36
- placeholder: intl && intl.formatMessage(expandMessages.expandPlaceholderText) || expandMessages.expandPlaceholderText.defaultMessage,
36
+ placeholder: intl && typeof intl.formatMessage === 'function' && intl.formatMessage(expandMessages.expandPlaceholderText) || expandMessages.expandPlaceholderText.defaultMessage,
37
37
  type: 'text'
38
38
  }]]],
39
39
  // prettier-ignore
@@ -45,9 +45,13 @@ export var renderIcon = function renderIcon(icon, allowInteractiveExpand, intl,
45
45
  if (!icon) {
46
46
  return;
47
47
  }
48
+ var expanded = node ? expandedState.get(node) : true;
49
+ if (expanded === undefined) {
50
+ expanded = false;
51
+ }
48
52
  ReactDOM.render( /*#__PURE__*/React.createElement(ExpandButton, {
49
53
  intl: intl,
50
54
  allowInteractiveExpand: allowInteractiveExpand,
51
- expanded: true // TO-DO https://product-fabric.atlassian.net/browse/ED-22841
55
+ expanded: expanded
52
56
  }), icon);
53
57
  };
@@ -7,6 +7,11 @@ export declare const insertExpand: (editorAnalyticsAPI: EditorAnalyticsAPI | und
7
7
  export declare const deleteExpand: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => Command;
8
8
  export declare const deleteExpandAtPos: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (expandNodePos: number, expandNode: PMNode) => Command;
9
9
  export declare const setSelectionInsideExpand: (expandPos: number) => Command;
10
+ export declare const toggleExpandExpanded: ({ editorAnalyticsAPI, pos, node, }: {
11
+ editorAnalyticsAPI: EditorAnalyticsAPI | undefined;
12
+ pos: number;
13
+ node: PMNode;
14
+ }) => Command;
10
15
  export declare const updateExpandTitle: ({ title, nodeType, pos, }: {
11
16
  title: string;
12
17
  pos: number;
@@ -30,6 +30,7 @@ export declare class ExpandNodeView implements NodeView {
30
30
  private handleBlur;
31
31
  private handleTitleKeydown;
32
32
  private deleteEmptyExpand;
33
+ private toggleExpand;
33
34
  private moveToOutsideOfTitle;
34
35
  private isCollapsed;
35
36
  private setRightGapCursor;
@@ -42,6 +43,7 @@ export declare class ExpandNodeView implements NodeView {
42
43
  target: Element;
43
44
  }): boolean;
44
45
  update(node: PmNode, _decorations: readonly Decoration[]): boolean;
46
+ updateExpandClassName(): void;
45
47
  destroy(): void;
46
48
  }
47
49
  export default function ({ getIntl, isMobile, api, allowInteractiveExpand, __livePage, }: {
@@ -1,5 +1,5 @@
1
1
  import type { IntlShape } from 'react-intl-next';
2
2
  import type { DOMOutputSpec, Node as PmNode } from '@atlaskit/editor-prosemirror/model';
3
- export declare const buildExpandClassName: (type: string) => string;
3
+ export declare const buildExpandClassName: (type: string, expanded: boolean) => string;
4
4
  export declare const toDOM: (node: PmNode, __livePage: boolean, intl?: IntlShape) => DOMOutputSpec;
5
5
  export declare const renderIcon: (icon: HTMLElement | null, allowInteractiveExpand: boolean, intl?: IntlShape, node?: PmNode) => void;
@@ -7,6 +7,11 @@ export declare const insertExpand: (editorAnalyticsAPI: EditorAnalyticsAPI | und
7
7
  export declare const deleteExpand: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => Command;
8
8
  export declare const deleteExpandAtPos: (editorAnalyticsAPI: EditorAnalyticsAPI | undefined) => (expandNodePos: number, expandNode: PMNode) => Command;
9
9
  export declare const setSelectionInsideExpand: (expandPos: number) => Command;
10
+ export declare const toggleExpandExpanded: ({ editorAnalyticsAPI, pos, node, }: {
11
+ editorAnalyticsAPI: EditorAnalyticsAPI | undefined;
12
+ pos: number;
13
+ node: PMNode;
14
+ }) => Command;
10
15
  export declare const updateExpandTitle: ({ title, nodeType, pos, }: {
11
16
  title: string;
12
17
  pos: number;
@@ -30,6 +30,7 @@ export declare class ExpandNodeView implements NodeView {
30
30
  private handleBlur;
31
31
  private handleTitleKeydown;
32
32
  private deleteEmptyExpand;
33
+ private toggleExpand;
33
34
  private moveToOutsideOfTitle;
34
35
  private isCollapsed;
35
36
  private setRightGapCursor;
@@ -42,6 +43,7 @@ export declare class ExpandNodeView implements NodeView {
42
43
  target: Element;
43
44
  }): boolean;
44
45
  update(node: PmNode, _decorations: readonly Decoration[]): boolean;
46
+ updateExpandClassName(): void;
45
47
  destroy(): void;
46
48
  }
47
49
  export default function ({ getIntl, isMobile, api, allowInteractiveExpand, __livePage, }: {
@@ -1,5 +1,5 @@
1
1
  import type { IntlShape } from 'react-intl-next';
2
2
  import type { DOMOutputSpec, Node as PmNode } from '@atlaskit/editor-prosemirror/model';
3
- export declare const buildExpandClassName: (type: string) => string;
3
+ export declare const buildExpandClassName: (type: string, expanded: boolean) => string;
4
4
  export declare const toDOM: (node: PmNode, __livePage: boolean, intl?: IntlShape) => DOMOutputSpec;
5
5
  export declare const renderIcon: (icon: HTMLElement | null, allowInteractiveExpand: boolean, intl?: IntlShape, node?: PmNode) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-expand",
3
- "version": "1.4.0",
3
+ "version": "1.4.1",
4
4
  "description": "Expand plugin for @atlaskit/editor-core",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -35,7 +35,7 @@
35
35
  "dependencies": {
36
36
  "@atlaskit/adf-schema": "^35.9.0",
37
37
  "@atlaskit/button": "^17.12.0",
38
- "@atlaskit/editor-common": "^78.28.0",
38
+ "@atlaskit/editor-common": "^78.29.0",
39
39
  "@atlaskit/editor-plugin-analytics": "^1.0.0",
40
40
  "@atlaskit/editor-plugin-decorations": "^1.0.0",
41
41
  "@atlaskit/editor-plugin-selection": "^1.1.0",