mirror of
https://github.com/ianstormtaylor/slate.git
synced 2025-08-16 20:24:01 +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:
5
.changeset/lovely-pumas-fix.md
Normal file
5
.changeset/lovely-pumas-fix.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'slate-react': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Revert #4876 & #4910 to restore original decorations behavior
|
@@ -600,9 +600,7 @@ export const Editable = (props: EditableProps) => {
|
|||||||
}
|
}
|
||||||
}, [scheduleOnDOMSelectionChange])
|
}, [scheduleOnDOMSelectionChange])
|
||||||
|
|
||||||
const decorations = [...Node.nodes(editor)].flatMap(([n, p]) =>
|
const decorations = decorate([editor, []])
|
||||||
decorate([n, p])
|
|
||||||
)
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
placeholder &&
|
placeholder &&
|
||||||
|
@@ -5,6 +5,7 @@ import ElementComponent from '../components/element'
|
|||||||
import TextComponent from '../components/text'
|
import TextComponent from '../components/text'
|
||||||
import { ReactEditor } from '..'
|
import { ReactEditor } from '..'
|
||||||
import { useSlateStatic } from './use-slate-static'
|
import { useSlateStatic } from './use-slate-static'
|
||||||
|
import { useDecorate } from './use-decorate'
|
||||||
import { NODE_TO_INDEX, NODE_TO_PARENT } from '../utils/weak-maps'
|
import { NODE_TO_INDEX, NODE_TO_PARENT } from '../utils/weak-maps'
|
||||||
import {
|
import {
|
||||||
RenderElementProps,
|
RenderElementProps,
|
||||||
@@ -33,6 +34,7 @@ const useChildren = (props: {
|
|||||||
renderLeaf,
|
renderLeaf,
|
||||||
selection,
|
selection,
|
||||||
} = props
|
} = props
|
||||||
|
const decorate = useDecorate()
|
||||||
const editor = useSlateStatic()
|
const editor = useSlateStatic()
|
||||||
const path = ReactEditor.findPath(editor, node)
|
const path = ReactEditor.findPath(editor, node)
|
||||||
const children = []
|
const children = []
|
||||||
@@ -47,12 +49,15 @@ const useChildren = (props: {
|
|||||||
const key = ReactEditor.findKey(editor, n)
|
const key = ReactEditor.findKey(editor, n)
|
||||||
const range = Editor.range(editor, p)
|
const range = Editor.range(editor, p)
|
||||||
const sel = selection && Range.intersection(range, selection)
|
const sel = selection && Range.intersection(range, selection)
|
||||||
|
const ds = decorate([n, p])
|
||||||
|
|
||||||
const ds = decorations.reduce<Range[]>((acc, dec) => {
|
for (const dec of decorations) {
|
||||||
const intersection = Range.intersection(dec, range)
|
const d = Range.intersection(dec, range)
|
||||||
if (intersection) acc.push(intersection)
|
|
||||||
return acc
|
if (d) {
|
||||||
}, [])
|
ds.push(d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Element.isElement(n)) {
|
if (Element.isElement(n)) {
|
||||||
children.push(
|
children.push(
|
||||||
|
@@ -1,22 +1,7 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {
|
import { createEditor, Element, Transforms } from 'slate'
|
||||||
createEditor,
|
|
||||||
NodeEntry,
|
|
||||||
Node,
|
|
||||||
Range,
|
|
||||||
Element,
|
|
||||||
Transforms,
|
|
||||||
} from 'slate'
|
|
||||||
import { create, act, ReactTestRenderer } from 'react-test-renderer'
|
import { create, act, ReactTestRenderer } from 'react-test-renderer'
|
||||||
import {
|
import { Slate, withReact, DefaultEditable } from '../src'
|
||||||
Slate,
|
|
||||||
withReact,
|
|
||||||
DefaultEditable,
|
|
||||||
RenderElementProps,
|
|
||||||
RenderLeafProps,
|
|
||||||
DefaultElement,
|
|
||||||
DefaultLeaf,
|
|
||||||
} from '../src'
|
|
||||||
|
|
||||||
const createNodeMock = () => ({
|
const createNodeMock = () => ({
|
||||||
ownerDocument: global.document,
|
ownerDocument: global.document,
|
||||||
@@ -25,161 +10,6 @@ const createNodeMock = () => ({
|
|||||||
|
|
||||||
describe('slate-react', () => {
|
describe('slate-react', () => {
|
||||||
describe('Editable', () => {
|
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', () => {
|
describe('NODE_TO_KEY logic', () => {
|
||||||
it('should not unmount the node that gets split on a split_node operation', async () => {
|
it('should not unmount the node that gets split on a split_node operation', async () => {
|
||||||
const editor = withReact(createEditor())
|
const editor = withReact(createEditor())
|
||||||
|
71
yarn.lock
71
yarn.lock
@@ -3550,12 +3550,12 @@ __metadata:
|
|||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/jest@npm:^27.4.1":
|
"@types/jest@npm:^27.4.1":
|
||||||
version: 27.4.1
|
version: 27.5.1
|
||||||
resolution: "@types/jest@npm:27.4.1"
|
resolution: "@types/jest@npm:27.5.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
jest-matcher-utils: ^27.0.0
|
jest-matcher-utils: ^27.0.0
|
||||||
pretty-format: ^27.0.0
|
pretty-format: ^27.0.0
|
||||||
checksum: 5184f3eef4832d01ee8f59bed15eec45ccc8e29c724a5e6ce37bf74396b37bdf04f557000f45ba4fc38ae6075cf9cfcce3d7a75abc981023c61ceb27230a93e4
|
checksum: be20e39f7aaf17179109c0060d0a0489cec2034d4e2e28a631284c7ecd13c5ae52f62697a33a0e89b03b6cfe54e9d5e8c2bd387ab2bd90d6071d68c63b86d1e3
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -3742,9 +3742,9 @@ __metadata:
|
|||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/tough-cookie@npm:*":
|
"@types/tough-cookie@npm:*":
|
||||||
version: 4.0.1
|
version: 4.0.2
|
||||||
resolution: "@types/tough-cookie@npm:4.0.1"
|
resolution: "@types/tough-cookie@npm:4.0.2"
|
||||||
checksum: 7570c1c2d74201f4ead3512cf8e4c99e97d92ab8a02ae2fb987fd720ced0ca1a2baf250c98a861a170b86762606c9bf6d32207675f13dffc5ab75c08c96578d2
|
checksum: e055556ffdaa39ad85ede0af192c93f93f986f4bd9e9426efdc2948e3e2632db3a4a584d4937dbf6d7620527419bc99e6182d3daf2b08685e710f2eda5291905
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -5409,9 +5409,9 @@ __metadata:
|
|||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"ci-info@npm:^3.2.0":
|
"ci-info@npm:^3.2.0":
|
||||||
version: 3.3.0
|
version: 3.3.1
|
||||||
resolution: "ci-info@npm:3.3.0"
|
resolution: "ci-info@npm:3.3.1"
|
||||||
checksum: c3d86fe374938ecda5093b1ba39acb535d8309185ba3f23587747c6a057e63f45419b406d880304dbc0e1d72392c9a33e42fe9a1e299209bc0ded5efaa232b66
|
checksum: 244546317cca96955860d2cb8d0bf47dd66d9078bbe83a215fa87464ab24b352c6fc6f56027d1c82f002e3f833be253f1320d35ed7199bd81134f7788c657f3a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -8278,9 +8278,9 @@ __metadata:
|
|||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"graceful-fs@npm:^4.2.9":
|
"graceful-fs@npm:^4.2.9":
|
||||||
version: 4.2.9
|
version: 4.2.10
|
||||||
resolution: "graceful-fs@npm:4.2.9"
|
resolution: "graceful-fs@npm:4.2.10"
|
||||||
checksum: 68ea4e07ff2c041ada184f9278b830375f8e0b75154e3f080af6b70f66172fabb4108d19b3863a96b53fc068a310b9b6493d86d1291acc5f3861eb4b79d26ad6
|
checksum: 3f109d70ae123951905d85032ebeae3c2a5a7a997430df00ea30df0e3a6c60cf6689b109654d6fdacd28810a053348c4d14642da1d075049e6be1ba5216218da
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -10269,14 +10269,12 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"json5@npm:2.x, json5@npm:^2.1.2, json5@npm:^2.2.0":
|
"json5@npm:2.x":
|
||||||
version: 2.2.0
|
version: 2.2.1
|
||||||
resolution: "json5@npm:2.2.0"
|
resolution: "json5@npm:2.2.1"
|
||||||
dependencies:
|
|
||||||
minimist: ^1.2.5
|
|
||||||
bin:
|
bin:
|
||||||
json5: lib/cli.js
|
json5: lib/cli.js
|
||||||
checksum: e88fc5274bb58fc99547baa777886b069d2dd96d9cfc4490b305fd16d711dabd5979e35a4f90873cefbeb552e216b041a304fe56702bedba76e19bc7845f208d
|
checksum: 74b8a23b102a6f2bf2d224797ae553a75488b5adbaee9c9b6e5ab8b510a2fc6e38f876d4c77dea672d4014a44b2399e15f2051ac2b37b87f74c0c7602003543b
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -10300,6 +10298,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"jsonfile@npm:^4.0.0":
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
resolution: "jsonfile@npm:4.0.0"
|
resolution: "jsonfile@npm:4.0.0"
|
||||||
@@ -14317,14 +14326,14 @@ resolve@^2.0.0-next.3:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"semver@npm:7.x, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5":
|
"semver@npm:7.x":
|
||||||
version: 7.3.5
|
version: 7.3.7
|
||||||
resolution: "semver@npm:7.3.5"
|
resolution: "semver@npm:7.3.7"
|
||||||
dependencies:
|
dependencies:
|
||||||
lru-cache: ^6.0.0
|
lru-cache: ^6.0.0
|
||||||
bin:
|
bin:
|
||||||
semver: bin/semver.js
|
semver: bin/semver.js
|
||||||
checksum: 5eafe6102bea2a7439897c1856362e31cc348ccf96efd455c8b5bc2c61e6f7e7b8250dc26b8828c1d76a56f818a7ee907a36ae9fb37a599d3d24609207001d60
|
checksum: 2fa3e877568cd6ce769c75c211beaed1f9fce80b28338cadd9d0b6c40f2e2862bafd62c19a6cff42f3d54292b7c623277bcab8816a2b5521cf15210d43e75232
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -14337,6 +14346,17 @@ resolve@^2.0.0-next.3:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"semver@npm:~2.3.1":
|
||||||
version: 2.3.2
|
version: 2.3.2
|
||||||
resolution: "semver@npm:2.3.2"
|
resolution: "semver@npm:2.3.2"
|
||||||
@@ -15885,8 +15905,8 @@ resolve@^2.0.0-next.3:
|
|||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"ts-jest@npm:^27.1.3":
|
"ts-jest@npm:^27.1.3":
|
||||||
version: 27.1.3
|
version: 27.1.5
|
||||||
resolution: "ts-jest@npm:27.1.3"
|
resolution: "ts-jest@npm:27.1.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
bs-logger: 0.x
|
bs-logger: 0.x
|
||||||
fast-json-stable-stringify: 2.x
|
fast-json-stable-stringify: 2.x
|
||||||
@@ -15900,7 +15920,6 @@ resolve@^2.0.0-next.3:
|
|||||||
"@babel/core": ">=7.0.0-beta.0 <8"
|
"@babel/core": ">=7.0.0-beta.0 <8"
|
||||||
"@types/jest": ^27.0.0
|
"@types/jest": ^27.0.0
|
||||||
babel-jest: ">=27.0.0 <28"
|
babel-jest: ">=27.0.0 <28"
|
||||||
esbuild: ~0.14.0
|
|
||||||
jest: ^27.0.0
|
jest: ^27.0.0
|
||||||
typescript: ">=3.8 <5.0"
|
typescript: ">=3.8 <5.0"
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
@@ -15914,7 +15933,7 @@ resolve@^2.0.0-next.3:
|
|||||||
optional: true
|
optional: true
|
||||||
bin:
|
bin:
|
||||||
ts-jest: cli.js
|
ts-jest: cli.js
|
||||||
checksum: eb54e5b8fc5f06e4cc20ecec7891201ddc78a3537d5eb3775e29ffbc7e83fd2a68f91db801b6a8c820c872060b24dc41fb6decac800b76256d3cdda6520b5c4f
|
checksum: 3ef51c538b82f49b3f529331c1a017871a2f90e7a9a6e69333304755036d121818c6b120e2ce32dd161ff8bb2487efec0c790753ecd39b46a9ed1ce0d241464c
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user