mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-16 04:04:06 +02:00
Fix: revert to prior decorations behavior (#5007)
* Revert "Fix child element decorations (#4910)" This reverts commit2a8d86f1a4
. * Revert "Fix stale decorations (#4876)" This reverts commit1b205c087b
. * chore: add changeset
This commit is contained in:
@@ -600,9 +600,7 @@ export const Editable = (props: EditableProps) => {
|
||||
}
|
||||
}, [scheduleOnDOMSelectionChange])
|
||||
|
||||
const decorations = [...Node.nodes(editor)].flatMap(([n, p]) =>
|
||||
decorate([n, p])
|
||||
)
|
||||
const decorations = decorate([editor, []])
|
||||
|
||||
if (
|
||||
placeholder &&
|
||||
|
@@ -5,6 +5,7 @@ import ElementComponent from '../components/element'
|
||||
import TextComponent from '../components/text'
|
||||
import { ReactEditor } from '..'
|
||||
import { useSlateStatic } from './use-slate-static'
|
||||
import { useDecorate } from './use-decorate'
|
||||
import { NODE_TO_INDEX, NODE_TO_PARENT } from '../utils/weak-maps'
|
||||
import {
|
||||
RenderElementProps,
|
||||
@@ -33,6 +34,7 @@ const useChildren = (props: {
|
||||
renderLeaf,
|
||||
selection,
|
||||
} = props
|
||||
const decorate = useDecorate()
|
||||
const editor = useSlateStatic()
|
||||
const path = ReactEditor.findPath(editor, node)
|
||||
const children = []
|
||||
@@ -47,12 +49,15 @@ const useChildren = (props: {
|
||||
const key = ReactEditor.findKey(editor, n)
|
||||
const range = Editor.range(editor, p)
|
||||
const sel = selection && Range.intersection(range, selection)
|
||||
const ds = decorate([n, p])
|
||||
|
||||
const ds = decorations.reduce<Range[]>((acc, dec) => {
|
||||
const intersection = Range.intersection(dec, range)
|
||||
if (intersection) acc.push(intersection)
|
||||
return acc
|
||||
}, [])
|
||||
for (const dec of decorations) {
|
||||
const d = Range.intersection(dec, range)
|
||||
|
||||
if (d) {
|
||||
ds.push(d)
|
||||
}
|
||||
}
|
||||
|
||||
if (Element.isElement(n)) {
|
||||
children.push(
|
||||
|
@@ -1,22 +1,7 @@
|
||||
import React from 'react'
|
||||
import {
|
||||
createEditor,
|
||||
NodeEntry,
|
||||
Node,
|
||||
Range,
|
||||
Element,
|
||||
Transforms,
|
||||
} from 'slate'
|
||||
import { createEditor, Element, Transforms } from 'slate'
|
||||
import { create, act, ReactTestRenderer } from 'react-test-renderer'
|
||||
import {
|
||||
Slate,
|
||||
withReact,
|
||||
DefaultEditable,
|
||||
RenderElementProps,
|
||||
RenderLeafProps,
|
||||
DefaultElement,
|
||||
DefaultLeaf,
|
||||
} from '../src'
|
||||
import { Slate, withReact, DefaultEditable } from '../src'
|
||||
|
||||
const createNodeMock = () => ({
|
||||
ownerDocument: global.document,
|
||||
@@ -25,161 +10,6 @@ const createNodeMock = () => ({
|
||||
|
||||
describe('slate-react', () => {
|
||||
describe('Editable', () => {
|
||||
describe('decorate', () => {
|
||||
it('should be called on all nodes in document', () => {
|
||||
const editor = withReact(createEditor())
|
||||
const value = [{ type: 'block', children: [{ text: '' }] }]
|
||||
|
||||
const decorate = jest.fn<Range[], [NodeEntry]>(entry => [])
|
||||
|
||||
let el: ReactTestRenderer
|
||||
|
||||
act(() => {
|
||||
el = create(
|
||||
<Slate editor={editor} value={value} onChange={() => {}}>
|
||||
<DefaultEditable decorate={decorate} />
|
||||
</Slate>,
|
||||
{ createNodeMock }
|
||||
)
|
||||
})
|
||||
|
||||
expect(decorate).toHaveBeenCalledTimes(3)
|
||||
})
|
||||
|
||||
it('should rerender the part of the tree that received an updated decoration', () => {
|
||||
const editor = withReact(createEditor())
|
||||
|
||||
const value = [
|
||||
{ type: 'block', children: [{ text: '' }] },
|
||||
{ type: 'block', children: [{ text: '' }] },
|
||||
]
|
||||
|
||||
// initial render does not return
|
||||
const decorate = jest.fn<Range[], [NodeEntry]>(() => [])
|
||||
|
||||
const renderElement = jest.fn<JSX.Element, [RenderElementProps]>(
|
||||
DefaultElement
|
||||
)
|
||||
|
||||
const onChange = jest.fn<void, []>()
|
||||
|
||||
let el: ReactTestRenderer
|
||||
|
||||
act(() => {
|
||||
el = create(
|
||||
<Slate editor={editor} value={value} onChange={onChange}>
|
||||
<DefaultEditable
|
||||
decorate={decorate}
|
||||
renderElement={renderElement}
|
||||
/>
|
||||
</Slate>,
|
||||
{ createNodeMock }
|
||||
)
|
||||
})
|
||||
|
||||
expect(renderElement).toHaveBeenCalledTimes(2)
|
||||
|
||||
decorate.mockImplementation(([node]) => {
|
||||
if (node !== value[0].children[0]) {
|
||||
return []
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
anchor: { path: [0, 0], offset: 0 },
|
||||
focus: { path: [0, 0], offset: 0 },
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
act(() => {
|
||||
el.update(
|
||||
<Slate editor={editor} value={value} onChange={onChange}>
|
||||
<DefaultEditable
|
||||
decorate={decorate}
|
||||
renderElement={renderElement}
|
||||
/>
|
||||
</Slate>
|
||||
)
|
||||
})
|
||||
|
||||
expect(renderElement).toHaveBeenCalledTimes(3)
|
||||
})
|
||||
|
||||
it('should pass the intersecting part of decorations to nested elements', () => {
|
||||
const editor = withReact(createEditor())
|
||||
|
||||
const value = [
|
||||
{
|
||||
type: 'parent',
|
||||
children: [
|
||||
{ type: 'block', children: [{ text: 'foo', highlight: false }] },
|
||||
{ type: 'block', children: [{ text: 'bar', highlight: false }] },
|
||||
{ type: 'block', children: [{ text: 'baz', highlight: false }] },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
const decorate = jest.fn<Range[], [NodeEntry]>(([node]) => {
|
||||
if (node !== value[0]) {
|
||||
return []
|
||||
}
|
||||
return [
|
||||
{
|
||||
anchor: { path: [0, 1, 0], offset: 1 },
|
||||
focus: { path: [0, 2, 0], offset: 2 },
|
||||
highlight: true,
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
const renderLeaf = jest.fn<JSX.Element, [RenderLeafProps]>(DefaultLeaf)
|
||||
const onChange = jest.fn<void, []>()
|
||||
let el: ReactTestRenderer
|
||||
|
||||
act(() => {
|
||||
el = create(
|
||||
<Slate editor={editor} value={value} onChange={onChange}>
|
||||
<DefaultEditable decorate={decorate} renderLeaf={renderLeaf} />
|
||||
</Slate>,
|
||||
{ createNodeMock }
|
||||
)
|
||||
})
|
||||
|
||||
// 4 renders, for foo,b,ar,ba,z
|
||||
expect(renderLeaf).toHaveBeenCalledTimes(5)
|
||||
expect(renderLeaf.mock.calls).toEqual(
|
||||
expect.arrayContaining([
|
||||
[
|
||||
expect.objectContaining({
|
||||
leaf: { highlight: false, text: 'foo' },
|
||||
}),
|
||||
],
|
||||
[
|
||||
expect.objectContaining({
|
||||
leaf: { highlight: false, text: 'b' },
|
||||
}),
|
||||
],
|
||||
[
|
||||
expect.objectContaining({
|
||||
leaf: { highlight: true, text: 'ar' },
|
||||
}),
|
||||
],
|
||||
[
|
||||
expect.objectContaining({
|
||||
leaf: { highlight: true, text: 'ba' },
|
||||
}),
|
||||
],
|
||||
[
|
||||
expect.objectContaining({
|
||||
leaf: { highlight: false, text: 'z' },
|
||||
}),
|
||||
],
|
||||
])
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('NODE_TO_KEY logic', () => {
|
||||
it('should not unmount the node that gets split on a split_node operation', async () => {
|
||||
const editor = withReact(createEditor())
|
||||
|
Reference in New Issue
Block a user