forked from ianstormtaylor/slate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstring.tsx
86 lines (73 loc) · 2.25 KB
/
string.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import React from 'react'
import { Editor, Text, Path, Element, Node } from 'slate'
import { ReactEditor, useSlateStatic } from '..'
/**
* Leaf content strings.
*/
const String = (props: {
isLast: boolean
leaf: Text
parent: Element
text: Text
}) => {
const { isLast, leaf, parent, text } = props
const editor = useSlateStatic()
const path = ReactEditor.findPath(editor, text)
const parentPath = Path.parent(path)
// COMPAT: Render text inside void nodes with a zero-width space.
// So the node can contain selection but the text is not visible.
if (editor.isVoid(parent)) {
return <ZeroWidthString length={Node.string(parent).length} />
}
// COMPAT: If this is the last text node in an empty block, render a zero-
// width space that will convert into a line break when copying and pasting
// to support expected plain text.
if (
leaf.text === '' &&
parent.children[parent.children.length - 1] === text &&
!editor.isInline(parent) &&
Editor.string(editor, parentPath) === ''
) {
return <ZeroWidthString isLineBreak />
}
// COMPAT: If the text is empty, it's because it's on the edge of an inline
// node, so we render a zero-width space so that the selection can be
// inserted next to it still.
if (leaf.text === '') {
return <ZeroWidthString />
}
// COMPAT: Browsers will collapse trailing new lines at the end of blocks,
// so we need to add an extra trailing new lines to prevent that.
if (isLast && leaf.text.slice(-1) === '\n') {
return <TextString isTrailing text={leaf.text} />
}
return <TextString text={leaf.text} />
}
/**
* Leaf strings with text in them.
*/
const TextString = (props: { text: string; isTrailing?: boolean }) => {
const { text, isTrailing = false } = props
return (
<span data-slate-string>
{text}
{isTrailing ? '\n' : null}
</span>
)
}
/**
* Leaf strings without text, render as zero-width strings.
*/
const ZeroWidthString = (props: { length?: number; isLineBreak?: boolean }) => {
const { length = 0, isLineBreak = false } = props
return (
<span
data-slate-zero-width={isLineBreak ? 'n' : 'z'}
data-slate-length={length}
>
{'\uFEFF'}
{isLineBreak ? <br /> : null}
</span>
)
}
export default String