Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: revert to prior decorations behavior #5007

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/lovely-pumas-fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'slate-react': patch
---

Revert #4876 & #4910 to restore original decorations behavior
4 changes: 1 addition & 3 deletions packages/slate-react/src/components/editable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
15 changes: 10 additions & 5 deletions packages/slate-react/src/hooks/use-children.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -33,6 +34,7 @@ const useChildren = (props: {
renderLeaf,
selection,
} = props
const decorate = useDecorate()
const editor = useSlateStatic()
const path = ReactEditor.findPath(editor, node)
const children = []
Expand All @@ -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(
Expand Down
174 changes: 2 additions & 172 deletions packages/slate-react/test/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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())
Expand Down
71 changes: 45 additions & 26 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3550,12 +3550,12 @@ __metadata:
linkType: hard

"@types/jest@npm:^27.4.1":
version: 27.4.1
resolution: "@types/jest@npm:27.4.1"
version: 27.5.1
resolution: "@types/jest@npm:27.5.1"
dependencies:
jest-matcher-utils: ^27.0.0
pretty-format: ^27.0.0
checksum: 5184f3eef4832d01ee8f59bed15eec45ccc8e29c724a5e6ce37bf74396b37bdf04f557000f45ba4fc38ae6075cf9cfcce3d7a75abc981023c61ceb27230a93e4
checksum: be20e39f7aaf17179109c0060d0a0489cec2034d4e2e28a631284c7ecd13c5ae52f62697a33a0e89b03b6cfe54e9d5e8c2bd387ab2bd90d6071d68c63b86d1e3
languageName: node
linkType: hard

Expand Down Expand Up @@ -3742,9 +3742,9 @@ __metadata:
linkType: hard

"@types/tough-cookie@npm:*":
version: 4.0.1
resolution: "@types/tough-cookie@npm:4.0.1"
checksum: 7570c1c2d74201f4ead3512cf8e4c99e97d92ab8a02ae2fb987fd720ced0ca1a2baf250c98a861a170b86762606c9bf6d32207675f13dffc5ab75c08c96578d2
version: 4.0.2
resolution: "@types/tough-cookie@npm:4.0.2"
checksum: e055556ffdaa39ad85ede0af192c93f93f986f4bd9e9426efdc2948e3e2632db3a4a584d4937dbf6d7620527419bc99e6182d3daf2b08685e710f2eda5291905
languageName: node
linkType: hard

Expand Down Expand Up @@ -5409,9 +5409,9 @@ __metadata:
linkType: hard

"ci-info@npm:^3.2.0":
version: 3.3.0
resolution: "ci-info@npm:3.3.0"
checksum: c3d86fe374938ecda5093b1ba39acb535d8309185ba3f23587747c6a057e63f45419b406d880304dbc0e1d72392c9a33e42fe9a1e299209bc0ded5efaa232b66
version: 3.3.1
resolution: "ci-info@npm:3.3.1"
checksum: 244546317cca96955860d2cb8d0bf47dd66d9078bbe83a215fa87464ab24b352c6fc6f56027d1c82f002e3f833be253f1320d35ed7199bd81134f7788c657f3a
languageName: node
linkType: hard

Expand Down Expand Up @@ -8278,9 +8278,9 @@ __metadata:
linkType: hard

"graceful-fs@npm:^4.2.9":
version: 4.2.9
resolution: "graceful-fs@npm:4.2.9"
checksum: 68ea4e07ff2c041ada184f9278b830375f8e0b75154e3f080af6b70f66172fabb4108d19b3863a96b53fc068a310b9b6493d86d1291acc5f3861eb4b79d26ad6
version: 4.2.10
resolution: "graceful-fs@npm:4.2.10"
checksum: 3f109d70ae123951905d85032ebeae3c2a5a7a997430df00ea30df0e3a6c60cf6689b109654d6fdacd28810a053348c4d14642da1d075049e6be1ba5216218da
languageName: node
linkType: hard

Expand Down Expand Up @@ -10269,14 +10269,12 @@ __metadata:
languageName: node
linkType: hard

"json5@npm:2.x, json5@npm:^2.1.2, json5@npm:^2.2.0":
version: 2.2.0
resolution: "json5@npm:2.2.0"
dependencies:
minimist: ^1.2.5
"json5@npm:2.x":
version: 2.2.1
resolution: "json5@npm:2.2.1"
bin:
json5: lib/cli.js
checksum: e88fc5274bb58fc99547baa777886b069d2dd96d9cfc4490b305fd16d711dabd5979e35a4f90873cefbeb552e216b041a304fe56702bedba76e19bc7845f208d
checksum: 74b8a23b102a6f2bf2d224797ae553a75488b5adbaee9c9b6e5ab8b510a2fc6e38f876d4c77dea672d4014a44b2399e15f2051ac2b37b87f74c0c7602003543b
languageName: node
linkType: hard

Expand All @@ -10300,6 +10298,17 @@ __metadata:
languageName: node
linkType: hard

"json5@npm:^2.1.2, json5@npm:^2.2.0":
version: 2.2.0
resolution: "json5@npm:2.2.0"
dependencies:
minimist: ^1.2.5
bin:
json5: lib/cli.js
checksum: e88fc5274bb58fc99547baa777886b069d2dd96d9cfc4490b305fd16d711dabd5979e35a4f90873cefbeb552e216b041a304fe56702bedba76e19bc7845f208d
languageName: node
linkType: hard

"jsonfile@npm:^4.0.0":
version: 4.0.0
resolution: "jsonfile@npm:4.0.0"
Expand Down Expand Up @@ -14317,14 +14326,14 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard

"semver@npm:7.x, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5":
version: 7.3.5
resolution: "semver@npm:7.3.5"
"semver@npm:7.x":
version: 7.3.7
resolution: "semver@npm:7.3.7"
dependencies:
lru-cache: ^6.0.0
bin:
semver: bin/semver.js
checksum: 5eafe6102bea2a7439897c1856362e31cc348ccf96efd455c8b5bc2c61e6f7e7b8250dc26b8828c1d76a56f818a7ee907a36ae9fb37a599d3d24609207001d60
checksum: 2fa3e877568cd6ce769c75c211beaed1f9fce80b28338cadd9d0b6c40f2e2862bafd62c19a6cff42f3d54292b7c623277bcab8816a2b5521cf15210d43e75232
languageName: node
linkType: hard

Expand All @@ -14337,6 +14346,17 @@ resolve@^2.0.0-next.3:
languageName: node
linkType: hard

"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5":
version: 7.3.5
resolution: "semver@npm:7.3.5"
dependencies:
lru-cache: ^6.0.0
bin:
semver: bin/semver.js
checksum: 5eafe6102bea2a7439897c1856362e31cc348ccf96efd455c8b5bc2c61e6f7e7b8250dc26b8828c1d76a56f818a7ee907a36ae9fb37a599d3d24609207001d60
languageName: node
linkType: hard

"semver@npm:~2.3.1":
version: 2.3.2
resolution: "semver@npm:2.3.2"
Expand Down Expand Up @@ -15885,8 +15905,8 @@ resolve@^2.0.0-next.3:
linkType: hard

"ts-jest@npm:^27.1.3":
version: 27.1.3
resolution: "ts-jest@npm:27.1.3"
version: 27.1.5
resolution: "ts-jest@npm:27.1.5"
dependencies:
bs-logger: 0.x
fast-json-stable-stringify: 2.x
Expand All @@ -15900,7 +15920,6 @@ resolve@^2.0.0-next.3:
"@babel/core": ">=7.0.0-beta.0 <8"
"@types/jest": ^27.0.0
babel-jest: ">=27.0.0 <28"
esbuild: ~0.14.0
jest: ^27.0.0
typescript: ">=3.8 <5.0"
peerDependenciesMeta:
Expand All @@ -15914,7 +15933,7 @@ resolve@^2.0.0-next.3:
optional: true
bin:
ts-jest: cli.js
checksum: eb54e5b8fc5f06e4cc20ecec7891201ddc78a3537d5eb3775e29ffbc7e83fd2a68f91db801b6a8c820c872060b24dc41fb6decac800b76256d3cdda6520b5c4f
checksum: 3ef51c538b82f49b3f529331c1a017871a2f90e7a9a6e69333304755036d121818c6b120e2ce32dd161ff8bb2487efec0c790753ecd39b46a9ed1ce0d241464c
languageName: node
linkType: hard

Expand Down