diff --git a/src/utils/focus/selection.ts b/src/utils/focus/selection.ts
index c09282c2..2149309d 100644
--- a/src/utils/focus/selection.ts
+++ b/src/utils/focus/selection.ts
@@ -217,14 +217,13 @@ export function moveSelection(node: Element, direction: -1 | 1) {
} else {
const selection = node.ownerDocument.getSelection()
- /* istanbul ignore if */
- if (!selection) {
+ if (!selection?.focusNode) {
return
}
if (selection.isCollapsed) {
const nextPosition = getNextCursorPosition(
- selection.focusNode as Node,
+ selection.focusNode,
selection.focusOffset,
direction,
)
diff --git a/tests/utils/focus/selection.ts b/tests/utils/focus/selection.ts
index 6c09b617..16c68e6b 100644
--- a/tests/utils/focus/selection.ts
+++ b/tests/utils/focus/selection.ts
@@ -4,6 +4,7 @@ import {
setSelection,
setSelectionRange,
modifySelection,
+ moveSelection,
} from '#src/utils'
import {setup} from '#testHelpers'
@@ -183,3 +184,78 @@ describe('update selection when moving focus into element with own selection imp
expect(document.getSelection()).toHaveProperty('focusOffset', 0)
})
})
+
+describe('move selection', () => {
+ test('do nothing without a selection range', () => {
+ const {element} = setup(`
`)
+ document.getSelection()?.removeAllRanges()
+
+ moveSelection(element, 1)
+
+ expect(document.getSelection()).toHaveProperty('rangeCount', 0)
+ })
+
+ test('move to next cursor position', () => {
+ const {element} = setup(`foo
`, {
+ selection: {focusNode: 'div/text()', focusOffset: 1},
+ })
+
+ moveSelection(element, 1)
+
+ expect(document.getSelection()).toHaveProperty(
+ 'focusNode',
+ element.firstChild,
+ )
+ expect(document.getSelection()).toHaveProperty('focusOffset', 2)
+ })
+
+ test('move to next cursor position', () => {
+ const {element} = setup(`foo
`, {
+ selection: {focusNode: 'div/text()', focusOffset: 1},
+ })
+
+ moveSelection(element, 1)
+
+ expect(document.getSelection()).toHaveProperty(
+ 'focusNode',
+ element.firstChild,
+ )
+ expect(document.getSelection()).toHaveProperty('focusOffset', 2)
+ expect(document.getSelection()).toHaveProperty('isCollapsed', true)
+ })
+
+ test('collapse range', () => {
+ const {element} = setup(`foo
`, {
+ selection: {focusNode: 'div/text()', anchorOffset: 1, focusOffset: 2},
+ })
+
+ moveSelection(element, 1)
+
+ expect(document.getSelection()).toHaveProperty(
+ 'focusNode',
+ element.firstChild,
+ )
+ expect(document.getSelection()).toHaveProperty('focusOffset', 2)
+ expect(document.getSelection()).toHaveProperty('isCollapsed', true)
+ })
+
+ test('move cursor in input', () => {
+ const {element} = setup(``)
+
+ moveSelection(element, 1)
+
+ expect(element).toHaveProperty('selectionStart', 1)
+ expect(element).toHaveProperty('selectionEnd', 1)
+ })
+
+ test('collapse range in input', () => {
+ const {element} = setup(``, {
+ selection: {anchorOffset: 1, focusOffset: 2},
+ })
+
+ moveSelection(element, 1)
+
+ expect(element).toHaveProperty('selectionStart', 2)
+ expect(element).toHaveProperty('selectionEnd', 2)
+ })
+})