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.
|
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.
|
`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,
|
reverse = false,
|
||||||
voids = false,
|
voids = false,
|
||||||
pass,
|
pass,
|
||||||
ignoreNonSelectable = false,
|
|
||||||
} = options
|
} = options
|
||||||
let { match } = options
|
let { match } = options
|
||||||
|
|
||||||
@@ -53,7 +52,7 @@ export function* nodes<T extends Node>(
|
|||||||
(Editor.isVoid(editor, node) || Editor.isElementReadOnly(editor, node))
|
(Editor.isVoid(editor, node) || Editor.isElementReadOnly(editor, node))
|
||||||
)
|
)
|
||||||
return true
|
return true
|
||||||
if (ignoreNonSelectable && !Editor.isSelectable(editor, node)) return true
|
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@@ -62,14 +61,6 @@ export function* nodes<T extends Node>(
|
|||||||
let hit: NodeEntry<T> | undefined
|
let hit: NodeEntry<T> | undefined
|
||||||
|
|
||||||
for (const [node, path] of nodeEntries) {
|
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
|
const isLower = hit && Path.compare(path, hit[1]) === 0
|
||||||
|
|
||||||
// In highest mode any node lower than the last hit is not a match.
|
// In highest mode any node lower than the last hit is not a match.
|
||||||
|
@@ -19,7 +19,6 @@ export function* positions(
|
|||||||
unit = 'offset',
|
unit = 'offset',
|
||||||
reverse = false,
|
reverse = false,
|
||||||
voids = false,
|
voids = false,
|
||||||
ignoreNonSelectable = false,
|
|
||||||
} = options
|
} = options
|
||||||
|
|
||||||
if (!at) {
|
if (!at) {
|
||||||
@@ -63,12 +62,24 @@ export function* positions(
|
|||||||
at,
|
at,
|
||||||
reverse,
|
reverse,
|
||||||
voids,
|
voids,
|
||||||
ignoreNonSelectable,
|
|
||||||
})) {
|
})) {
|
||||||
/*
|
/*
|
||||||
* ELEMENT NODE - Yield position(s) for voids, collect blockText for blocks
|
* ELEMENT NODE - Yield position(s) for voids, collect blockText for blocks
|
||||||
*/
|
*/
|
||||||
if (Element.isElement(node)) {
|
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
|
// Void nodes are a special case, so by default we will always
|
||||||
// yield their first point. If the `voids` option is set to true,
|
// yield their first point. If the `voids` option is set to true,
|
||||||
// then we will iterate over their content.
|
// then we will iterate over their content.
|
||||||
|
@@ -255,7 +255,6 @@ export interface EditorNodesOptions<T extends Node> {
|
|||||||
reverse?: boolean
|
reverse?: boolean
|
||||||
voids?: boolean
|
voids?: boolean
|
||||||
pass?: (entry: NodeEntry) => boolean
|
pass?: (entry: NodeEntry) => boolean
|
||||||
ignoreNonSelectable?: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EditorNormalizeOptions {
|
export interface EditorNormalizeOptions {
|
||||||
@@ -290,7 +289,6 @@ export interface EditorPositionsOptions {
|
|||||||
unit?: TextUnitAdjustment
|
unit?: TextUnitAdjustment
|
||||||
reverse?: boolean
|
reverse?: boolean
|
||||||
voids?: boolean
|
voids?: boolean
|
||||||
ignoreNonSelectable?: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EditorPreviousOptions<T extends Node> {
|
export interface EditorPreviousOptions<T extends Node> {
|
||||||
|
@@ -21,7 +21,7 @@ export const move: SelectionTransforms['move'] = (editor, options = {}) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { anchor, focus } = selection
|
const { anchor, focus } = selection
|
||||||
const opts = { distance, unit, ignoreNonSelectable: true }
|
const opts = { distance, unit }
|
||||||
const props: Partial<Range> = {}
|
const props: Partial<Range> = {}
|
||||||
|
|
||||||
if (edge == null || edge === 'anchor') {
|
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 => {
|
export const test = editor => {
|
||||||
return Editor.after(
|
return Editor.after(editor, { path: [0, 0], offset: 3 })
|
||||||
editor,
|
|
||||||
{ path: [0, 0], offset: 3 },
|
|
||||||
{ ignoreNonSelectable: true }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const output = { path: [0, 2], offset: 0 }
|
export const output = { path: [0, 2], offset: 0 }
|
||||||
|
@@ -12,11 +12,7 @@ export const input = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
export const test = editor => {
|
export const test = editor => {
|
||||||
return Editor.before(
|
return Editor.before(editor, { path: [0, 2], offset: 0 })
|
||||||
editor,
|
|
||||||
{ path: [0, 2], offset: 0 },
|
|
||||||
{ ignoreNonSelectable: true }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const output = { path: [0, 0], offset: 3 }
|
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