mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-30 18:39:51 +02:00
Optimize editor#above and allow passing a location that doesnt exist as long as its parent exists (#5880)
* optimize editor#apply and allow potential paths as input * fix Editor#above regression for cross-node ranges * add test to prevent regressions * add changeset * improve comment * factor out for-loop that will never actually loop * aw crud I didnt lint. fixing
This commit is contained in:
5
.changeset/popular-bags-relax.md
Normal file
5
.changeset/popular-bags-relax.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'slate': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Optimize editor#above and allow passing a location that doesnt exist as long as its parent exists
|
@@ -1,6 +1,5 @@
|
|||||||
import { Editor, EditorInterface } from '../interfaces/editor'
|
import { Editor, EditorInterface } from '../interfaces/editor'
|
||||||
import { Text } from '../interfaces/text'
|
import { Range } from '../interfaces'
|
||||||
import { Range } from '../interfaces/range'
|
|
||||||
import { Path } from '../interfaces/path'
|
import { Path } from '../interfaces/path'
|
||||||
|
|
||||||
export const above: EditorInterface['above'] = (editor, options = {}) => {
|
export const above: EditorInterface['above'] = (editor, options = {}) => {
|
||||||
@@ -15,27 +14,22 @@ export const above: EditorInterface['above'] = (editor, options = {}) => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const path = Editor.path(editor, at)
|
let path = Editor.path(editor, at)
|
||||||
|
|
||||||
|
// If `at` is a Range that spans mulitple nodes, `path` will be their common ancestor.
|
||||||
|
// Otherwise `path` will be a text node and/or the same as `at`, in which cases we want to start with its parent.
|
||||||
|
if (!Range.isRange(at) || Path.equals(at.focus.path, at.anchor.path)) {
|
||||||
|
if (path.length === 0) return
|
||||||
|
path = Path.parent(path)
|
||||||
|
}
|
||||||
|
|
||||||
const reverse = mode === 'lowest'
|
const reverse = mode === 'lowest'
|
||||||
|
|
||||||
for (const [n, p] of Editor.levels(editor, {
|
const [firstMatch] = Editor.levels(editor, {
|
||||||
at: path,
|
at: path,
|
||||||
voids,
|
voids,
|
||||||
match,
|
match,
|
||||||
reverse,
|
reverse,
|
||||||
})) {
|
})
|
||||||
if (Text.isText(n)) continue
|
return firstMatch // if nothing matches this returns undefined
|
||||||
if (Range.isRange(at)) {
|
|
||||||
if (
|
|
||||||
Path.isAncestor(p, at.anchor.path) &&
|
|
||||||
Path.isAncestor(p, at.focus.path)
|
|
||||||
) {
|
|
||||||
return [n, p]
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!Path.equals(path, p)) {
|
|
||||||
return [n, p]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,33 @@
|
|||||||
|
/** @jsx jsx */
|
||||||
|
import { Editor, Element } from 'slate'
|
||||||
|
import { jsx } from '../../..'
|
||||||
|
|
||||||
|
// `above` can never return the location passed into it, and shouldnt care if it exists, only if its parent exists.
|
||||||
|
|
||||||
|
export const input = (
|
||||||
|
<editor>
|
||||||
|
<block>
|
||||||
|
<block>
|
||||||
|
<block>one</block>
|
||||||
|
{/* path points here */}
|
||||||
|
</block>
|
||||||
|
<block>two</block>
|
||||||
|
</block>
|
||||||
|
</editor>
|
||||||
|
)
|
||||||
|
|
||||||
|
const path = [0, 0, 1]
|
||||||
|
|
||||||
|
export const test = editor => {
|
||||||
|
return Editor.above(editor, {
|
||||||
|
at: path,
|
||||||
|
match: n => Element.isElement(n) && Editor.isBlock(editor, n),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const output = [
|
||||||
|
<block>
|
||||||
|
<block>one</block>
|
||||||
|
</block>,
|
||||||
|
[0, 0],
|
||||||
|
]
|
Reference in New Issue
Block a user