mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-30 02:19:52 +02:00
Editor.next and Editor.previous now return the first match (#3957)
* Fixes to Editor.next and Editor.previous along with methods used therein (Editor.before, Editor.after, Editor.positions).
This commit is contained in:
@@ -121,6 +121,7 @@ export const Editor = {
|
||||
options: {
|
||||
distance?: number
|
||||
unit?: 'offset' | 'character' | 'word' | 'line' | 'block'
|
||||
voids?: boolean
|
||||
} = {}
|
||||
): Point | undefined {
|
||||
const anchor = Editor.point(editor, at, { edge: 'end' })
|
||||
@@ -130,7 +131,10 @@ export const Editor = {
|
||||
let d = 0
|
||||
let target
|
||||
|
||||
for (const p of Editor.positions(editor, { ...options, at: range })) {
|
||||
for (const p of Editor.positions(editor, {
|
||||
...options,
|
||||
at: range,
|
||||
})) {
|
||||
if (d > distance) {
|
||||
break
|
||||
}
|
||||
@@ -155,6 +159,7 @@ export const Editor = {
|
||||
options: {
|
||||
distance?: number
|
||||
unit?: 'offset' | 'character' | 'word' | 'line' | 'block'
|
||||
voids?: boolean
|
||||
} = {}
|
||||
): Point | undefined {
|
||||
const anchor = Editor.start(editor, [])
|
||||
@@ -570,9 +575,13 @@ export const Editor = {
|
||||
return
|
||||
}
|
||||
|
||||
const [, from] = Editor.last(editor, at)
|
||||
const pointAfterLocation = Editor.after(editor, at, { voids })
|
||||
|
||||
if (!pointAfterLocation) return
|
||||
|
||||
const [, to] = Editor.last(editor, [])
|
||||
const span: Span = [from, to]
|
||||
|
||||
const span: Span = [pointAfterLocation.path, to]
|
||||
|
||||
if (Path.isPath(at) && at.length === 0) {
|
||||
throw new Error(`Cannot get the next node from the root node!`)
|
||||
@@ -587,7 +596,7 @@ export const Editor = {
|
||||
}
|
||||
}
|
||||
|
||||
const [, next] = Editor.nodes(editor, { at: span, match, mode, voids })
|
||||
const [next] = Editor.nodes(editor, { at: span, match, mode, voids })
|
||||
return next
|
||||
},
|
||||
|
||||
@@ -973,8 +982,9 @@ export const Editor = {
|
||||
* can pass the `unit: 'character'` option to moved forward one character, word,
|
||||
* or line at at time.
|
||||
*
|
||||
* Note: void nodes are treated as a single point, and iteration will not
|
||||
* happen inside their content.
|
||||
* Note: By default void nodes are treated as a single point and iteration
|
||||
* will not happen inside their content unless you pass in true for the
|
||||
* voids option, then iteration will occur.
|
||||
*/
|
||||
|
||||
*positions(
|
||||
@@ -983,9 +993,15 @@ export const Editor = {
|
||||
at?: Location
|
||||
unit?: 'offset' | 'character' | 'word' | 'line' | 'block'
|
||||
reverse?: boolean
|
||||
voids?: boolean
|
||||
} = {}
|
||||
): Generator<Point, void, undefined> {
|
||||
const { at = editor.selection, unit = 'offset', reverse = false } = options
|
||||
const {
|
||||
at = editor.selection,
|
||||
unit = 'offset',
|
||||
reverse = false,
|
||||
voids = false,
|
||||
} = options
|
||||
|
||||
if (!at) {
|
||||
return
|
||||
@@ -1024,11 +1040,12 @@ export const Editor = {
|
||||
distance = available >= 0 ? null : 0 - available
|
||||
}
|
||||
|
||||
for (const [node, path] of Editor.nodes(editor, { at, reverse })) {
|
||||
for (const [node, path] of Editor.nodes(editor, { at, reverse, voids })) {
|
||||
if (Element.isElement(node)) {
|
||||
// Void nodes are a special case, since we don't want to iterate over
|
||||
// their content. We instead always just yield their first point.
|
||||
if (editor.isVoid(node)) {
|
||||
// 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
|
||||
if (!voids && editor.isVoid(node)) {
|
||||
yield Editor.start(editor, path)
|
||||
continue
|
||||
}
|
||||
@@ -1045,7 +1062,7 @@ export const Editor = {
|
||||
? start
|
||||
: Editor.start(editor, path)
|
||||
|
||||
const text = Editor.string(editor, { anchor: s, focus: e })
|
||||
const text = Editor.string(editor, { anchor: s, focus: e }, { voids })
|
||||
string = reverse ? reverseText(text) : text
|
||||
isNewBlock = true
|
||||
}
|
||||
@@ -1107,9 +1124,17 @@ export const Editor = {
|
||||
return
|
||||
}
|
||||
|
||||
const [, from] = Editor.first(editor, at)
|
||||
const pointBeforeLocation = Editor.before(editor, at, { voids })
|
||||
|
||||
if (!pointBeforeLocation) {
|
||||
return
|
||||
}
|
||||
|
||||
const [, to] = Editor.first(editor, [])
|
||||
const span: Span = [from, to]
|
||||
|
||||
// The search location is from the start of the document to the path of
|
||||
// the point before the location passed in
|
||||
const span: Span = [pointBeforeLocation.path, to]
|
||||
|
||||
if (Path.isPath(at) && at.length === 0) {
|
||||
throw new Error(`Cannot get the previous node from the root node!`)
|
||||
@@ -1124,7 +1149,7 @@ export const Editor = {
|
||||
}
|
||||
}
|
||||
|
||||
const [, previous] = Editor.nodes(editor, {
|
||||
const [previous] = Editor.nodes(editor, {
|
||||
reverse: true,
|
||||
at: span,
|
||||
match,
|
||||
@@ -1217,11 +1242,18 @@ export const Editor = {
|
||||
/**
|
||||
* Get the text string content of a location.
|
||||
*
|
||||
* Note: the text of void nodes is presumed to be an empty string, regardless
|
||||
* of what their actual content is.
|
||||
* Note: by default the text of void nodes is considered to be an empty
|
||||
* string, regardless of content, unless you pass in true for the voids option
|
||||
*/
|
||||
|
||||
string(editor: Editor, at: Location): string {
|
||||
string(
|
||||
editor: Editor,
|
||||
at: Location,
|
||||
options: {
|
||||
voids?: boolean
|
||||
} = {}
|
||||
): string {
|
||||
const { voids = false } = options
|
||||
const range = Editor.range(editor, at)
|
||||
const [start, end] = Range.edges(range)
|
||||
let text = ''
|
||||
@@ -1229,6 +1261,7 @@ export const Editor = {
|
||||
for (const [node, path] of Editor.nodes(editor, {
|
||||
at: range,
|
||||
match: Text.isText,
|
||||
voids,
|
||||
})) {
|
||||
let t = node.text
|
||||
|
||||
|
19
packages/slate/test/interfaces/Editor/after/path-void.tsx
Normal file
19
packages/slate/test/interfaces/Editor/after/path-void.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>
|
||||
<text>one</text>
|
||||
<text>two</text>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const test = editor => {
|
||||
return Editor.after(editor, [0, 0], { voids: true })
|
||||
}
|
||||
|
||||
export const output = { path: [0, 1], offset: 0 }
|
16
packages/slate/test/interfaces/Editor/after/point-void.tsx
Normal file
16
packages/slate/test/interfaces/Editor/after/point-void.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>one</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const test = editor => {
|
||||
return Editor.after(editor, { path: [0, 0], offset: 1 }, { voids: true })
|
||||
}
|
||||
|
||||
export const output = { path: [0, 0], offset: 2 }
|
24
packages/slate/test/interfaces/Editor/after/range-void.tsx
Normal file
24
packages/slate/test/interfaces/Editor/after/range-void.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>one</block>
|
||||
<block void>two</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const test = editor => {
|
||||
return Editor.after(
|
||||
editor,
|
||||
{
|
||||
anchor: { path: [0, 0], offset: 1 },
|
||||
focus: { path: [1, 0], offset: 2 },
|
||||
},
|
||||
{ voids: true }
|
||||
)
|
||||
}
|
||||
|
||||
export const output = { path: [1, 0], offset: 3 }
|
17
packages/slate/test/interfaces/Editor/before/path-void.tsx
Normal file
17
packages/slate/test/interfaces/Editor/before/path-void.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>one</block>
|
||||
<block void>two</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const test = editor => {
|
||||
return Editor.before(editor, [1, 0], { voids: true })
|
||||
}
|
||||
|
||||
export const output = { path: [0, 0], offset: 3 }
|
16
packages/slate/test/interfaces/Editor/before/point-void.tsx
Normal file
16
packages/slate/test/interfaces/Editor/before/point-void.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>one</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const test = editor => {
|
||||
return Editor.before(editor, { path: [0, 0], offset: 1 }, { voids: true })
|
||||
}
|
||||
|
||||
export const output = { path: [0, 0], offset: 0 }
|
24
packages/slate/test/interfaces/Editor/before/range-void.tsx
Normal file
24
packages/slate/test/interfaces/Editor/before/range-void.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>one</block>
|
||||
<block void>two</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const test = editor => {
|
||||
return Editor.before(
|
||||
editor,
|
||||
{
|
||||
anchor: { path: [0, 0], offset: 1 },
|
||||
focus: { path: [0, 1], offset: 2 },
|
||||
},
|
||||
{ voids: true }
|
||||
)
|
||||
}
|
||||
|
||||
export const output = { path: [0, 0], offset: 0 }
|
@@ -0,0 +1,20 @@
|
||||
/** @jsx jsx */
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>one</block>
|
||||
</editor>
|
||||
)
|
||||
export const test = editor => {
|
||||
return Array.from(
|
||||
Editor.positions(editor, { at: [], reverse: true, voids: true })
|
||||
)
|
||||
}
|
||||
export const output = [
|
||||
{ path: [0, 0], offset: 3 },
|
||||
{ path: [0, 0], offset: 2 },
|
||||
{ path: [0, 0], offset: 1 },
|
||||
{ path: [0, 0], offset: 0 },
|
||||
]
|
@@ -0,0 +1,18 @@
|
||||
/** @jsx jsx */
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>one</block>
|
||||
</editor>
|
||||
)
|
||||
export const test = editor => {
|
||||
return Array.from(Editor.positions(editor, { at: [], voids: true }))
|
||||
}
|
||||
export const output = [
|
||||
{ path: [0, 0], offset: 0 },
|
||||
{ path: [0, 0], offset: 1 },
|
||||
{ path: [0, 0], offset: 2 },
|
||||
{ path: [0, 0], offset: 3 },
|
||||
]
|
@@ -0,0 +1,32 @@
|
||||
/** @jsx jsx */
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>
|
||||
one<inline>two</inline>three
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
export const test = editor => {
|
||||
return Array.from(
|
||||
Editor.positions(editor, { at: [], reverse: true, voids: true })
|
||||
)
|
||||
}
|
||||
export const output = [
|
||||
{ path: [0, 2], offset: 5 },
|
||||
{ path: [0, 2], offset: 4 },
|
||||
{ path: [0, 2], offset: 3 },
|
||||
{ path: [0, 2], offset: 2 },
|
||||
{ path: [0, 2], offset: 1 },
|
||||
{ path: [0, 2], offset: 0 },
|
||||
{ path: [0, 1, 0], offset: 3 },
|
||||
{ path: [0, 1, 0], offset: 2 },
|
||||
{ path: [0, 1, 0], offset: 1 },
|
||||
{ path: [0, 1, 0], offset: 0 },
|
||||
{ path: [0, 0], offset: 3 },
|
||||
{ path: [0, 0], offset: 2 },
|
||||
{ path: [0, 0], offset: 1 },
|
||||
{ path: [0, 0], offset: 0 },
|
||||
]
|
@@ -0,0 +1,30 @@
|
||||
/** @jsx jsx */
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>
|
||||
one<inline>two</inline>three
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
export const test = editor => {
|
||||
return Array.from(Editor.positions(editor, { at: [], voids: 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, 1, 0], offset: 0 },
|
||||
{ path: [0, 1, 0], offset: 1 },
|
||||
{ path: [0, 1, 0], offset: 2 },
|
||||
{ path: [0, 1, 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 },
|
||||
]
|
@@ -0,0 +1,16 @@
|
||||
/** @jsx jsx */
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block void>
|
||||
<text>one</text>
|
||||
<text>two</text>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
export const test = editor => {
|
||||
return Editor.string(editor, [0], { voids: true })
|
||||
}
|
||||
export const output = `onetwo`
|
@@ -4,10 +4,13 @@ import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>one</block>
|
||||
<block>
|
||||
<text>bar</text>
|
||||
<text>foo</text>
|
||||
</block>
|
||||
<block>
|
||||
<cursor />
|
||||
two
|
||||
baz
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
@@ -17,12 +20,14 @@ export const run = editor => {
|
||||
export const output = (
|
||||
<editor>
|
||||
<block>
|
||||
<text />
|
||||
<text>foo</text>
|
||||
</block>
|
||||
<block>
|
||||
one
|
||||
<cursor />
|
||||
two
|
||||
<text>
|
||||
bar
|
||||
<cursor />
|
||||
baz
|
||||
</text>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
@@ -6,20 +6,22 @@ export const input = (
|
||||
<editor>
|
||||
<block void>one</block>
|
||||
<block void>two</block>
|
||||
<block void>three</block>
|
||||
</editor>
|
||||
)
|
||||
export const run = editor => {
|
||||
Transforms.moveNodes(editor, {
|
||||
at: [0, 0],
|
||||
to: [1, 0],
|
||||
at: [1, 0],
|
||||
to: [2, 0],
|
||||
voids: true,
|
||||
})
|
||||
}
|
||||
export const output = (
|
||||
<editor>
|
||||
<block void>one</block>
|
||||
<block void>
|
||||
<text />
|
||||
</block>
|
||||
<block void>onetwo</block>
|
||||
<block void>twothree</block>
|
||||
</editor>
|
||||
)
|
||||
|
Reference in New Issue
Block a user