mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-14 03:03:58 +02:00
fix bug: decorate is not called for immediate children of editor (#4394)
* fix bug: decorate is not called for immediate children of editor * short-circuit return instead of else in Child Co-authored-by: Tim Buckley <timothypbuckley@gmail.com> * oops missing brace * changeset Co-authored-by: Tim Buckley <timothypbuckley@gmail.com>
This commit is contained in:
@@ -24,6 +24,8 @@
|
||||
"tiny-invariant": "1.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"jsdom": "^16.6.0",
|
||||
"react-test-renderer": ">=16.8.0",
|
||||
"slate": "^0.63.0",
|
||||
"slate-hyperscript": "^0.62.0"
|
||||
},
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import { Editor, Range, Element, NodeEntry, Ancestor, Descendant } from 'slate'
|
||||
import { Editor, Range, Element, Path, Ancestor, Descendant } from 'slate'
|
||||
|
||||
import ElementComponent from '../components/element'
|
||||
import TextComponent from '../components/text'
|
||||
@@ -17,6 +17,67 @@ import {
|
||||
* Children.
|
||||
*/
|
||||
|
||||
const Child = (props: {
|
||||
decorations: Range[]
|
||||
parent: Ancestor
|
||||
path: Path
|
||||
child: Descendant
|
||||
isLast: boolean
|
||||
renderElement?: (props: RenderElementProps) => JSX.Element
|
||||
renderPlaceholder: (props: RenderPlaceholderProps) => JSX.Element
|
||||
renderLeaf?: (props: RenderLeafProps) => JSX.Element
|
||||
selection: Range | null
|
||||
}) => {
|
||||
const {
|
||||
decorations,
|
||||
parent,
|
||||
path,
|
||||
child,
|
||||
isLast,
|
||||
renderElement,
|
||||
renderPlaceholder,
|
||||
renderLeaf,
|
||||
selection,
|
||||
} = props
|
||||
const decorate = useDecorate()
|
||||
const editor = useSlateStatic()
|
||||
|
||||
const range = Editor.range(editor, path)
|
||||
const sel = selection && Range.intersection(range, selection)
|
||||
const ds = decorate([child, path])
|
||||
|
||||
for (const dec of decorations) {
|
||||
const d = Range.intersection(dec, range)
|
||||
|
||||
if (d) {
|
||||
ds.push(d)
|
||||
}
|
||||
}
|
||||
|
||||
if (Element.isElement(child)) {
|
||||
return (
|
||||
<ElementComponent
|
||||
decorations={ds}
|
||||
element={child}
|
||||
renderElement={renderElement}
|
||||
renderPlaceholder={renderPlaceholder}
|
||||
renderLeaf={renderLeaf}
|
||||
selection={sel}
|
||||
/>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<TextComponent
|
||||
decorations={ds}
|
||||
isLast={isLast}
|
||||
parent={parent}
|
||||
renderPlaceholder={renderPlaceholder}
|
||||
renderLeaf={renderLeaf}
|
||||
text={child}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const useChildren = (props: {
|
||||
decorations: Range[]
|
||||
node: Ancestor
|
||||
@@ -33,7 +94,6 @@ const useChildren = (props: {
|
||||
renderLeaf,
|
||||
selection,
|
||||
} = props
|
||||
const decorate = useDecorate()
|
||||
const editor = useSlateStatic()
|
||||
const path = ReactEditor.findPath(editor, node)
|
||||
const children = []
|
||||
@@ -46,43 +106,21 @@ const useChildren = (props: {
|
||||
const p = path.concat(i)
|
||||
const n = node.children[i] as Descendant
|
||||
const key = ReactEditor.findKey(editor, n)
|
||||
const range = Editor.range(editor, p)
|
||||
const sel = selection && Range.intersection(range, selection)
|
||||
const ds = decorate([n, p])
|
||||
|
||||
for (const dec of decorations) {
|
||||
const d = Range.intersection(dec, range)
|
||||
|
||||
if (d) {
|
||||
ds.push(d)
|
||||
}
|
||||
}
|
||||
|
||||
if (Element.isElement(n)) {
|
||||
children.push(
|
||||
<ElementComponent
|
||||
decorations={ds}
|
||||
element={n}
|
||||
key={key.id}
|
||||
renderElement={renderElement}
|
||||
renderPlaceholder={renderPlaceholder}
|
||||
renderLeaf={renderLeaf}
|
||||
selection={sel}
|
||||
/>
|
||||
)
|
||||
} else {
|
||||
children.push(
|
||||
<TextComponent
|
||||
decorations={ds}
|
||||
key={key.id}
|
||||
isLast={isLeafBlock && i === node.children.length - 1}
|
||||
parent={node}
|
||||
renderPlaceholder={renderPlaceholder}
|
||||
renderLeaf={renderLeaf}
|
||||
text={n}
|
||||
/>
|
||||
)
|
||||
}
|
||||
children.push(
|
||||
<Child
|
||||
decorations={decorations}
|
||||
parent={node}
|
||||
path={p}
|
||||
child={n}
|
||||
key={key.id}
|
||||
isLast={isLeafBlock && i === node.children.length - 1}
|
||||
renderElement={renderElement}
|
||||
renderPlaceholder={renderPlaceholder}
|
||||
renderLeaf={renderLeaf}
|
||||
selection={selection}
|
||||
/>
|
||||
)
|
||||
|
||||
NODE_TO_INDEX.set(n, i)
|
||||
NODE_TO_PARENT.set(n, node)
|
||||
|
@@ -1 +1,46 @@
|
||||
describe('slate-react', () => {})
|
||||
import * as Slate from 'slate'
|
||||
import * as SlateReact from '..'
|
||||
import { JSDOM } from 'jsdom'
|
||||
import React from 'react'
|
||||
import TestRenderer from 'react-test-renderer'
|
||||
import assert from 'assert'
|
||||
|
||||
describe('slate-react', () => {
|
||||
describe('Editable', () => {
|
||||
describe('decorate', () => {
|
||||
// stub out some DOM stuff to avoid crashes
|
||||
before(() => {
|
||||
const jsdom = new JSDOM()
|
||||
global.window = jsdom.window
|
||||
global.document = jsdom.window.document
|
||||
global.Document = document.constructor
|
||||
})
|
||||
|
||||
const createNodeMock = () => ({
|
||||
ownerDocument: global.document,
|
||||
getRootNode: () => global.document,
|
||||
})
|
||||
|
||||
it('should be called on all nodes in document', () => {
|
||||
const editor = SlateReact.withReact(Slate.createEditor())
|
||||
const value = [{ type: 'block', children: [{ text: '' }] }]
|
||||
let count = 0
|
||||
const decorate = ([node, path]) => {
|
||||
count++
|
||||
return []
|
||||
}
|
||||
|
||||
const el = React.createElement(
|
||||
SlateReact.Slate,
|
||||
{ editor, value },
|
||||
React.createElement(SlateReact.Editable, { decorate })
|
||||
)
|
||||
|
||||
TestRenderer.create(el, { createNodeMock })
|
||||
|
||||
// editor, block, text
|
||||
assert.strictEqual(count, 3)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
Reference in New Issue
Block a user