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:
6
.changeset/nice-deers-hammer.md
Normal file
6
.changeset/nice-deers-hammer.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'slate': minor
|
||||
---
|
||||
|
||||
- Remove `ignoreNonSelectable` option from positions,before,after,nodes.
|
||||
- Fix move behavior when encounter non-selectable inline voids.
|
@@ -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.
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
@@ -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> {
|
||||
|
@@ -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') {
|
||||
|
@@ -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 }
|
@@ -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 }
|
||||
|
@@ -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 }
|
||||
|
@@ -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 = []
|
@@ -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]],
|
||||
]
|
@@ -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 = []
|
@@ -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 },
|
||||
]
|
Reference in New Issue
Block a user