1
0
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:
Tommy Dong
2020-11-10 20:56:25 -06:00
committed by GitHub
parent 6602681565
commit a5f4170162
14 changed files with 299 additions and 27 deletions

View File

@@ -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

View 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 }

View 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 }

View 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 }

View 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 }

View 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 }

View 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 }

View File

@@ -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 },
]

View File

@@ -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 },
]

View File

@@ -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 },
]

View File

@@ -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 },
]

View File

@@ -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`

View File

@@ -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>
)

View File

@@ -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>
)