@atlaskit/editor-plugin-selection 0.2.2 → 1.0.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,17 @@
1
1
  # @atlaskit/editor-plugin-selection
2
2
 
3
+ ## 1.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#70261](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/70261) [`a92879d672c6`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a92879d672c6) - [ux] ED-21620: Corrected the selection functions for atom nodes that are triggered on pressing the right and left arrow keys.
8
+
9
+ ## 1.0.0
10
+
11
+ ### Major Changes
12
+
13
+ - [#72386](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/72386) [`0c52b0be40c1`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/0c52b0be40c1) - This changeset exists to bump all editor plugins that currently don't have a major version. This is to address an issue with Jira plugin consumption.
14
+
3
15
  ## 0.2.2
4
16
 
5
17
  ### Patch Changes
@@ -7,11 +7,14 @@ exports.setSelectionRelativeToNode = exports.setSelectionInsideAtNodeEnd = expor
7
7
  var _selection = require("@atlaskit/editor-common/selection");
8
8
  var _utils = require("@atlaskit/editor-common/utils");
9
9
  var _state = require("@atlaskit/editor-prosemirror/state");
10
+ var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
10
11
  var _actions = require("./actions");
11
12
  var _gapCursorSelection = require("./gap-cursor-selection");
12
13
  var _pluginFactory = require("./plugin-factory");
13
14
  var _types = require("./types");
14
15
  var _utils2 = require("./utils");
16
+ /* eslint-disable import/no-extraneous-dependencies */
17
+
15
18
  var selectNearNode = exports.selectNearNode = function selectNearNode(selectionRelativeToNode, selection) {
16
19
  return function (_ref) {
17
20
  var tr = _ref.tr;
@@ -117,6 +120,25 @@ var arrowRightFromNode = function arrowRightFromNode(selection) {
117
120
  $to = selection.$to;
118
121
  var _getPluginState2 = (0, _pluginFactory.getPluginState)(state),
119
122
  selectionRelativeToNode = _getPluginState2.selectionRelativeToNode;
123
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.change-navigation-for-atom-nodes')) {
124
+ if (node.isAtom) {
125
+ if ((0, _utils2.isSelectionAtEndOfParentNode)($to, selection) && (node.isInline || (0, _selection.isIgnored)(node))) {
126
+ // selection is for inline node or atom node which is ignored by gap-cursor and that is the last child of its parent node - set text selection after it
127
+ return findAndSetTextSelection(_types.RelativeSelectionPos.End, state.doc.resolve(from + 1), _types.SelectionDirection.After)(state, dispatch);
128
+ }
129
+ return false;
130
+ } else if (selectionRelativeToNode === _types.RelativeSelectionPos.Start) {
131
+ // selection is for container node - set selection inside it at the start
132
+ return setSelectionInsideAtNodeStart(_types.RelativeSelectionPos.Inside, node, from)(state, dispatch);
133
+ } else if ((0, _selection.isIgnored)(node) && (!selectionRelativeToNode || selectionRelativeToNode === _types.RelativeSelectionPos.End)) {
134
+ var selectableNode = (0, _utils2.findSelectableContainerAfter)($to, state.doc);
135
+ if (selectableNode && (0, _selection.isIgnored)(selectableNode.node)) {
136
+ // selection is for node without gap cursor followed by another node without gap cursor - set node selection for next node
137
+ return setSelectionRelativeToNode(_types.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
138
+ }
139
+ }
140
+ return false;
141
+ }
120
142
  if (node.isAtom) {
121
143
  if ((0, _utils2.isSelectionAtEndOfParentNode)($to, selection)) {
122
144
  // selection is for inline node that is the last child of its parent node - set text selection after it
@@ -127,10 +149,10 @@ var arrowRightFromNode = function arrowRightFromNode(selection) {
127
149
  // selection is for container node - set selection inside it at the start
128
150
  return setSelectionInsideAtNodeStart(_types.RelativeSelectionPos.Inside, node, from)(state, dispatch);
129
151
  } else if ((0, _selection.isIgnored)(node) && (!selectionRelativeToNode || selectionRelativeToNode === _types.RelativeSelectionPos.End)) {
130
- var selectableNode = (0, _utils2.findSelectableContainerAfter)($to, state.doc);
131
- if (selectableNode && (0, _selection.isIgnored)(selectableNode.node)) {
152
+ var _selectableNode4 = (0, _utils2.findSelectableContainerAfter)($to, state.doc);
153
+ if (_selectableNode4 && (0, _selection.isIgnored)(_selectableNode4.node)) {
132
154
  // selection is for node without gap cursor followed by another node without gap cursor - set node selection for next node
133
- return setSelectionRelativeToNode(_types.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
155
+ return setSelectionRelativeToNode(_types.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, _selectableNode4.pos))(state, dispatch);
134
156
  }
135
157
  }
136
158
  return false;
@@ -144,6 +166,29 @@ var arrowLeftFromNode = function arrowLeftFromNode(selection) {
144
166
  $from = selection.$from;
145
167
  var _getPluginState3 = (0, _pluginFactory.getPluginState)(state),
146
168
  selectionRelativeToNode = _getPluginState3.selectionRelativeToNode;
169
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.change-navigation-for-atom-nodes')) {
170
+ if (node.isAtom) {
171
+ if ((0, _utils2.isSelectionAtStartOfParentNode)($from, selection) && (node.isInline || (0, _selection.isIgnored)(node))) {
172
+ // selection is for inline node or atom node which is ignored by gap-cursor and that is the first child of its parent node - set text selection before it
173
+ return findAndSetTextSelection(_types.RelativeSelectionPos.Start, state.doc.resolve(from), _types.SelectionDirection.Before)(state, dispatch);
174
+ }
175
+ return false;
176
+ } else if (selectionRelativeToNode === _types.RelativeSelectionPos.End) {
177
+ // selection is for container node - set selection inside it at the end
178
+ return setSelectionInsideAtNodeEnd(_types.RelativeSelectionPos.Inside, node, from, to)(state, dispatch);
179
+ } else if (!selectionRelativeToNode || selectionRelativeToNode === _types.RelativeSelectionPos.Inside) {
180
+ // selection is for container node - set selection inside it at the start
181
+ // (this is a special case when the user selects by clicking node)
182
+ return setSelectionInsideAtNodeStart(_types.RelativeSelectionPos.Before, node, from)(state, dispatch);
183
+ } else if ((0, _selection.isIgnored)(node) && selectionRelativeToNode === _types.RelativeSelectionPos.Start) {
184
+ // selection is for node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
185
+ var selectableNode = (0, _utils2.findSelectableContainerBefore)($from, state.doc);
186
+ if (selectableNode && (0, _selection.isIgnored)(selectableNode.node)) {
187
+ return setSelectionRelativeToNode(_types.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
188
+ }
189
+ }
190
+ return false;
191
+ }
147
192
  if (node.isAtom) {
148
193
  if ((0, _utils2.isSelectionAtStartOfParentNode)($from, selection)) {
149
194
  // selection is for inline node that is the first child of its parent node - set text selection before it
@@ -159,9 +204,9 @@ var arrowLeftFromNode = function arrowLeftFromNode(selection) {
159
204
  return setSelectionInsideAtNodeStart(_types.RelativeSelectionPos.Before, node, from)(state, dispatch);
160
205
  } else if ((0, _selection.isIgnored)(node) && selectionRelativeToNode === _types.RelativeSelectionPos.Start) {
161
206
  // selection is for node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
162
- var selectableNode = (0, _utils2.findSelectableContainerBefore)($from, state.doc);
163
- if (selectableNode && (0, _selection.isIgnored)(selectableNode.node)) {
164
- return setSelectionRelativeToNode(_types.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
207
+ var _selectableNode5 = (0, _utils2.findSelectableContainerBefore)($from, state.doc);
208
+ if (_selectableNode5 && (0, _selection.isIgnored)(_selectableNode5.node)) {
209
+ return setSelectionRelativeToNode(_types.RelativeSelectionPos.End, _state.NodeSelection.create(state.doc, _selectableNode5.pos))(state, dispatch);
165
210
  }
166
211
  }
167
212
  return false;
@@ -192,9 +237,9 @@ var arrowLeftFromText = function arrowLeftFromText(selection) {
192
237
  // from responding to arrow left key
193
238
  setSelectionRelativeToNode(undefined)(state, dispatch);
194
239
  } else if ((0, _utils2.isSelectionAtStartOfParentNode)(selection.$from, selection)) {
195
- var _selectableNode4 = (0, _utils2.findSelectableContainerParent)(selection);
196
- if (_selectableNode4) {
197
- return setSelectionRelativeToNode(_types.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, _selectableNode4.pos))(state, dispatch);
240
+ var _selectableNode6 = (0, _utils2.findSelectableContainerParent)(selection);
241
+ if (_selectableNode6) {
242
+ return setSelectionRelativeToNode(_types.RelativeSelectionPos.Start, _state.NodeSelection.create(state.doc, _selectableNode6.pos))(state, dispatch);
198
243
  }
199
244
  }
200
245
  return false;
@@ -215,18 +260,36 @@ var setSelectionInsideAtNodeStart = function setSelectionInsideAtNodeStart(selec
215
260
  return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(pos), _types.SelectionDirection.After)(state, dispatch);
216
261
  }
217
262
  var selectableNode = (0, _utils2.findFirstChildNodeToSelect)(node);
263
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.change-navigation-for-atom-nodes')) {
264
+ if (selectableNode) {
265
+ var childNode = selectableNode.node,
266
+ childPos = selectableNode.pos;
267
+ var selectionPos = pos + childPos + 1;
268
+ if (childNode.isText || childNode.isAtom && (0, _selection.isIgnored)(childNode) || childNode.isInline) {
269
+ //selection is for text node, inline node or atom node which is ignored by gap-cursor. set selection before it.
270
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), _types.SelectionDirection.Before)(state, dispatch);
271
+ } else if ((0, _utils.isEmptyParagraph)(childNode)) {
272
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), _types.SelectionDirection.Before)(state, dispatch);
273
+ } else if (!(0, _selection.isIgnored)(node)) {
274
+ return setSelectionRelativeToNode(selectionRelativeToNode, new _gapCursorSelection.GapCursorSelection(state.doc.resolve(selectionPos), _gapCursorSelection.Side.LEFT))(state, dispatch);
275
+ } else if ((0, _utils2.isSelectableContainerNode)(node)) {
276
+ return setSelectionRelativeToNode(selectionRelativeToNode, _state.NodeSelection.create(state.doc, selectionPos))(state, dispatch);
277
+ }
278
+ }
279
+ return false;
280
+ }
218
281
  if (selectableNode) {
219
- var childNode = selectableNode.node,
220
- childPos = selectableNode.pos;
221
- var selectionPos = pos + childPos + 1;
222
- if (childNode.isText || childNode.isAtom) {
223
- return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), _types.SelectionDirection.Before)(state, dispatch);
224
- } else if ((0, _utils.isEmptyParagraph)(childNode)) {
225
- return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), _types.SelectionDirection.Before)(state, dispatch);
282
+ var _childNode = selectableNode.node,
283
+ _childPos = selectableNode.pos;
284
+ var _selectionPos = pos + _childPos + 1;
285
+ if (_childNode.isText || _childNode.isAtom) {
286
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(_selectionPos), _types.SelectionDirection.Before)(state, dispatch);
287
+ } else if ((0, _utils.isEmptyParagraph)(_childNode)) {
288
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(_selectionPos + 1), _types.SelectionDirection.Before)(state, dispatch);
226
289
  } else if (!(0, _selection.isIgnored)(node)) {
227
- return setSelectionRelativeToNode(selectionRelativeToNode, new _gapCursorSelection.GapCursorSelection(state.doc.resolve(selectionPos), _gapCursorSelection.Side.LEFT))(state, dispatch);
290
+ return setSelectionRelativeToNode(selectionRelativeToNode, new _gapCursorSelection.GapCursorSelection(state.doc.resolve(_selectionPos), _gapCursorSelection.Side.LEFT))(state, dispatch);
228
291
  } else if ((0, _utils2.isSelectableContainerNode)(node)) {
229
- return setSelectionRelativeToNode(selectionRelativeToNode, _state.NodeSelection.create(state.doc, selectionPos))(state, dispatch);
292
+ return setSelectionRelativeToNode(selectionRelativeToNode, _state.NodeSelection.create(state.doc, _selectionPos))(state, dispatch);
230
293
  }
231
294
  }
232
295
  return false;
@@ -238,18 +301,36 @@ var setSelectionInsideAtNodeEnd = exports.setSelectionInsideAtNodeEnd = function
238
301
  return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(to), _types.SelectionDirection.Before)(state, dispatch);
