mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-31 10:51:44 +02:00
improve Editor.marks and Editor.nodes abstraction
This commit is contained in:
@@ -18,7 +18,8 @@
|
||||
"@types/esrever": "^0.2.0",
|
||||
"esrever": "^0.2.0",
|
||||
"immer": "^5.0.0",
|
||||
"is-plain-object": "^3.0.0"
|
||||
"is-plain-object": "^3.0.0",
|
||||
"tiny-warning": "^1.0.3"
|
||||
},
|
||||
"keywords": [
|
||||
"canvas",
|
||||
|
@@ -1,3 +1,4 @@
|
||||
import warning from 'tiny-warning'
|
||||
import { reverse as reverseText } from 'esrever'
|
||||
|
||||
import {
|
||||
@@ -20,6 +21,7 @@ import {
|
||||
Text,
|
||||
TextEntry,
|
||||
} from '../../..'
|
||||
import { MarkMatch } from '../../mark'
|
||||
|
||||
export const LocationQueries = {
|
||||
/**
|
||||
@@ -44,69 +46,19 @@ export const LocationQueries = {
|
||||
hanging?: boolean
|
||||
} = {}
|
||||
): Mark[] {
|
||||
const { union = false, hanging = false } = options
|
||||
let { at = editor.selection } = options
|
||||
warning(
|
||||
false,
|
||||
'The `Editor.activeMarks` helper is deprecated, use `Editor.marks` instead.'
|
||||
)
|
||||
|
||||
if (!at) {
|
||||
return []
|
||||
}
|
||||
|
||||
at = Editor.range(editor, at)
|
||||
|
||||
if (!hanging) {
|
||||
at = Editor.unhangRange(editor, at)
|
||||
}
|
||||
|
||||
// If the range is collapsed at the start of a text node, it should carry
|
||||
// over the marks from the previous text node in the same block.
|
||||
if (Range.isCollapsed(at) && at.anchor.offset === 0) {
|
||||
const { anchor } = at
|
||||
const prev = Editor.previous(editor, anchor, 'text')
|
||||
|
||||
if (prev && Path.isSibling(anchor.path, prev[1])) {
|
||||
const [prevNode, prevPath] = prev
|
||||
|
||||
if (Text.isText(prevNode)) {
|
||||
at = Editor.range(editor, prevPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const marks: Mark[] = []
|
||||
let first = true
|
||||
|
||||
for (const [node] of Editor.texts(editor, { at })) {
|
||||
if (first) {
|
||||
marks.push(...node.marks)
|
||||
first = false
|
||||
continue
|
||||
}
|
||||
|
||||
if (union) {
|
||||
for (const mark of node.marks) {
|
||||
if (!Mark.exists(mark, marks)) {
|
||||
marks.push(mark)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// PERF: If we're doing an intersection and the result hits zero it can
|
||||
// never increase again, so we can exit early.
|
||||
if (marks.length === 0) {
|
||||
break
|
||||
}
|
||||
|
||||
// Iterate backwards so that removing marks doesn't impact indexing.
|
||||
for (let i = marks.length - 1; i >= 0; i--) {
|
||||
const existing = marks[i]
|
||||
|
||||
if (!Mark.exists(existing, node.marks)) {
|
||||
marks.splice(i, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return marks
|
||||
return Array.from(
|
||||
Editor.marks(editor, {
|
||||
at: options.at,
|
||||
mode: options.union ? 'distinct' : 'universal',
|
||||
continuing: true,
|
||||
}),
|
||||
([m]) => m
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -368,23 +320,117 @@ export const LocationQueries = {
|
||||
editor: Editor,
|
||||
options: {
|
||||
at?: Location | Span
|
||||
match?: MarkMatch
|
||||
mode?: 'all' | 'first' | 'distinct' | 'universal'
|
||||
reverse?: boolean
|
||||
continuing?: boolean
|
||||
} = {}
|
||||
): Iterable<MarkEntry> {
|
||||
const { at = editor.selection } = options
|
||||
const { match, mode = 'all', reverse = false, continuing = false } = options
|
||||
let { at = editor.selection } = options
|
||||
|
||||
if (!at) {
|
||||
return
|
||||
}
|
||||
|
||||
const [from, to] = toSpan(editor, at, options)
|
||||
// If the range is collapsed at the start of a text node, it should continue
|
||||
// the marks from the previous text node in the same block.
|
||||
if (
|
||||
continuing &&
|
||||
Range.isRange(at) &&
|
||||
Range.isCollapsed(at) &&
|
||||
at.anchor.offset === 0
|
||||
) {
|
||||
const { anchor } = at
|
||||
const prev = Editor.previous(editor, anchor, 'text')
|
||||
|
||||
yield* Node.marks(editor, {
|
||||
...options,
|
||||
if (prev && Path.isSibling(anchor.path, prev[1])) {
|
||||
const [, prevPath] = prev
|
||||
at = Editor.range(editor, prevPath)
|
||||
}
|
||||
}
|
||||
|
||||
const [from, to] = toSpan(editor, at, options)
|
||||
const iterable = Node.texts(editor, {
|
||||
reverse,
|
||||
from,
|
||||
to,
|
||||
pass: ([n]) => Element.isElement(n) && editor.isVoid(n),
|
||||
})
|
||||
|
||||
let universalMarks: Mark[] = []
|
||||
let distinctMarks: Mark[] = []
|
||||
let universalEntries: MarkEntry[] = []
|
||||
let first = true
|
||||
|
||||
for (const entry of iterable) {
|
||||
const [node, path] = entry
|
||||
const isMatch = (m: MarkMatch, entry: MarkEntry) => {
|
||||
if (typeof m === 'function') {
|
||||
return m(entry)
|
||||
} else {
|
||||
return Mark.matches(entry[0], m)
|
||||
}
|
||||
}
|
||||
debugger
|
||||
|
||||
if (mode === 'universal') {
|
||||
debugger
|
||||
if (first) {
|
||||
universalMarks.push(...node.marks)
|
||||
universalEntries = node.marks.map((m, i) => [m, i, node, path])
|
||||
first = false
|
||||
continue
|
||||
}
|
||||
|
||||
// PERF: If we're in universal mode and the eligible marks hits zero
|
||||
// it can never increase again, so we can exit early.
|
||||
if (universalMarks.length === 0) {
|
||||
debugger
|
||||
return
|
||||
}
|
||||
|
||||
debugger
|
||||
for (let i = universalMarks.length - 1; i >= 0; i--) {
|
||||
const existing = universalMarks[i]
|
||||
|
||||
if (!Mark.exists(existing, node.marks)) {
|
||||
universalMarks.splice(i, 1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let index = 0; index < node.marks.length; index++) {
|
||||
const mark = node.marks[index]
|
||||
const markEntry: MarkEntry = [mark, index, node, path]
|
||||
|
||||
if (match != null && !isMatch(match, markEntry)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (mode === 'distinct') {
|
||||
if (Mark.exists(mark, distinctMarks)) {
|
||||
continue
|
||||
} else {
|
||||
distinctMarks.push(mark)
|
||||
}
|
||||
}
|
||||
|
||||
yield markEntry
|
||||
|
||||
// After matching a mark, if we're in first mode skip to the next text.
|
||||
if (mode === 'first') {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In universal mode, the marks are collected while iterating and we can
|
||||
// only be certain of which are universal when we've finished.
|
||||
if (mode === 'universal') {
|
||||
debugger
|
||||
yield* universalEntries
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -413,6 +459,11 @@ export const LocationQueries = {
|
||||
reverse?: boolean
|
||||
}
|
||||
): Iterable<NodeEntry> {
|
||||
warning(
|
||||
false,
|
||||
'The `Editor.matches` helper is deprecated, use `Editor.nodes` instead.'
|
||||
)
|
||||
|
||||
const { at = editor.selection, reverse = false } = options
|
||||
let { match } = options
|
||||
|
||||
@@ -453,7 +504,11 @@ export const LocationQueries = {
|
||||
const span: Span = [from, to]
|
||||
let i = 0
|
||||
|
||||
for (const entry of Editor.matches(editor, { at: span, match })) {
|
||||
for (const entry of Editor.nodes(editor, {
|
||||
at: span,
|
||||
match,
|
||||
mode: 'highest',
|
||||
})) {
|
||||
if (i === 1) {
|
||||
return entry
|
||||
}
|
||||
@@ -487,10 +542,17 @@ export const LocationQueries = {
|
||||
editor: Editor,
|
||||
options: {
|
||||
at?: Location | Span
|
||||
match?: NodeMatch
|
||||
mode?: 'all' | 'highest'
|
||||
reverse?: boolean
|
||||
} = {}
|
||||
): Iterable<NodeEntry> {
|
||||
const { at = editor.selection } = options
|
||||
const {
|
||||
at = editor.selection,
|
||||
match,
|
||||
mode = 'all',
|
||||
reverse = false,
|
||||
} = options
|
||||
|
||||
if (!at) {
|
||||
return
|
||||
@@ -498,13 +560,32 @@ export const LocationQueries = {
|
||||
|
||||
const [from, to] = toSpan(editor, at, options)
|
||||
const iterable = Node.nodes(editor, {
|
||||
...options,
|
||||
reverse,
|
||||
from,
|
||||
to,
|
||||
pass: ([n]) => Element.isElement(n) && editor.isVoid(n),
|
||||
})
|
||||
|
||||
let prev: NodeEntry | undefined
|
||||
|
||||
for (const entry of iterable) {
|
||||
if (match != null) {
|
||||
if (mode === 'highest' && prev) {
|
||||
const [, prevPath] = prev
|
||||
const [, path] = entry
|
||||
|
||||
if (Path.compare(path, prevPath) === 0) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if (!Editor.isMatch(editor, entry, match)) {
|
||||
continue
|
||||
}
|
||||
|
||||
prev = entry
|
||||
}
|
||||
|
||||
yield entry
|
||||
}
|
||||
},
|
||||
@@ -751,10 +832,11 @@ export const LocationQueries = {
|
||||
const span: Span = [from, to]
|
||||
let i = 0
|
||||
|
||||
for (const entry of Editor.matches(editor, {
|
||||
for (const entry of Editor.nodes(editor, {
|
||||
match,
|
||||
at: span,
|
||||
reverse: true,
|
||||
mode: 'highest',
|
||||
})) {
|
||||
if (i === 1) {
|
||||
return entry
|
||||
|
@@ -144,7 +144,7 @@ export const NodeTransforms = {
|
||||
return
|
||||
}
|
||||
|
||||
const matches = Editor.matches(editor, { at, match })
|
||||
const matches = Editor.nodes(editor, { at, match, mode: 'highest' })
|
||||
const pathRefs = Array.from(matches, ([, p]) => Editor.pathRef(editor, p))
|
||||
|
||||
for (const pathRef of pathRefs) {
|
||||
@@ -352,7 +352,7 @@ export const NodeTransforms = {
|
||||
}
|
||||
|
||||
const toRef = Editor.pathRef(editor, to)
|
||||
const targets = Editor.matches(editor, { at, match })
|
||||
const targets = Editor.nodes(editor, { at, match, mode: 'highest' })
|
||||
const pathRefs = Array.from(targets, ([, p]) => Editor.pathRef(editor, p))
|
||||
|
||||
for (const pathRef of pathRefs) {
|
||||
@@ -401,7 +401,7 @@ export const NodeTransforms = {
|
||||
at = Editor.unhangRange(editor, at)
|
||||
}
|
||||
|
||||
const depths = Editor.matches(editor, { at, match })
|
||||
const depths = Editor.nodes(editor, { at, match, mode: 'highest' })
|
||||
const pathRefs = Array.from(depths, ([, p]) => Editor.pathRef(editor, p))
|
||||
|
||||
for (const pathRef of pathRefs) {
|
||||
@@ -446,7 +446,11 @@ export const NodeTransforms = {
|
||||
at = Editor.unhangRange(editor, at)
|
||||
}
|
||||
|
||||
for (const [node, path] of Editor.matches(editor, { at, match })) {
|
||||
for (const [node, path] of Editor.nodes(editor, {
|
||||
at,
|
||||
match,
|
||||
mode: 'highest',
|
||||
})) {
|
||||
const properties: Partial<Node> = {}
|
||||
const newProperties: Partial<Node> = {}
|
||||
|
||||
@@ -631,7 +635,7 @@ export const NodeTransforms = {
|
||||
return
|
||||
}
|
||||
|
||||
const matches = Editor.matches(editor, { at, match })
|
||||
const matches = Editor.nodes(editor, { at, match, mode: 'highest' })
|
||||
const pathRefs = Array.from(matches, ([, p]) => Editor.pathRef(editor, p))
|
||||
|
||||
for (const pathRef of pathRefs) {
|
||||
@@ -699,7 +703,14 @@ export const NodeTransforms = {
|
||||
}
|
||||
|
||||
const roots: NodeEntry[] = editor.isInline(element)
|
||||
? Array.from(Editor.matches(editor, { ...options, at, match: 'block' }))
|
||||
? Array.from(
|
||||
Editor.nodes(editor, {
|
||||
...options,
|
||||
at,
|
||||
match: 'block',
|
||||
mode: 'highest',
|
||||
})
|
||||
)
|
||||
: [[editor, []]]
|
||||
|
||||
for (const [, rootPath] of roots) {
|
||||
@@ -712,7 +723,7 @@ export const NodeTransforms = {
|
||||
}
|
||||
|
||||
const matches = Array.from(
|
||||
Editor.matches(editor, { ...options, at: a, match })
|
||||
Editor.nodes(editor, { ...options, at: a, match, mode: 'highest' })
|
||||
)
|
||||
|
||||
if (matches.length > 0) {
|
||||
|
@@ -92,8 +92,9 @@ export const TextTransforms = {
|
||||
|
||||
// Get the highest nodes that are completely inside the range, as well as
|
||||
// the start and end nodes.
|
||||
const matches = Editor.matches(editor, {
|
||||
const matches = Editor.nodes(editor, {
|
||||
at,
|
||||
mode: 'highest',
|
||||
match: ([n, p]) =>
|
||||
(Element.isElement(n) && editor.isVoid(n)) ||
|
||||
(!Path.isCommon(p, start.path) && !Path.isCommon(p, end.path)),
|
||||
|
@@ -1,24 +0,0 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<mark key="a">
|
||||
<anchor />o
|
||||
</mark>
|
||||
n
|
||||
<mark key="b">
|
||||
e<focus />
|
||||
</mark>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.activeMarks(editor, { union: true }))
|
||||
}
|
||||
|
||||
export const output = [{ key: 'a' }, { key: 'b' }]
|
@@ -1,21 +1,23 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<mark key="a">one</mark>
|
||||
<cursor />
|
||||
two
|
||||
<text>
|
||||
<cursor />
|
||||
two
|
||||
</text>
|
||||
</block>
|
||||
<block />
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.activeMarks(editor))
|
||||
return Array.from(Editor.marks(editor, { continuing: true }), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = [{ key: 'a' }]
|
@@ -0,0 +1,28 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<mark key="a">
|
||||
<mark key="b">
|
||||
<anchor />o
|
||||
</mark>
|
||||
</mark>
|
||||
n
|
||||
<mark key="a">
|
||||
<mark key="b">
|
||||
e<focus />
|
||||
</mark>
|
||||
</mark>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.marks(editor), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = [{ key: 'b' }, { key: 'a' }, { key: 'b' }, { key: 'a' }]
|
@@ -0,0 +1,28 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
<block>
|
||||
<mark key="a">
|
||||
<mark key="b">
|
||||
<anchor />o
|
||||
</mark>
|
||||
</mark>
|
||||
n
|
||||
<mark key="a">
|
||||
<mark key="b">
|
||||
e<focus />
|
||||
</mark>
|
||||
</mark>
|
||||
</block>
|
||||
</editor>
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.marks(editor, { mode: 'distinct' }), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = [{ key: 'b' }, { key: 'a' }]
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
@@ -16,8 +16,8 @@ export const input = (
|
||||
<block>
|
||||
<mark key="a">
|
||||
<mark key="b">
|
||||
o<focus />
|
||||
ne
|
||||
t<focus />
|
||||
wo
|
||||
</mark>
|
||||
</mark>
|
||||
</block>
|
||||
@@ -25,7 +25,7 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.activeMarks(editor))
|
||||
return Array.from(Editor.marks(editor, { mode: 'universal' }), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = [{ key: 'b' }, { key: 'a' }]
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
@@ -16,7 +16,7 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.activeMarks(editor))
|
||||
return Array.from(Editor.marks(editor, { mode: 'universal' }), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = []
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
@@ -17,7 +17,7 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.activeMarks(editor))
|
||||
return Array.from(Editor.marks(editor, { mode: 'universal' }), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = []
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
@@ -18,7 +18,7 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.activeMarks(editor))
|
||||
return Array.from(Editor.marks(editor, { mode: 'universal' }), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = []
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
@@ -17,7 +17,7 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.activeMarks(editor))
|
||||
return Array.from(Editor.marks(editor, { mode: 'universal' }), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = [{ key: 'b' }, { key: 'a' }]
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
@@ -13,7 +13,7 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.activeMarks(editor))
|
||||
return Array.from(Editor.marks(editor, { mode: 'universal' }), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = []
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
@@ -15,7 +15,7 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.activeMarks(editor))
|
||||
return Array.from(Editor.marks(editor, { mode: 'universal' }), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = [{ key: 'a' }]
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
||||
@@ -12,7 +12,7 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.activeMarks(editor))
|
||||
return Array.from(Editor.marks(editor, { mode: 'universal' }), ([m]) => m)
|
||||
}
|
||||
|
||||
export const output = []
|
@@ -13,12 +13,12 @@ export const input = (
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(
|
||||
Editor.matches(editor, { at: [], match: 'block', reverse: true })
|
||||
Editor.nodes(editor, { at: [], match: 'block', mode: 'highest' })
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [
|
||||
[<block>three</block>, [2]],
|
||||
[<block>two</block>, [1]],
|
||||
[<block>one</block>, [0]],
|
||||
[<block>two</block>, [1]],
|
||||
[<block>three</block>, [2]],
|
||||
]
|
@@ -15,7 +15,9 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.matches(editor, { at: [], match: 'block' }))
|
||||
return Array.from(
|
||||
Editor.nodes(editor, { at: [], match: 'block', mode: 'highest' })
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [
|
@@ -12,11 +12,18 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.matches(editor, { at: [], match: 'block' }))
|
||||
return Array.from(
|
||||
Editor.nodes(editor, {
|
||||
at: [],
|
||||
match: 'block',
|
||||
mode: 'highest',
|
||||
reverse: true,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [
|
||||
[<block>one</block>, [0]],
|
||||
[<block>two</block>, [1]],
|
||||
[<block>three</block>, [2]],
|
||||
[<block>two</block>, [1]],
|
||||
[<block>one</block>, [0]],
|
||||
]
|
@@ -12,7 +12,9 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.matches(editor, { at: [], match: 'block' }))
|
||||
return Array.from(
|
||||
Editor.nodes(editor, { at: [], match: 'block', mode: 'highest' })
|
||||
)
|
||||
}
|
||||
|
||||
export const output = []
|
@@ -10,7 +10,9 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.matches(editor, { at: [], match: 'block' }))
|
||||
return Array.from(
|
||||
Editor.nodes(editor, { at: [], match: 'block', mode: 'highest' })
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [[<block>one</block>, [0]]]
|
@@ -12,7 +12,9 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.matches(editor, { at: [], match: 'block' }))
|
||||
return Array.from(
|
||||
Editor.nodes(editor, { at: [], match: 'block', mode: 'highest' })
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [
|
@@ -13,7 +13,11 @@ export const input = (
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(
|
||||
Editor.matches(editor, { at: [], match: ([, p]) => p.length === 1 })
|
||||
Editor.nodes(editor, {
|
||||
at: [],
|
||||
match: ([, p]) => p.length === 1,
|
||||
mode: 'highest',
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@@ -10,7 +10,9 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.matches(editor, { at: [], match: 'inline' }))
|
||||
return Array.from(
|
||||
Editor.nodes(editor, { at: [], match: 'inline', mode: 'highest' })
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [[<text>one</text>, [0, 0]]]
|
@@ -13,14 +13,14 @@ export const input = (
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(
|
||||
Editor.matches(editor, { at: [], match: 'inline', reverse: true })
|
||||
Editor.nodes(editor, { at: [], match: 'inline', mode: 'highest' })
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [
|
||||
[<text>five</text>, [0, 4]],
|
||||
[<inline>four</inline>, [0, 3]],
|
||||
[<text>three</text>, [0, 2]],
|
||||
[<inline>two</inline>, [0, 1]],
|
||||
[<text>one</text>, [0, 0]],
|
||||
[<inline>two</inline>, [0, 1]],
|
||||
[<text>three</text>, [0, 2]],
|
||||
[<inline>four</inline>, [0, 3]],
|
||||
[<text>five</text>, [0, 4]],
|
||||
]
|
@@ -16,7 +16,9 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.matches(editor, { at: [], match: 'inline' }))
|
||||
return Array.from(
|
||||
Editor.nodes(editor, { at: [], match: 'inline', mode: 'highest' })
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [
|
@@ -12,13 +12,20 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.matches(editor, { at: [], match: 'inline' }))
|
||||
return Array.from(
|
||||
Editor.nodes(editor, {
|
||||
at: [],
|
||||
match: 'inline',
|
||||
mode: 'highest',
|
||||
reverse: true,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [
|
||||
[<text>one</text>, [0, 0]],
|
||||
[<inline>two</inline>, [0, 1]],
|
||||
[<text>three</text>, [0, 2]],
|
||||
[<inline>four</inline>, [0, 3]],
|
||||
[<text>five</text>, [0, 4]],
|
||||
[<inline>four</inline>, [0, 3]],
|
||||
[<text>three</text>, [0, 2]],
|
||||
[<inline>two</inline>, [0, 1]],
|
||||
[<text>one</text>, [0, 0]],
|
||||
]
|
@@ -12,7 +12,9 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.matches(editor, { at: [], match: 'inline' }))
|
||||
return Array.from(
|
||||
Editor.nodes(editor, { at: [], match: 'inline', mode: 'highest' })
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [
|
@@ -12,7 +12,9 @@ export const input = (
|
||||
)
|
||||
|
||||
export const run = editor => {
|
||||
return Array.from(Editor.matches(editor, { at: [], match: 'inline' }))
|
||||
return Array.from(
|
||||
Editor.nodes(editor, { at: [], match: 'inline', mode: 'highest' })
|
||||
)
|
||||
}
|
||||
|
||||
export const output = [
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
@@ -1,7 +1,7 @@
|
||||
/** @jsx jsx */
|
||||
|
||||
import { Editor } from 'slate'
|
||||
import { jsx } from '../..'
|
||||
import { jsx } from '../../..'
|
||||
|
||||
export const input = (
|
||||
<editor>
|
Reference in New Issue
Block a user