1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-22 15:02:51 +02:00

skip nonselectable nodes when move (#5885)

* skip nonselectable nodes when move

* fix

* docs

* remove ignoreNonSelectable

* docs

* revert
This commit is contained in:
Felix Feng
2025-06-11 06:37:56 +08:00
committed by GitHub
parent 86e1411235
commit c56a98fd65
13 changed files with 46 additions and 108 deletions

View File

@@ -0,0 +1,6 @@
---
'slate': minor
---
- Remove `ignoreNonSelectable` option from positions,before,after,nodes.
- Fix move behavior when encounter non-selectable inline voids.

View File

@@ -141,7 +141,7 @@ Options: `depth?: number, edge?: 'start' | 'end'`
At any given `Location` or `Span` in the editor provided by `at` (default is the current selection), the method returns a Generator of `NodeEntry` objects that represent the nodes that include `at`. At the top of the hierarchy is the `Editor` object itself.
Options: `{at?: Location | Span, match?: NodeMatch, mode?: 'all' | 'highest' | 'lowest', universal?: boolean, reverse?: boolean, voids?: boolean, pass?: (node: NodeEntry => boolean), ignoreNonSelectable?: boolean}`
Options: `{at?: Location | Span, match?: NodeMatch, mode?: 'all' | 'highest' | 'lowest', universal?: boolean, reverse?: boolean, voids?: boolean, pass?: (node: NodeEntry => boolean)}`
`options.match`: Provide a value to the `match?` option to limit the `NodeEntry` objects that are returned.

View File

@@ -16,7 +16,6 @@ export function* nodes<T extends Node>(
reverse = false,
voids = false,
pass,
ignoreNonSelectable = false,
} = options
let { match } = options
@@ -53,7 +52,7 @@ export function* nodes<T extends Node>(
(Editor.isVoid(editor, node) || Editor.isElementReadOnly(editor, node))
)
return true
if (ignoreNonSelectable && !Editor.isSelectable(editor, node)) return true
return false
},
})
@@ -62,14 +61,6 @@ export function* nodes<T extends Node>(
let hit: NodeEntry<T> | undefined
for (const [node, path] of nodeEntries) {
if (
ignoreNonSelectable &&
Element.isElement(node) &&
!Editor.isSelectable(editor, node)
) {
continue
}
const isLower = hit && Path.compare(path, hit[1]) === 0
// In highest mode any node lower than the last hit is not a match.

View File

@@ -19,7 +19,6 @@ export function* positions(
unit = 'offset',
reverse = false,
voids = false,
ignoreNonSelectable = false,
} = options
if (!at) {
@@ -63,12 +62,24 @@ export function* positions(
at,
reverse,
voids,
ignoreNonSelectable,
})) {
/*
* ELEMENT NODE - Yield position(s) for voids, collect blockText for blocks
*/
if (Element.isElement(node)) {
if (!editor.isSelectable(node)) {
/**
* If the node is not selectable, skip it
*/
if (reverse) {
yield Editor.end(editor, Path.previous(path))
continue
} else {
yield Editor.start(editor, Path.next(path))
continue
}
}
// Void nodes are a special case, so by default we will always
// yield their first point. If the `voids` option is set to true,
// then we will iterate over their content.

View File

@@ -255,7 +255,6 @@ export interface EditorNodesOptions<T extends Node> {
reverse?: boolean
voids?: boolean
pass?: (entry: NodeEntry) => boolean
ignoreNonSelectable?: boolean
}
export interface EditorNormalizeOptions {
@@ -290,7 +289,6 @@ export interface EditorPositionsOptions {
unit?: TextUnitAdjustment
reverse?: boolean
voids?: boolean
ignoreNonSelectable?: boolean
}
export interface EditorPreviousOptions<T extends Node> {

View File

@@ -21,7 +21,7 @@ export const move: SelectionTransforms['move'] = (editor, options = {}) => {
}
const { anchor, focus } = selection
const opts = { distance, unit, ignoreNonSelectable: true }
const opts = { distance, unit }
const props: Partial<Range> = {}
if (edge == null || edge === 'anchor') {

View File

@@ -0,0 +1,22 @@
/** @jsx jsx */
import { Editor } from 'slate'
import { jsx } from '../../..'
export const input = (
<editor>
<block>
one
<inline void nonSelectable>
<text />
</inline>
three
</block>
</editor>
)
export const test = editor => {
return Editor.after(editor, { path: [0, 0], offset: 3 })
}
export const output = { path: [0, 2], offset: 0 }

View File

@@ -12,11 +12,7 @@ export const input = (
)
export const test = editor => {
return Editor.after(
editor,
{ path: [0, 0], offset: 3 },
{ ignoreNonSelectable: true }
)
return Editor.after(editor, { path: [0, 0], offset: 3 })
}
export const output = { path: [0, 2], offset: 0 }

View File

@@ -12,11 +12,7 @@ export const input = (
)
export const test = editor => {
return Editor.before(
editor,
{ path: [0, 2], offset: 0 },
{ ignoreNonSelectable: true }
)
return Editor.before(editor, { path: [0, 2], offset: 0 })
}
export const output = { path: [0, 0], offset: 3 }

View File

@@ -1,19 +0,0 @@
/** @jsx jsx */
import { Editor, Text } from 'slate'
import { jsx } from '../../../..'
export const input = (
<editor>
<block nonSelectable>one</block>
</editor>
)
export const test = editor => {
return Array.from(
Editor.nodes(editor, {
at: [],
match: Text.isText,
ignoreNonSelectable: true,
})
)
}
export const output = []

View File

@@ -1,20 +0,0 @@
/** @jsx jsx */
import { Editor, Text } from 'slate'
import { jsx } from '../../../..'
export const input = (
<editor>
<block>
one<inline nonSelectable>two</inline>three
</block>
</editor>
)
export const test = editor => {
return Array.from(Editor.nodes(editor, { at: [], ignoreNonSelectable: true }))
}
export const output = [
[input, []],
[input.children[0], [0]],
[input.children[0].children[0], [0, 0]],
[input.children[0].children[2], [0, 2]],
]

View File

@@ -1,15 +0,0 @@
/** @jsx jsx */
import { Editor } from 'slate'
import { jsx } from '../../../..'
export const input = (
<editor>
<block nonSelectable>one</block>
</editor>
)
export const test = editor => {
return Array.from(
Editor.positions(editor, { at: [], ignoreNonSelectable: true })
)
}
export const output = []

View File

@@ -1,28 +0,0 @@
/** @jsx jsx */
import { Editor } from 'slate'
import { jsx } from '../../../..'
export const input = (
<editor>
<block>
one<inline nonSelectable>two</inline>three
</block>
</editor>
)
export const test = editor => {
return Array.from(
Editor.positions(editor, { at: [], ignoreNonSelectable: true })
)
}
export const output = [
{ path: [0, 0], offset: 0 },
{ path: [0, 0], offset: 1 },
{ path: [0, 0], offset: 2 },
{ path: [0, 0], offset: 3 },
{ path: [0, 2], offset: 0 },
{ path: [0, 2], offset: 1 },
{ path: [0, 2], offset: 2 },
{ path: [0, 2], offset: 3 },
{ path: [0, 2], offset: 4 },
{ path: [0, 2], offset: 5 },
]