239
302
  }
240
303
  var selectableNode = (0, _utils2.findLastChildNodeToSelect)(node);
304
+ if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.change-navigation-for-atom-nodes')) {
305
+ if (selectableNode) {
306
+ var childNode = selectableNode.node,
307
+ childPos = selectableNode.pos;
308
+ var selectionPos = from + childPos + childNode.nodeSize;
309
+ if (childNode.isText || childNode.isAtom && (0, _selection.isIgnored)(childNode) || childNode.isInline) {
310
+ //selection is for text node, inline node or atom node which is ignored by gap-cursor. set selection after it.
311
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), _types.SelectionDirection.After)(state, dispatch);
312
+ } else if ((0, _utils.isEmptyParagraph)(childNode)) {
313
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), _types.SelectionDirection.After)(state, dispatch);
314
+ } else if (!(0, _selection.isIgnored)(node)) {
315
+ return setSelectionRelativeToNode(selectionRelativeToNode, new _gapCursorSelection.GapCursorSelection(state.doc.resolve(selectionPos + 1), _gapCursorSelection.Side.RIGHT))(state, dispatch);
316
+ } else if ((0, _utils2.isSelectableContainerNode)(node)) {
317
+ return setSelectionRelativeToNode(selectionRelativeToNode, _state.NodeSelection.create(state.doc, selectionPos))(state, dispatch);
318
+ }
319
+ }
320
+ return false;
321
+ }
241
322
  if (selectableNode) {
242
- var childNode = selectableNode.node,
243
- childPos = selectableNode.pos;
244
- var selectionPos = from + childPos + childNode.nodeSize;
245
- if (childNode.isText || childNode.isAtom) {
246
- return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), _types.SelectionDirection.After)(state, dispatch);
247
- } else if ((0, _utils.isEmptyParagraph)(childNode)) {
248
- return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), _types.SelectionDirection.After)(state, dispatch);
323
+ var _childNode2 = selectableNode.node,
324
+ _childPos2 = selectableNode.pos;
325
+ var _selectionPos2 = from + _childPos2 + _childNode2.nodeSize;
326
+ if (_childNode2.isText || _childNode2.isAtom) {
327
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(_selectionPos2 + 1), _types.SelectionDirection.After)(state, dispatch);
328
+ } else if ((0, _utils.isEmptyParagraph)(_childNode2)) {
329
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(_selectionPos2), _types.SelectionDirection.After)(state, dispatch);
249
330
  } else if (!(0, _selection.isIgnored)(node)) {
250
- return setSelectionRelativeToNode(selectionRelativeToNode, new _gapCursorSelection.GapCursorSelection(state.doc.resolve(selectionPos + 1), _gapCursorSelection.Side.RIGHT))(state, dispatch);
331
+ return setSelectionRelativeToNode(selectionRelativeToNode, new _gapCursorSelection.GapCursorSelection(state.doc.resolve(_selectionPos2 + 1), _gapCursorSelection.Side.RIGHT))(state, dispatch);
251
332
  } else if ((0, _utils2.isSelectableContainerNode)(node)) {
252
- return setSelectionRelativeToNode(selectionRelativeToNode, _state.NodeSelection.create(state.doc, selectionPos))(state, dispatch);
333
+ return setSelectionRelativeToNode(selectionRelativeToNode, _state.NodeSelection.create(state.doc, _selectionPos2))(state, dispatch);
253
334
  }
