1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-16 12:14:14 +02:00

moved getLeaves from react to slate core package and added some basic tests (#3358)

This commit is contained in:
Johan Sörlin
2019-12-19 17:51:44 +01:00
committed by Ian Storm Taylor
parent e54b07eba8
commit 5418e260d4
6 changed files with 221 additions and 75 deletions

View File

@@ -25,7 +25,7 @@ const Text = (props: {
const { decorations, isLast, parent, renderLeaf, text } = props
const editor = useEditor()
const ref = useRef<HTMLSpanElement>(null)
const leaves = getLeaves(text, decorations)
const leaves = SlateText.decorations(text, decorations)
const key = ReactEditor.findKey(editor, text)
const children = []
@@ -63,79 +63,6 @@ const Text = (props: {
)
}
/**
* Get the leaves for a text node given decorations.
*/
const getLeaves = (node: SlateText, decorations: Range[]): SlateText[] => {
let leaves: SlateText[] = [{ ...node }]
for (const dec of decorations) {
const { anchor, focus, ...rest } = dec
const [start, end] = Range.edges(dec)
const next = []
let o = 0
for (const leaf of leaves) {
const { length } = leaf.text
const offset = o
o += length
// If the range encompases the entire leaf, add the range.
if (start.offset <= offset && end.offset >= offset + length) {
Object.assign(leaf, rest)
next.push(leaf)
continue
}
// If the range starts after the leaf, or ends before it, continue.
if (
start.offset > offset + length ||
end.offset < offset ||
(end.offset === offset && offset !== 0)
) {
next.push(leaf)
continue
}
// Otherwise we need to split the leaf, at the start, end, or both,
// and add the range to the middle intersecting section. Do the end
// split first since we don't need to update the offset that way.
let middle = leaf
let before
let after
if (end.offset < offset + length) {
const off = end.offset - offset
after = { ...middle, text: middle.text.slice(off) }
middle = { ...middle, text: middle.text.slice(0, off) }
}
if (start.offset > offset) {
const off = start.offset - offset
before = { ...middle, text: middle.text.slice(0, off) }
middle = { ...middle, text: middle.text.slice(off) }
}
Object.assign(middle, rest)
if (before) {
next.push(before)
}
next.push(middle)
if (after) {
next.push(after)
}
}
leaves = next
}
return leaves
}
const MemoizedText = React.memo(Text, (prev, next) => {
return (
next.parent === prev.parent &&