1
0
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 commit 2a8d86f1a4.

* Revert "Fix stale decorations (#4876)"

This reverts commit 1b205c087b.

* chore: add changeset
This commit is contained in:
jasonphillips
2022-05-25 16:01:14 -05:00
committed by GitHub
parent f5ccab241c
commit 92c5730a96
5 changed files with 63 additions and 206 deletions

View File

@@ -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 &&

View File

@@ -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(

View File

@@ -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())