254
335
  }
255
336
  return false;
@@ -1,6 +1,8 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
1
2
  import { isIgnored as isIgnoredByGapCursor } from '@atlaskit/editor-common/selection';
2
3
  import { isEmptyParagraph, isNodeEmpty } from '@atlaskit/editor-common/utils';
3
4
  import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
5
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
4
6
  import { SelectionActionTypes } from './actions';
5
7
  import { GapCursorSelection, Side } from './gap-cursor-selection';
6
8
  import { createCommand, getPluginState } from './plugin-factory';
@@ -115,6 +117,25 @@ const arrowRightFromNode = selection => (state, dispatch) => {
115
117
  const {
116
118
  selectionRelativeToNode
117
119
  } = getPluginState(state);
120
+ if (getBooleanFF('platform.editor.change-navigation-for-atom-nodes')) {
121
+ if (node.isAtom) {
122
+ if (isSelectionAtEndOfParentNode($to, selection) && (node.isInline || isIgnoredByGapCursor(node))) {
123
+ // selection is for inline node or atom node which is ignored by gap-cursor and that is the last child of its parent node - set text selection after it
124
+ return findAndSetTextSelection(RelativeSelectionPos.End, state.doc.resolve(from + 1), SelectionDirection.After)(state, dispatch);
125
+ }
126
+ return false;
127
+ } else if (selectionRelativeToNode === RelativeSelectionPos.Start) {
128
+ // selection is for container node - set selection inside it at the start
129
+ return setSelectionInsideAtNodeStart(RelativeSelectionPos.Inside, node, from)(state, dispatch);
130
+ } else if (isIgnoredByGapCursor(node) && (!selectionRelativeToNode || selectionRelativeToNode === RelativeSelectionPos.End)) {
131
+ const selectableNode = findSelectableContainerAfter($to, state.doc);
132
+ if (selectableNode && isIgnoredByGapCursor(selectableNode.node)) {
133
+ // selection is for node without gap cursor followed by another node without gap cursor - set node selection for next node
134
+ return setSelectionRelativeToNode(RelativeSelectionPos.Start, NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
135
+ }
136
+ }
137
+ return false;
138
+ }
118
139
  if (node.isAtom) {
119
140
  if (isSelectionAtEndOfParentNode($to, selection)) {
120
141
  // selection is for inline node that is the last child of its parent node - set text selection after it
@@ -143,6 +164,29 @@ const arrowLeftFromNode = selection => (state, dispatch) => {
143
164
  const {
144
165
  selectionRelativeToNode
145
166
  } = getPluginState(state);
167
+ if (getBooleanFF('platform.editor.change-navigation-for-atom-nodes')) {
168
+ if (node.isAtom) {
169
+ if (isSelectionAtStartOfParentNode($from, selection) && (node.isInline || isIgnoredByGapCursor(node))) {
170
+ // selection is for inline node or atom node which is ignored by gap-cursor and that is the first child of its parent node - set text selection before it
171
+ return findAndSetTextSelection(RelativeSelectionPos.Start, state.doc.resolve(from), SelectionDirection.Before)(state, dispatch);
172
+ }
173
+ return false;
174
+ } else if (selectionRelativeToNode === RelativeSelectionPos.End) {
175
+ // selection is for container node - set selection inside it at the end
176
+ return setSelectionInsideAtNodeEnd(RelativeSelectionPos.Inside, node, from, to)(state, dispatch);
177
+ } else if (!selectionRelativeToNode || selectionRelativeToNode === RelativeSelectionPos.Inside) {
178
+ // selection is for container node - set selection inside it at the start
179
+ // (this is a special case when the user selects by clicking node)
180
+ return setSelectionInsideAtNodeStart(RelativeSelectionPos.Before, node, from)(state, dispatch);
181
+ } else if (isIgnoredByGapCursor(node) && selectionRelativeToNode === RelativeSelectionPos.Start) {
182
+ // selection is for node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
183
+ const selectableNode = findSelectableContainerBefore($from, state.doc);
184
+ if (selectableNode && isIgnoredByGapCursor(selectableNode.node)) {
185
+ return setSelectionRelativeToNode(RelativeSelectionPos.End, NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
186
+ }
187
+ }
188
+ return false;
189
+ }
146
190
  if (node.isAtom) {
147
191
  if (isSelectionAtStartOfParentNode($from, selection)) {
148
192
  // selection is for inline node that is the first child of its parent node - set text selection before it
@@ -207,6 +251,26 @@ const setSelectionInsideAtNodeStart = (selectionRelativeToNode, node, pos) => (s
207
251
  return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(pos), SelectionDirection.After)(state, dispatch);
208
252
  }
209
253
  const selectableNode = findFirstChildNodeToSelect(node);
254
+ if (getBooleanFF('platform.editor.change-navigation-for-atom-nodes')) {
255
+ if (selectableNode) {
256
+ const {
257
+ node: childNode,
258
+ pos: childPos
259
+ } = selectableNode;
260
+ const selectionPos = pos + childPos + 1;
261
+ if (childNode.isText || childNode.isAtom && isIgnoredByGapCursor(childNode) || childNode.isInline) {
262
+ //selection is for text node, inline node or atom node which is ignored by gap-cursor. set selection before it.
263
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), SelectionDirection.Before)(state, dispatch);
264
+ } else if (isEmptyParagraph(childNode)) {
265
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), SelectionDirection.Before)(state, dispatch);
266
+ } else if (!isIgnoredByGapCursor(node)) {
267
+ return setSelectionRelativeToNode(selectionRelativeToNode, new GapCursorSelection(state.doc.resolve(selectionPos), Side.LEFT))(state, dispatch);
268
+ } else if (isSelectableContainerNode(node)) {
269
+ return setSelectionRelativeToNode(selectionRelativeToNode, NodeSelection.create(state.doc, selectionPos))(state, dispatch);
270
+ }
271
+ }
272
+ return false;
273
+ }
210
274
  if (selectableNode) {
211
275
  const {
212
276
  node: childNode,
@@ -230,6 +294,26 @@ export const setSelectionInsideAtNodeEnd = (selectionRelativeToNode, node, from,
230
294
  return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(to), SelectionDirection.Before)(state, dispatch);
231
295
  }
232
296
  const selectableNode = findLastChildNodeToSelect(node);
297
+ if (getBooleanFF('platform.editor.change-navigation-for-atom-nodes')) {
298
+ if (selectableNode) {
299
+ const {
300
+ node: childNode,
301
+ pos: childPos
302
+ } = selectableNode;
303
+ const selectionPos = from + childPos + childNode.nodeSize;
304
+ if (childNode.isText || childNode.isAtom && isIgnoredByGapCursor(childNode) || childNode.isInline) {
305
+ //selection is for text node, inline node or atom node which is ignored by gap-cursor. set selection after it.
306
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), SelectionDirection.After)(state, dispatch);
307
+ } else if (isEmptyParagraph(childNode)) {
308
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), SelectionDirection.After)(state, dispatch);
309
+ } else if (!isIgnoredByGapCursor(node)) {
310
+ return setSelectionRelativeToNode(selectionRelativeToNode, new GapCursorSelection(state.doc.resolve(selectionPos + 1), Side.RIGHT))(state, dispatch);
311
+ } else if (isSelectableContainerNode(node)) {
312
+ return setSelectionRelativeToNode(selectionRelativeToNode, NodeSelection.create(state.doc, selectionPos))(state, dispatch);
313
+ }
314
+ }
315
+ return false;
316
+ }
233
317
  if (selectableNode) {
234
318
  const {
235
319
  node: childNode,
@@ -1,6 +1,8 @@
1
+ /* eslint-disable import/no-extraneous-dependencies */
1
2
  import { isIgnored as isIgnoredByGapCursor } from '@atlaskit/editor-common/selection';
2
3
  import { isEmptyParagraph, isNodeEmpty } from '@atlaskit/editor-common/utils';
3
4
  import { NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
5
+ import { getBooleanFF } from '@atlaskit/platform-feature-flags';
4
6
  import { SelectionActionTypes } from './actions';
5
7
  import { GapCursorSelection, Side } from './gap-cursor-selection';
6
8
  import { createCommand, getPluginState } from './plugin-factory';
@@ -111,6 +113,25 @@ var arrowRightFromNode = function arrowRightFromNode(selection) {
111
113
  $to = selection.$to;
112
114
  var _getPluginState2 = getPluginState(state),
113
115
  selectionRelativeToNode = _getPluginState2.selectionRelativeToNode;
116
+ if (getBooleanFF('platform.editor.change-navigation-for-atom-nodes')) {
117
+ if (node.isAtom) {
118
+ if (isSelectionAtEndOfParentNode($to, selection) && (node.isInline || isIgnoredByGapCursor(node))) {
119
+ // selection is for inline node or atom node which is ignored by gap-cursor and that is the last child of its parent node - set text selection after it
120
+ return findAndSetTextSelection(RelativeSelectionPos.End, state.doc.resolve(from + 1), SelectionDirection.After)(state, dispatch);
121
+ }
122
+ return false;
123
+ } else if (selectionRelativeToNode === RelativeSelectionPos.Start) {
124
+ // selection is for container node - set selection inside it at the start
125
+ return setSelectionInsideAtNodeStart(RelativeSelectionPos.Inside, node, from)(state, dispatch);
126
+ } else if (isIgnoredByGapCursor(node) && (!selectionRelativeToNode || selectionRelativeToNode === RelativeSelectionPos.End)) {
127
+ var selectableNode = findSelectableContainerAfter($to, state.doc);
128
+ if (selectableNode && isIgnoredByGapCursor(selectableNode.node)) {
129
+ // selection is for node without gap cursor followed by another node without gap cursor - set node selection for next node
130
+ return setSelectionRelativeToNode(RelativeSelectionPos.Start, NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
131
+ }
132
+ }
133
+ return false;
134
+ }
114
135
  if (node.isAtom) {
115
136
  if (isSelectionAtEndOfParentNode($to, selection)) {
116
137
  // selection is for inline node that is the last child of its parent node - set text selection after it
@@ -121,10 +142,10 @@ var arrowRightFromNode = function arrowRightFromNode(selection) {
121
142
  // selection is for container node - set selection inside it at the start
122
143
  return setSelectionInsideAtNodeStart(RelativeSelectionPos.Inside, node, from)(state, dispatch);
123
144
  } else if (isIgnoredByGapCursor(node) && (!selectionRelativeToNode || selectionRelativeToNode === RelativeSelectionPos.End)) {
124
- var selectableNode = findSelectableContainerAfter($to, state.doc);
125
- if (selectableNode && isIgnoredByGapCursor(selectableNode.node)) {
145
+ var _selectableNode4 = findSelectableContainerAfter($to, state.doc);
146
+ if (_selectableNode4 && isIgnoredByGapCursor(_selectableNode4.node)) {
126
147
  // selection is for node without gap cursor followed by another node without gap cursor - set node selection for next node
127
- return setSelectionRelativeToNode(RelativeSelectionPos.Start, NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
148
+ return setSelectionRelativeToNode(RelativeSelectionPos.Start, NodeSelection.create(state.doc, _selectableNode4.pos))(state, dispatch);
128
149
  }
129
150
  }
130
151
  return false;
@@ -138,6 +159,29 @@ var arrowLeftFromNode = function arrowLeftFromNode(selection) {
138
159
  $from = selection.$from;
139
160
  var _getPluginState3 = getPluginState(state),
140
161
  selectionRelativeToNode = _getPluginState3.selectionRelativeToNode;
162
+ if (getBooleanFF('platform.editor.change-navigation-for-atom-nodes')) {
163
+ if (node.isAtom) {
164
+ if (isSelectionAtStartOfParentNode($from, selection) && (node.isInline || isIgnoredByGapCursor(node))) {
165
+ // selection is for inline node or atom node which is ignored by gap-cursor and that is the first child of its parent node - set text selection before it
166
+ return findAndSetTextSelection(RelativeSelectionPos.Start, state.doc.resolve(from), SelectionDirection.Before)(state, dispatch);
167
+ }
168
+ return false;
169
+ } else if (selectionRelativeToNode === RelativeSelectionPos.End) {
170
+ // selection is for container node - set selection inside it at the end
171
+ return setSelectionInsideAtNodeEnd(RelativeSelectionPos.Inside, node, from, to)(state, dispatch);
172
+ } else if (!selectionRelativeToNode || selectionRelativeToNode === RelativeSelectionPos.Inside) {
173
+ // selection is for container node - set selection inside it at the start
174
+ // (this is a special case when the user selects by clicking node)
175
+ return setSelectionInsideAtNodeStart(RelativeSelectionPos.Before, node, from)(state, dispatch);
176
+ } else if (isIgnoredByGapCursor(node) && selectionRelativeToNode === RelativeSelectionPos.Start) {
177
+ // selection is for node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
178
+ var selectableNode = findSelectableContainerBefore($from, state.doc);
179
+ if (selectableNode && isIgnoredByGapCursor(selectableNode.node)) {
180
+ return setSelectionRelativeToNode(RelativeSelectionPos.End, NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
181
+ }
182
+ }
183
+ return false;
184
+ }
141
185
  if (node.isAtom) {
142
186
  if (isSelectionAtStartOfParentNode($from, selection)) {
143
187
  // selection is for inline node that is the first child of its parent node - set text selection before it
@@ -153,9 +197,9 @@ var arrowLeftFromNode = function arrowLeftFromNode(selection) {
153
197
  return setSelectionInsideAtNodeStart(RelativeSelectionPos.Before, node, from)(state, dispatch);
154
198
  } else if (isIgnoredByGapCursor(node) && selectionRelativeToNode === RelativeSelectionPos.Start) {
155
199
  // selection is for node without gap cursor preceeded by another node without gap cursor - set node selection for previous node
156
- var selectableNode = findSelectableContainerBefore($from, state.doc);
157
- if (selectableNode && isIgnoredByGapCursor(selectableNode.node)) {
158
- return setSelectionRelativeToNode(RelativeSelectionPos.End, NodeSelection.create(state.doc, selectableNode.pos))(state, dispatch);
200
+ var _selectableNode5 = findSelectableContainerBefore($from, state.doc);
201
+ if (_selectableNode5 && isIgnoredByGapCursor(_selectableNode5.node)) {
202
+ return setSelectionRelativeToNode(RelativeSelectionPos.End, NodeSelection.create(state.doc, _selectableNode5.pos))(state, dispatch);
159
203
  }
160
204
  }
161
205
  return false;
@@ -186,9 +230,9 @@ var arrowLeftFromText = function arrowLeftFromText(selection) {
186
230
  // from responding to arrow left key
187
231
  setSelectionRelativeToNode(undefined)(state, dispatch);
188
232
  } else if (isSelectionAtStartOfParentNode(selection.$from, selection)) {
189
- var _selectableNode4 = findSelectableContainerParent(selection);
190
- if (_selectableNode4) {
191
- return setSelectionRelativeToNode(RelativeSelectionPos.Start, NodeSelection.create(state.doc, _selectableNode4.pos))(state, dispatch);
233
+ var _selectableNode6 = findSelectableContainerParent(selection);
234
+ if (_selectableNode6) {
235
+ return setSelectionRelativeToNode(RelativeSelectionPos.Start, NodeSelection.create(state.doc, _selectableNode6.pos))(state, dispatch);
192
236
  }
193
237
  }
194
238
  return false;
@@ -209,18 +253,36 @@ var setSelectionInsideAtNodeStart = function setSelectionInsideAtNodeStart(selec
209
253
  return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(pos), SelectionDirection.After)(state, dispatch);
210
254
  }
211
255
  var selectableNode = findFirstChildNodeToSelect(node);
256
+ if (getBooleanFF('platform.editor.change-navigation-for-atom-nodes')) {
257
+ if (selectableNode) {
258
+ var childNode = selectableNode.node,
259
+ childPos = selectableNode.pos;
260
+ var selectionPos = pos + childPos + 1;
261
+ if (childNode.isText || childNode.isAtom && isIgnoredByGapCursor(childNode) || childNode.isInline) {
262
+ //selection is for text node, inline node or atom node which is ignored by gap-cursor. set selection before it.
263
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), SelectionDirection.Before)(state, dispatch);
264
+ } else if (isEmptyParagraph(childNode)) {
265
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), SelectionDirection.Before)(state, dispatch);
266
+ } else if (!isIgnoredByGapCursor(node)) {
267
+ return setSelectionRelativeToNode(selectionRelativeToNode, new GapCursorSelection(state.doc.resolve(selectionPos), Side.LEFT))(state, dispatch);
268
+ } else if (isSelectableContainerNode(node)) {
269
+ return setSelectionRelativeToNode(selectionRelativeToNode, NodeSelection.create(state.doc, selectionPos))(state, dispatch);
270
+ }
271
+ }
272
+ return false;
273
+ }
212
274
  if (selectableNode) {
213
- var childNode = selectableNode.node,
214
- childPos = selectableNode.pos;
215
- var selectionPos = pos + childPos + 1;
216
- if (childNode.isText || childNode.isAtom) {
217
- return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), SelectionDirection.Before)(state, dispatch);
218
- } else if (isEmptyParagraph(childNode)) {
219
- return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), SelectionDirection.Before)(state, dispatch);
275
+ var _childNode = selectableNode.node,
276
+ _childPos = selectableNode.pos;
277
+ var _selectionPos = pos + _childPos + 1;
278
+ if (_childNode.isText || _childNode.isAtom) {
279
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(_selectionPos), SelectionDirection.Before)(state, dispatch);
280
+ } else if (isEmptyParagraph(_childNode)) {
281
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(_selectionPos + 1), SelectionDirection.Before)(state, dispatch);
220
282
  } else if (!isIgnoredByGapCursor(node)) {
221
- return setSelectionRelativeToNode(selectionRelativeToNode, new GapCursorSelection(state.doc.resolve(selectionPos), Side.LEFT))(state, dispatch);
283
+ return setSelectionRelativeToNode(selectionRelativeToNode, new GapCursorSelection(state.doc.resolve(_selectionPos), Side.LEFT))(state, dispatch);
222
284
  } else if (isSelectableContainerNode(node)) {
223
- return setSelectionRelativeToNode(selectionRelativeToNode, NodeSelection.create(state.doc, selectionPos))(state, dispatch);
285
+ return setSelectionRelativeToNode(selectionRelativeToNode, NodeSelection.create(state.doc, _selectionPos))(state, dispatch);
224
286
  }
225
287
  }
226
288
  return false;
@@ -232,18 +294,36 @@ export var setSelectionInsideAtNodeEnd = function setSelectionInsideAtNodeEnd(se
232
294
  return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(to), SelectionDirection.Before)(state, dispatch);
233
295
  }
234
296
  var selectableNode = findLastChildNodeToSelect(node);
297
+ if (getBooleanFF('platform.editor.change-navigation-for-atom-nodes')) {
298
+ if (selectableNode) {
299
+ var childNode = selectableNode.node,
300
+ childPos = selectableNode.pos;
301
+ var selectionPos = from + childPos + childNode.nodeSize;
302
+ if (childNode.isText || childNode.isAtom && isIgnoredByGapCursor(childNode) || childNode.isInline) {
303
+ //selection is for text node, inline node or atom node which is ignored by gap-cursor. set selection after it.
304
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), SelectionDirection.After)(state, dispatch);
305
+ } else if (isEmptyParagraph(childNode)) {
306
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), SelectionDirection.After)(state, dispatch);
307
+ } else if (!isIgnoredByGapCursor(node)) {
308
+ return setSelectionRelativeToNode(selectionRelativeToNode, new GapCursorSelection(state.doc.resolve(selectionPos + 1), Side.RIGHT))(state, dispatch);
309
+ } else if (isSelectableContainerNode(node)) {
310
+ return setSelectionRelativeToNode(selectionRelativeToNode, NodeSelection.create(state.doc, selectionPos))(state, dispatch);
311
+ }
312
+ }
313
+ return false;
314
+ }
235
315
  if (selectableNode) {
236
- var childNode = selectableNode.node,
237
- childPos = selectableNode.pos;
238
- var selectionPos = from + childPos + childNode.nodeSize;
239
- if (childNode.isText || childNode.isAtom) {
240
- return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos + 1), SelectionDirection.After)(state, dispatch);
241
- } else if (isEmptyParagraph(childNode)) {
242
- return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(selectionPos), SelectionDirection.After)(state, dispatch);
316
+ var _childNode2 = selectableNode.node,
317
+ _childPos2 = selectableNode.pos;
318
+ var _selectionPos2 = from + _childPos2 + _childNode2.nodeSize;
319
+ if (_childNode2.isText || _childNode2.isAtom) {
320
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(_selectionPos2 + 1), SelectionDirection.After)(state, dispatch);
321
+ } else if (isEmptyParagraph(_childNode2)) {
322
+ return findAndSetTextSelection(selectionRelativeToNode, state.doc.resolve(_selectionPos2), SelectionDirection.After)(state, dispatch);
243
323
  } else if (!isIgnoredByGapCursor(node)) {
244
- return setSelectionRelativeToNode(selectionRelativeToNode, new GapCursorSelection(state.doc.resolve(selectionPos + 1), Side.RIGHT))(state, dispatch);
324
+ return setSelectionRelativeToNode(selectionRelativeToNode, new GapCursorSelection(state.doc.resolve(_selectionPos2 + 1), Side.RIGHT))(state, dispatch);
245
325
  } else if (isSelectableContainerNode(node)) {
246
- return setSelectionRelativeToNode(selectionRelativeToNode, NodeSelection.create(state.doc, selectionPos))(state, dispatch);
326
+ return setSelectionRelativeToNode(selectionRelativeToNode, NodeSelection.create(state.doc, _selectionPos2))(state, dispatch);
247
327
  }
248
328
  }
249
329
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-plugin-selection",
3
- "version": "0.2.2",
3
+ "version": "1.0.1",
4
4
  "description": "Selection plugin for @atlaskit/editor-core",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -21,7 +21,7 @@
21
21
  "runReact18": false
22
22
  },
23
23
  "dependencies": {
24
- "@atlaskit/editor-common": "^77.3.0",
24
+ "@atlaskit/editor-common": "^77.4.0",
25
25
  "@atlaskit/editor-prosemirror": "3.0.0",
26
26
  "@atlaskit/editor-shared-styles": "^2.9.0",
27
27
  "@atlaskit/editor-tables": "^2.5.0",
@@ -78,5 +78,10 @@
78
78
  "no-unused-dependencies": {
79
79
  "checkDevDependencies": true
80
80
  }
81
+ },
82
+ "platform-feature-flags": {
83
+ "platform.editor.change-navigation-for-atom-nodes": {
84
+ "type": "boolean"
85
+ }
81
86
  }
82
87
  }