@atlaskit/editor-plugin-selection 3.0.1 → 3.0.3
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,24 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-selection
|
|
2
2
|
|
|
3
|
+
## 3.0.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#184963](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/184963)
|
|
8
|
+
[`f6b81506eb05b`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/f6b81506eb05b) -
|
|
9
|
+
[ux][ED-25230] Bug fix: inability to navigate between layout columns using arrow keys
|
|
10
|
+
- Updated dependencies
|
|
11
|
+
|
|
12
|
+
## 3.0.2
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [#184967](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/pull-requests/184967)
|
|
17
|
+
[`c868ad3f120c0`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/c868ad3f120c0) -
|
|
18
|
+
[ux] Fix bug: pressing right arrow from listItem in layout/extended/panel skips next listItem and
|
|
19
|
+
selects container instead
|
|
20
|
+
- Updated dependencies
|
|
21
|
+
|
|
3
22
|
## 3.0.1
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isSelectionAtStartOfParentNode = exports.isSelectionAtEndOfParentNode = exports.isSelectableContainerNode = exports.isSelectableChildNode = exports.getNodesToDecorateFromSelection = exports.getDecorations = exports.findSelectableContainerParent = exports.findSelectableContainerBefore = exports.findSelectableContainerAfter = exports.findLastChildNodeToSelect = exports.findFirstChildNodeToSelect = void 0;
|
|
6
|
+
exports.isSelectionAtStartOfParentNode = exports.isSelectionAtEndOfParentNode = exports.isSelectionAtEndOfLayoutColumn = exports.isSelectableContainerNode = exports.isSelectableChildNode = exports.isListItemWithinContainerNotAtEnd = exports.isLayoutColumnNode = exports.isContainerNode = exports.getNodesToDecorateFromSelection = exports.getDecorations = exports.findTopLevelList = exports.findSelectableContainerParent = exports.findSelectableContainerBefore = exports.findSelectableContainerAfter = exports.findLastChildNodeToSelect = exports.findFirstChildNodeToSelect = void 0;
|
|
7
7
|
exports.shouldRecalcDecorations = shouldRecalcDecorations;
|
|
8
8
|
var _selection = require("@atlaskit/editor-common/selection");
|
|
9
9
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
@@ -11,6 +11,7 @@ var _state = require("@atlaskit/editor-prosemirror/state");
|
|
|
11
11
|
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
|
|
12
12
|
var _view = require("@atlaskit/editor-prosemirror/view");
|
|
13
13
|
var _editorSharedStyles = require("@atlaskit/editor-shared-styles");
|
|
14
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
14
15
|
var _types = require("../types");
|
|
15
16
|
var getDecorations = exports.getDecorations = function getDecorations(tr, manualSelection) {
|
|
16
17
|
var selection = tr.selection;
|
|
@@ -248,13 +249,127 @@ var isSelectionAtStartOfParentNode = exports.isSelectionAtStartOfParentNode = fu
|
|
|
248
249
|
return (0, _selection.isSelectionAtStartOfNode)($pos, (_findSelectableContai = findSelectableContainerParent(selection)) === null || _findSelectableContai === void 0 ? void 0 : _findSelectableContai.node);
|
|
249
250
|
};
|
|
250
251
|
var isSelectionAtEndOfParentNode = exports.isSelectionAtEndOfParentNode = function isSelectionAtEndOfParentNode($pos, selection) {
|
|
252
|
+
// If the current position is at the end of its parent node's content.
|
|
251
253
|
var isAtTheEndOfCurrentLevel = $pos.parent.content.size === $pos.parentOffset;
|
|
252
254
|
if (!isAtTheEndOfCurrentLevel) {
|
|
253
255
|
return false;
|
|
254
256
|
}
|
|
257
|
+
|
|
258
|
+
// If at the root or parent is selectable, we're at the end
|
|
255
259
|
if ($pos.depth === 0 || _state.NodeSelection.isSelectable($pos.parent)) {
|
|
256
260
|
return isAtTheEndOfCurrentLevel;
|
|
257
261
|
}
|
|
262
|
+
|
|
263
|
+
// Handle lists: if in a list inside container and not at the end, return false
|
|
264
|
+
if ((0, _utils2.hasParentNode)(_utils.isListItemNode)(selection) && isListItemWithinContainerNotAtEnd($pos, selection) && (0, _platformFeatureFlags.fg)('platform_editor_fix_right_arrow_bug_list_in_layout')) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// Handle layout columns: if another node follows, not at end
|
|
269
|
+
if (isSelectionAtEndOfLayoutColumn($pos) && (0, _platformFeatureFlags.fg)('platform_editor_fix_right_arrow_nav_bug_in_layout')) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Default: if at end of parent's parent
|
|
258
274
|
var $after = $pos.doc.resolve($pos.after());
|
|
259
275
|
return $after.parent.content.size === $after.parentOffset;
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Determines if the current selection is inside a list item within a container and not at the end of the parent list.
|
|
280
|
+
*
|
|
281
|
+
* This is useful for handling edge cases where the selection is within a list inside a container structure,
|
|
282
|
+
* and we need to know if the selection is not at the logical end of the parent list node.
|
|
283
|
+
*/
|
|
284
|
+
var isListItemWithinContainerNotAtEnd = exports.isListItemWithinContainerNotAtEnd = function isListItemWithinContainerNotAtEnd($pos, selection) {
|
|
285
|
+
var isInContainerNode = (0, _utils2.hasParentNode)(isContainerNode)(selection);
|
|
286
|
+
if (!isInContainerNode) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
var parentList = (0, _utils2.findParentNodeClosestToPos)($pos, _utils.isListItemNode);
|
|
290
|
+
if (!parentList) {
|
|
291
|
+
return false;
|
|
292
|
+
}
|
|
293
|
+
var $parentListPos = $pos.doc.resolve(parentList.pos);
|
|
294
|
+
var topLevelList = findTopLevelList($pos);
|
|
295
|
+
if (!topLevelList) {
|
|
296
|
+
return false;
|
|
297
|
+
}
|
|
298
|
+
var $afterTopLevelList = $pos.doc.resolve(topLevelList.pos + topLevelList.node.nodeSize);
|
|
299
|
+
var nodeAfterTopLevelList = $afterTopLevelList.nodeAfter;
|
|
300
|
+
var grandParentList = (0, _utils2.findParentNodeClosestToPos)($pos.doc.resolve($parentListPos.before()), _utils.isListItemNode);
|
|
301
|
+
var grandParentListPos = grandParentList ? $pos.doc.resolve(grandParentList.pos) : undefined;
|
|
302
|
+
var isLastListItemInParent =
|
|
303
|
+
// Check if the current list item is the last child in its parent list
|
|
304
|
+
$parentListPos.index() === $parentListPos.parent.childCount - 1 && (
|
|
305
|
+
// Check if there is no grandparent list, or if the grandparent list item is also the last child in its parent
|
|
306
|
+
!grandParentList || grandParentListPos && grandParentListPos.index() === grandParentListPos.parent.childCount - 1);
|
|
307
|
+
if (!isLastListItemInParent || nodeAfterTopLevelList) {
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
return false;
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Determines if the given node is a Container (layoutColumn, panel, expand) node.
|
|
315
|
+
*/
|
|
316
|
+
var isContainerNode = exports.isContainerNode = function isContainerNode(node) {
|
|
317
|
+
var _node$type;
|
|
318
|
+
var _ref3 = (node === null || node === void 0 || (_node$type = node.type) === null || _node$type === void 0 || (_node$type = _node$type.schema) === null || _node$type === void 0 ? void 0 : _node$type.nodes) || {},
|
|
319
|
+
layoutColumn = _ref3.layoutColumn,
|
|
320
|
+
panel = _ref3.panel,
|
|
321
|
+
expand = _ref3.expand;
|
|
322
|
+
return Boolean(node && node.type && [panel, expand, layoutColumn].includes(node.type));
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Finds the top-level List ancestor of the given position.
|
|
327
|
+
* Returns the node and its position if found, otherwise returns undefined.
|
|
328
|
+
*/
|
|
329
|
+
var findTopLevelList = exports.findTopLevelList = function findTopLevelList(pos) {
|
|
330
|
+
var _pos$doc$type$schema$ = pos.doc.type.schema.nodes,
|
|
331
|
+
bulletList = _pos$doc$type$schema$.bulletList,
|
|
332
|
+
orderedList = _pos$doc$type$schema$.orderedList;
|
|
333
|
+
var currentDepth = pos.depth;
|
|
334
|
+
var topLevelList;
|
|
335
|
+
while (currentDepth > 0) {
|
|
336
|
+
var node = pos.node(currentDepth);
|
|
337
|
+
if ([bulletList, orderedList].includes(node.type)) {
|
|
338
|
+
topLevelList = {
|
|
339
|
+
node: node,
|
|
340
|
+
pos: pos.before(currentDepth)
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
currentDepth--;
|
|
344
|
+
}
|
|
345
|
+
return topLevelList;
|
|
346
|
+
};
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Determines whether the current selection position is at the end of a layout column node.
|
|
350
|
+
*/
|
|
351
|
+
var isSelectionAtEndOfLayoutColumn = exports.isSelectionAtEndOfLayoutColumn = function isSelectionAtEndOfLayoutColumn($pos) {
|
|
352
|
+
var layoutColumnParent = (0, _utils2.findParentNodeClosestToPos)($pos, isLayoutColumnNode);
|
|
353
|
+
if (!layoutColumnParent) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
var grandParentDepth = $pos.depth - 1;
|
|
357
|
+
if (grandParentDepth < 0) {
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
var layoutColumn = $pos.doc.type.schema.nodes.layoutColumn;
|
|
361
|
+
var grandParent = $pos.node(grandParentDepth);
|
|
362
|
+
var afterPos = layoutColumnParent.pos + layoutColumnParent.node.nodeSize;
|
|
363
|
+
var $after = $pos.doc.resolve(afterPos);
|
|
364
|
+
return Boolean($after.nodeAfter) && grandParent.type === layoutColumn;
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Determines if the given node is a LayoutColumn node.
|
|
369
|
+
*/
|
|
370
|
+
var isLayoutColumnNode = exports.isLayoutColumnNode = function isLayoutColumnNode(node) {
|
|
371
|
+
var _node$type2;
|
|
372
|
+
var _ref4 = (node === null || node === void 0 || (_node$type2 = node.type) === null || _node$type2 === void 0 || (_node$type2 = _node$type2.schema) === null || _node$type2 === void 0 ? void 0 : _node$type2.nodes) || {},
|
|
373
|
+
layoutColumn = _ref4.layoutColumn;
|
|
374
|
+
return Boolean(node && node.type && node.type === layoutColumn);
|
|
260
375
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { isIgnored as isIgnoredByGapCursor, isSelectionAtStartOfNode } from '@atlaskit/editor-common/selection';
|
|
2
|
-
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
2
|
+
import { isEmptyParagraph, isListItemNode } from '@atlaskit/editor-common/utils';
|
|
3
3
|
import { AllSelection, NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
-
import { findParentNode, flatten } from '@atlaskit/editor-prosemirror/utils';
|
|
4
|
+
import { findParentNode, findParentNodeClosestToPos, flatten, hasParentNode } from '@atlaskit/editor-prosemirror/utils';
|
|
5
5
|
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
6
6
|
import { akEditorSelectedNodeClassName } from '@atlaskit/editor-shared-styles';
|
|
7
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
7
8
|
import { selectionPluginKey } from '../types';
|
|
8
9
|
export const getDecorations = (tr, manualSelection) => {
|
|
9
10
|
let selection = tr.selection;
|
|
@@ -237,13 +238,132 @@ export const isSelectionAtStartOfParentNode = ($pos, selection) => {
|
|
|
237
238
|
return isSelectionAtStartOfNode($pos, (_findSelectableContai = findSelectableContainerParent(selection)) === null || _findSelectableContai === void 0 ? void 0 : _findSelectableContai.node);
|
|
238
239
|
};
|
|
239
240
|
export const isSelectionAtEndOfParentNode = ($pos, selection) => {
|
|
241
|
+
// If the current position is at the end of its parent node's content.
|
|
240
242
|
const isAtTheEndOfCurrentLevel = $pos.parent.content.size === $pos.parentOffset;
|
|
241
243
|
if (!isAtTheEndOfCurrentLevel) {
|
|
242
244
|
return false;
|
|
243
245
|
}
|
|
246
|
+
|
|
247
|
+
// If at the root or parent is selectable, we're at the end
|
|
244
248
|
if ($pos.depth === 0 || NodeSelection.isSelectable($pos.parent)) {
|
|
245
249
|
return isAtTheEndOfCurrentLevel;
|
|
246
250
|
}
|
|
251
|
+
|
|
252
|
+
// Handle lists: if in a list inside container and not at the end, return false
|
|
253
|
+
if (hasParentNode(isListItemNode)(selection) && isListItemWithinContainerNotAtEnd($pos, selection) && fg('platform_editor_fix_right_arrow_bug_list_in_layout')) {
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Handle layout columns: if another node follows, not at end
|
|
258
|
+
if (isSelectionAtEndOfLayoutColumn($pos) && fg('platform_editor_fix_right_arrow_nav_bug_in_layout')) {
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Default: if at end of parent's parent
|
|
247
263
|
const $after = $pos.doc.resolve($pos.after());
|
|
248
264
|
return $after.parent.content.size === $after.parentOffset;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Determines if the current selection is inside a list item within a container and not at the end of the parent list.
|
|
269
|
+
*
|
|
270
|
+
* This is useful for handling edge cases where the selection is within a list inside a container structure,
|
|
271
|
+
* and we need to know if the selection is not at the logical end of the parent list node.
|
|
272
|
+
*/
|
|
273
|
+
export const isListItemWithinContainerNotAtEnd = ($pos, selection) => {
|
|
274
|
+
const isInContainerNode = hasParentNode(isContainerNode)(selection);
|
|
275
|
+
if (!isInContainerNode) {
|
|
276
|
+
return false;
|
|
277
|
+
}
|
|
278
|
+
const parentList = findParentNodeClosestToPos($pos, isListItemNode);
|
|
279
|
+
if (!parentList) {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
const $parentListPos = $pos.doc.resolve(parentList.pos);
|
|
283
|
+
const topLevelList = findTopLevelList($pos);
|
|
284
|
+
if (!topLevelList) {
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
const $afterTopLevelList = $pos.doc.resolve(topLevelList.pos + topLevelList.node.nodeSize);
|
|
288
|
+
const nodeAfterTopLevelList = $afterTopLevelList.nodeAfter;
|
|
289
|
+
const grandParentList = findParentNodeClosestToPos($pos.doc.resolve($parentListPos.before()), isListItemNode);
|
|
290
|
+
const grandParentListPos = grandParentList ? $pos.doc.resolve(grandParentList.pos) : undefined;
|
|
291
|
+
const isLastListItemInParent =
|
|
292
|
+
// Check if the current list item is the last child in its parent list
|
|
293
|
+
$parentListPos.index() === $parentListPos.parent.childCount - 1 && (
|
|
294
|
+
// Check if there is no grandparent list, or if the grandparent list item is also the last child in its parent
|
|
295
|
+
!grandParentList || grandParentListPos && grandParentListPos.index() === grandParentListPos.parent.childCount - 1);
|
|
296
|
+
if (!isLastListItemInParent || nodeAfterTopLevelList) {
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
return false;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Determines if the given node is a Container (layoutColumn, panel, expand) node.
|
|
304
|
+
*/
|
|
305
|
+
export const isContainerNode = node => {
|
|
306
|
+
var _node$type, _node$type$schema;
|
|
307
|
+
const {
|
|
308
|
+
layoutColumn,
|
|
309
|
+
panel,
|
|
310
|
+
expand
|
|
311
|
+
} = (node === null || node === void 0 ? void 0 : (_node$type = node.type) === null || _node$type === void 0 ? void 0 : (_node$type$schema = _node$type.schema) === null || _node$type$schema === void 0 ? void 0 : _node$type$schema.nodes) || {};
|
|
312
|
+
return Boolean(node && node.type && [panel, expand, layoutColumn].includes(node.type));
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Finds the top-level List ancestor of the given position.
|
|
317
|
+
* Returns the node and its position if found, otherwise returns undefined.
|
|
318
|
+
*/
|
|
319
|
+
export const findTopLevelList = pos => {
|
|
320
|
+
const {
|
|
321
|
+
bulletList,
|
|
322
|
+
orderedList
|
|
323
|
+
} = pos.doc.type.schema.nodes;
|
|
324
|
+
let currentDepth = pos.depth;
|
|
325
|
+
let topLevelList;
|
|
326
|
+
while (currentDepth > 0) {
|
|
327
|
+
const node = pos.node(currentDepth);
|
|
328
|
+
if ([bulletList, orderedList].includes(node.type)) {
|
|
329
|
+
topLevelList = {
|
|
330
|
+
node,
|
|
331
|
+
pos: pos.before(currentDepth)
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
currentDepth--;
|
|
335
|
+
}
|
|
336
|
+
return topLevelList;
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Determines whether the current selection position is at the end of a layout column node.
|
|
341
|
+
*/
|
|
342
|
+
export const isSelectionAtEndOfLayoutColumn = $pos => {
|
|
343
|
+
const layoutColumnParent = findParentNodeClosestToPos($pos, isLayoutColumnNode);
|
|
344
|
+
if (!layoutColumnParent) {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
const grandParentDepth = $pos.depth - 1;
|
|
348
|
+
if (grandParentDepth < 0) {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
const {
|
|
352
|
+
layoutColumn
|
|
353
|
+
} = $pos.doc.type.schema.nodes;
|
|
354
|
+
const grandParent = $pos.node(grandParentDepth);
|
|
355
|
+
const afterPos = layoutColumnParent.pos + layoutColumnParent.node.nodeSize;
|
|
356
|
+
const $after = $pos.doc.resolve(afterPos);
|
|
357
|
+
return Boolean($after.nodeAfter) && grandParent.type === layoutColumn;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Determines if the given node is a LayoutColumn node.
|
|
362
|
+
*/
|
|
363
|
+
export const isLayoutColumnNode = node => {
|
|
364
|
+
var _node$type2, _node$type2$schema;
|
|
365
|
+
const {
|
|
366
|
+
layoutColumn
|
|
367
|
+
} = (node === null || node === void 0 ? void 0 : (_node$type2 = node.type) === null || _node$type2 === void 0 ? void 0 : (_node$type2$schema = _node$type2.schema) === null || _node$type2$schema === void 0 ? void 0 : _node$type2$schema.nodes) || {};
|
|
368
|
+
return Boolean(node && node.type && node.type === layoutColumn);
|
|
249
369
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { isIgnored as isIgnoredByGapCursor, isSelectionAtStartOfNode } from '@atlaskit/editor-common/selection';
|
|
2
|
-
import { isEmptyParagraph } from '@atlaskit/editor-common/utils';
|
|
2
|
+
import { isEmptyParagraph, isListItemNode } from '@atlaskit/editor-common/utils';
|
|
3
3
|
import { AllSelection, NodeSelection, Selection, TextSelection } from '@atlaskit/editor-prosemirror/state';
|
|
4
|
-
import { findParentNode, flatten } from '@atlaskit/editor-prosemirror/utils';
|
|
4
|
+
import { findParentNode, findParentNodeClosestToPos, flatten, hasParentNode } from '@atlaskit/editor-prosemirror/utils';
|
|
5
5
|
import { Decoration, DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
6
6
|
import { akEditorSelectedNodeClassName } from '@atlaskit/editor-shared-styles';
|
|
7
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
7
8
|
import { selectionPluginKey } from '../types';
|
|
8
9
|
export var getDecorations = function getDecorations(tr, manualSelection) {
|
|
9
10
|
var selection = tr.selection;
|
|
@@ -241,13 +242,127 @@ export var isSelectionAtStartOfParentNode = function isSelectionAtStartOfParentN
|
|
|
241
242
|
return isSelectionAtStartOfNode($pos, (_findSelectableContai = findSelectableContainerParent(selection)) === null || _findSelectableContai === void 0 ? void 0 : _findSelectableContai.node);
|
|
242
243
|
};
|
|
243
244
|
export var isSelectionAtEndOfParentNode = function isSelectionAtEndOfParentNode($pos, selection) {
|
|
245
|
+
// If the current position is at the end of its parent node's content.
|
|
244
246
|
var isAtTheEndOfCurrentLevel = $pos.parent.content.size === $pos.parentOffset;
|
|
245
247
|
if (!isAtTheEndOfCurrentLevel) {
|
|
246
248
|
return false;
|
|
247
249
|
}
|
|
250
|
+
|
|
251
|
+
// If at the root or parent is selectable, we're at the end
|
|
248
252
|
if ($pos.depth === 0 || NodeSelection.isSelectable($pos.parent)) {
|
|
249
253
|
return isAtTheEndOfCurrentLevel;
|
|
250
254
|
}
|
|
255
|
+
|
|
256
|
+
// Handle lists: if in a list inside container and not at the end, return false
|
|
257
|
+
if (hasParentNode(isListItemNode)(selection) && isListItemWithinContainerNotAtEnd($pos, selection) && fg('platform_editor_fix_right_arrow_bug_list_in_layout')) {
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Handle layout columns: if another node follows, not at end
|
|
262
|
+
if (isSelectionAtEndOfLayoutColumn($pos) && fg('platform_editor_fix_right_arrow_nav_bug_in_layout')) {
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Default: if at end of parent's parent
|
|
251
267
|
var $after = $pos.doc.resolve($pos.after());
|
|
252
268
|
return $after.parent.content.size === $after.parentOffset;
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Determines if the current selection is inside a list item within a container and not at the end of the parent list.
|
|
273
|
+
*
|
|
274
|
+
* This is useful for handling edge cases where the selection is within a list inside a container structure,
|
|
275
|
+
* and we need to know if the selection is not at the logical end of the parent list node.
|
|
276
|
+
*/
|
|
277
|
+
export var isListItemWithinContainerNotAtEnd = function isListItemWithinContainerNotAtEnd($pos, selection) {
|
|
278
|
+
var isInContainerNode = hasParentNode(isContainerNode)(selection);
|
|
279
|
+
if (!isInContainerNode) {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
var parentList = findParentNodeClosestToPos($pos, isListItemNode);
|
|
283
|
+
if (!parentList) {
|
|
284
|
+
return false;
|
|
285
|
+
}
|
|
286
|
+
var $parentListPos = $pos.doc.resolve(parentList.pos);
|
|
287
|
+
var topLevelList = findTopLevelList($pos);
|
|
288
|
+
if (!topLevelList) {
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
var $afterTopLevelList = $pos.doc.resolve(topLevelList.pos + topLevelList.node.nodeSize);
|
|
292
|
+
var nodeAfterTopLevelList = $afterTopLevelList.nodeAfter;
|
|
293
|
+
var grandParentList = findParentNodeClosestToPos($pos.doc.resolve($parentListPos.before()), isListItemNode);
|
|
294
|
+
var grandParentListPos = grandParentList ? $pos.doc.resolve(grandParentList.pos) : undefined;
|
|
295
|
+
var isLastListItemInParent =
|
|
296
|
+
// Check if the current list item is the last child in its parent list
|
|
297
|
+
$parentListPos.index() === $parentListPos.parent.childCount - 1 && (
|
|
298
|
+
// Check if there is no grandparent list, or if the grandparent list item is also the last child in its parent
|
|
299
|
+
!grandParentList || grandParentListPos && grandParentListPos.index() === grandParentListPos.parent.childCount - 1);
|
|
300
|
+
if (!isLastListItemInParent || nodeAfterTopLevelList) {
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
return false;
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Determines if the given node is a Container (layoutColumn, panel, expand) node.
|
|
308
|
+
*/
|
|
309
|
+
export var isContainerNode = function isContainerNode(node) {
|
|
310
|
+
var _node$type;
|
|
311
|
+
var _ref3 = (node === null || node === void 0 || (_node$type = node.type) === null || _node$type === void 0 || (_node$type = _node$type.schema) === null || _node$type === void 0 ? void 0 : _node$type.nodes) || {},
|
|
312
|
+
layoutColumn = _ref3.layoutColumn,
|
|
313
|
+
panel = _ref3.panel,
|
|
314
|
+
expand = _ref3.expand;
|
|
315
|
+
return Boolean(node && node.type && [panel, expand, layoutColumn].includes(node.type));
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Finds the top-level List ancestor of the given position.
|
|
320
|
+
* Returns the node and its position if found, otherwise returns undefined.
|
|
321
|
+
*/
|
|
322
|
+
export var findTopLevelList = function findTopLevelList(pos) {
|
|
323
|
+
var _pos$doc$type$schema$ = pos.doc.type.schema.nodes,
|
|
324
|
+
bulletList = _pos$doc$type$schema$.bulletList,
|
|
325
|
+
orderedList = _pos$doc$type$schema$.orderedList;
|
|
326
|
+
var currentDepth = pos.depth;
|
|
327
|
+
var topLevelList;
|
|
328
|
+
while (currentDepth > 0) {
|
|
329
|
+
var node = pos.node(currentDepth);
|
|
330
|
+
if ([bulletList, orderedList].includes(node.type)) {
|
|
331
|
+
topLevelList = {
|
|
332
|
+
node: node,
|
|
333
|
+
pos: pos.before(currentDepth)
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
currentDepth--;
|
|
337
|
+
}
|
|
338
|
+
return topLevelList;
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Determines whether the current selection position is at the end of a layout column node.
|
|
343
|
+
*/
|
|
344
|
+
export var isSelectionAtEndOfLayoutColumn = function isSelectionAtEndOfLayoutColumn($pos) {
|
|
345
|
+
var layoutColumnParent = findParentNodeClosestToPos($pos, isLayoutColumnNode);
|
|
346
|
+
if (!layoutColumnParent) {
|
|
347
|
+
return false;
|
|
348
|
+
}
|
|
349
|
+
var grandParentDepth = $pos.depth - 1;
|
|
350
|
+
if (grandParentDepth < 0) {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
353
|
+
var layoutColumn = $pos.doc.type.schema.nodes.layoutColumn;
|
|
354
|
+
var grandParent = $pos.node(grandParentDepth);
|
|
355
|
+
var afterPos = layoutColumnParent.pos + layoutColumnParent.node.nodeSize;
|
|
356
|
+
var $after = $pos.doc.resolve(afterPos);
|
|
357
|
+
return Boolean($after.nodeAfter) && grandParent.type === layoutColumn;
|
|
358
|
+
};
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Determines if the given node is a LayoutColumn node.
|
|
362
|
+
*/
|
|
363
|
+
export var isLayoutColumnNode = function isLayoutColumnNode(node) {
|
|
364
|
+
var _node$type2;
|
|
365
|
+
var _ref4 = (node === null || node === void 0 || (_node$type2 = node.type) === null || _node$type2 === void 0 || (_node$type2 = _node$type2.schema) === null || _node$type2 === void 0 ? void 0 : _node$type2.nodes) || {},
|
|
366
|
+
layoutColumn = _ref4.layoutColumn;
|
|
367
|
+
return Boolean(node && node.type && node.type === layoutColumn);
|
|
253
368
|
};
|
|
@@ -57,3 +57,30 @@ export declare const findFirstChildNodeToSelect: (parent: PmNode) => NodeWithPos
|
|
|
57
57
|
export declare const findLastChildNodeToSelect: (parent: PmNode) => NodeWithPos | undefined;
|
|
58
58
|
export declare const isSelectionAtStartOfParentNode: ($pos: ResolvedPos, selection: Selection) => boolean;
|
|
59
59
|
export declare const isSelectionAtEndOfParentNode: ($pos: ResolvedPos, selection: Selection) => boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Determines if the current selection is inside a list item within a container and not at the end of the parent list.
|
|
62
|
+
*
|
|
63
|
+
* This is useful for handling edge cases where the selection is within a list inside a container structure,
|
|
64
|
+
* and we need to know if the selection is not at the logical end of the parent list node.
|
|
65
|
+
*/
|
|
66
|
+
export declare const isListItemWithinContainerNotAtEnd: ($pos: ResolvedPos, selection: Selection) => boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Determines if the given node is a Container (layoutColumn, panel, expand) node.
|
|
69
|
+
*/
|
|
70
|
+
export declare const isContainerNode: (node: PmNode | null | undefined) => boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Finds the top-level List ancestor of the given position.
|
|
73
|
+
* Returns the node and its position if found, otherwise returns undefined.
|
|
74
|
+
*/
|
|
75
|
+
export declare const findTopLevelList: (pos: ResolvedPos) => {
|
|
76
|
+
node: PmNode;
|
|
77
|
+
pos: number;
|
|
78
|
+
} | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Determines whether the current selection position is at the end of a layout column node.
|
|
81
|
+
*/
|
|
82
|
+
export declare const isSelectionAtEndOfLayoutColumn: ($pos: ResolvedPos) => boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Determines if the given node is a LayoutColumn node.
|
|
85
|
+
*/
|
|
86
|
+
export declare const isLayoutColumnNode: (node: PmNode | null | undefined) => boolean;
|
|
@@ -57,3 +57,30 @@ export declare const findFirstChildNodeToSelect: (parent: PmNode) => NodeWithPos
|
|
|
57
57
|
export declare const findLastChildNodeToSelect: (parent: PmNode) => NodeWithPos | undefined;
|
|
58
58
|
export declare const isSelectionAtStartOfParentNode: ($pos: ResolvedPos, selection: Selection) => boolean;
|
|
59
59
|
export declare const isSelectionAtEndOfParentNode: ($pos: ResolvedPos, selection: Selection) => boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Determines if the current selection is inside a list item within a container and not at the end of the parent list.
|
|
62
|
+
*
|
|
63
|
+
* This is useful for handling edge cases where the selection is within a list inside a container structure,
|
|
64
|
+
* and we need to know if the selection is not at the logical end of the parent list node.
|
|
65
|
+
*/
|
|
66
|
+
export declare const isListItemWithinContainerNotAtEnd: ($pos: ResolvedPos, selection: Selection) => boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Determines if the given node is a Container (layoutColumn, panel, expand) node.
|
|
69
|
+
*/
|
|
70
|
+
export declare const isContainerNode: (node: PmNode | null | undefined) => boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Finds the top-level List ancestor of the given position.
|
|
73
|
+
* Returns the node and its position if found, otherwise returns undefined.
|
|
74
|
+
*/
|
|
75
|
+
export declare const findTopLevelList: (pos: ResolvedPos) => {
|
|
76
|
+
node: PmNode;
|
|
77
|
+
pos: number;
|
|
78
|
+
} | undefined;
|
|
79
|
+
/**
|
|
80
|
+
* Determines whether the current selection position is at the end of a layout column node.
|
|
81
|
+
*/
|
|
82
|
+
export declare const isSelectionAtEndOfLayoutColumn: ($pos: ResolvedPos) => boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Determines if the given node is a LayoutColumn node.
|
|
85
|
+
*/
|
|
86
|
+
export declare const isLayoutColumnNode: (node: PmNode | null | undefined) => boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-selection",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"description": "Selection plugin for @atlaskit/editor-core",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
"@atlaskit/editor-shared-styles": "^3.4.0",
|
|
25
25
|
"@atlaskit/editor-tables": "^2.9.0",
|
|
26
26
|
"@atlaskit/platform-feature-flags": "^1.1.0",
|
|
27
|
-
"@atlaskit/tmp-editor-statsig": "^9.
|
|
28
|
-
"@atlaskit/tokens": "^5.
|
|
27
|
+
"@atlaskit/tmp-editor-statsig": "^9.7.0",
|
|
28
|
+
"@atlaskit/tokens": "^5.5.0",
|
|
29
29
|
"@babel/runtime": "^7.0.0"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"@atlaskit/editor-common": "^107.
|
|
32
|
+
"@atlaskit/editor-common": "^107.8.0",
|
|
33
33
|
"react": "^18.2.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
@@ -86,6 +86,12 @@
|
|
|
86
86
|
},
|
|
87
87
|
"platform_editor_nested_tables_gap_cursor": {
|
|
88
88
|
"type": "boolean"
|
|
89
|
+
},
|
|
90
|
+
"platform_editor_fix_right_arrow_bug_list_in_layout": {
|
|
91
|
+
"type": "boolean"
|
|
92
|
+
},
|
|
93
|
+
"platform_editor_fix_right_arrow_nav_bug_in_layout": {
|
|
94
|
+
"type": "boolean"
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
}
|